Edge type flags - #89
Conversation
|
Warning Review limit reached
Next review available in: 78 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe PR replaces fixed KNN edge construction with configurable radius and KNN policies. It adds fallback rescue, edge-type ablations, model-owned configuration, CLI and inference wiring, README documentation, and expanded regression tests. ChangesDynamic edge construction
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant TrainingCLI
participant FlowWaterGVP
participant ProteinWaterUpdate
participant build_dynamic_edges
TrainingCLI->>FlowWaterGVP: pass dynamic-edge configuration
FlowWaterGVP->>ProteinWaterUpdate: initialize active edge settings
ProteinWaterUpdate->>build_dynamic_edges: construct water interaction edges
build_dynamic_edges-->>ProteinWaterUpdate: return dynamic edges
ProteinWaterUpdate-->>FlowWaterGVP: return assembled graph
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR makes edge construction in the flow model configurable (edge-type ablations and radius-vs-kNN dynamic graph building), and updates training/inference plumbing plus tests/docs to support replaying historical configs and new runtime edge policies.
Changes:
- Introduces dynamic edge construction controls (policy, cutoff, max_neighbors, fallback k, and WW/WP ablations) and threads them through
FlowWaterGVP/ProteinWaterUpdate. - Replaces the previous KNN-only edge builder with a unified radius/KNN builder plus optional “rescue” edges for isolated nodes.
- Updates CLI/config loading, tests, and README documentation to reflect the new edge configuration surface.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_train_config.py | Adds regression test to ensure recorded configs with dynamic_edge_policy: "auto" replay successfully and map to the intended runtime policy/etypes. |
| tests/test_forward.py | Updates forward-pass test to validate dynamic edges via the new build_edges() signature (no explicit k args). |
| tests/test_flow.py | Expands unit tests for radius/KNN edge building semantics, row conventions, fallback behavior, and policy resolution. |
| src/flow.py | Implements resolve_edge_policy, build_dynamic_edges, edge-type configuration/ablation, and fallback (“rescue”) logic in ProteinWaterUpdate. |
| src/constants.py | Adds get_active_edge_types() helper for WW/WP ablation while keeping PW/PP always enabled. |
| scripts/train.py | Replaces old k-only flags with a richer edge configuration CLI and wires args into model construction. |
| scripts/inference.py | Loads the same edge configuration keys from config.json when reconstructing models for inference. |
| README.md | Updates edge-type descriptions and adds an “Edge Construction” section documenting the new policy controls. |
Suppressed comments (2)
src/flow.py:259
- build_dynamic_edges currently treats any
policyother than "knn" as the radius path. That means typos (or accidentally passing "knn_if_isolated") silently change behavior instead of failing fast.
if policy == "knn":
# Asked for each destination's nearest sources, so sources come back second.
dst_idx, src_idx = knn(
x=src_pos, y=dst_pos, k=k, batch_x=batch_src, batch_y=batch_dst
)
README.md:310
- The CLI-flag summary table is out of sync with the implemented arguments: it lists
--dynamic_edge_policydefault asradiusand only mentionsradius/knn, but the CLI defaults toautoand also supportsknn_if_isolated; additionally,--max_neighborsand--k_wp(and the knn k's) are missing.
| `--dynamic_edge_policy` | `radius` | How water-touching edges are built: `radius` or `knn` (see [Edge Construction](#edge-construction)) |
| `--cutoff` | `8.0` | Distance cutoff in Å for radius edges |
| `--knn_fallback_k` | `8` | Nearest neighbours attached to waters stranded by the radius query; `0` disables |
| `--disable_ww` | `false` | Ablate water→water edges |
| `--disable_wp` | `false` | Ablate water→protein edges |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/train.py (1)
1101-1108: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPass
sampling_strategytoFlowMatcher.
build_modelresolvesdynamic_edge_policyfrom the run's sampling strategy.FlowMatcherhere keeps its"uniform_ball"default. If a run selectsscaled_gaussian, the model resolves"auto"toknn_if_isolatedwhile the matcher still samples from the uniform ball prior. The two settings then describe different runs.🐛 Proposed fix
flow_matcher = FlowMatcher( model=model, p_self_cond=args.p_self_cond, use_distortion=args.use_distortion, p_distort=args.p_distort, t_distort=args.t_distort, sigma_distort=args.sigma_distort, + sampling_strategy=args.sampling_strategy, )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/train.py` around lines 1101 - 1108, Pass the run’s sampling_strategy argument into the FlowMatcher construction alongside the existing distortion parameters, ensuring it uses the same resolved strategy as build_model. Preserve the current argument wiring and FlowMatcher behavior for callers whose strategy is unspecified.
🧹 Nitpick comments (3)
src/flow.py (2)
673-684: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDocument
sampling_strategyin the constructor docstring.The signature adds
sampling_strategy, and the value decides how"auto"resolves. The Args block does not list it. Readers cannot see that the prior affects edge construction.📝 Proposed docstring addition
dynamic_edge_policy: How water-touching edges are built, one of DYNAMIC_EDGE_POLICIES. Default: "radius" + sampling_strategy: Prior the run uses. Consulted only to resolve + a "auto" policy; see `resolve_edge_policy`. Default: "uniform_ball" knn_fallback_k: Nearest neighbours attached to waters the radius🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/flow.py` around lines 673 - 684, Update the constructor docstring’s Args section to document the sampling_strategy parameter, including that it controls how the “auto” strategy is resolved and affects edge construction. Place it alongside the other edge-construction configuration arguments and describe its default or accepted values using the existing symbols.
527-537: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse a PP-specific neighbour count instead of
k_pwfor the dynamic protein-protein fallback.Under
policy="knn", this branch builds protein->protein edges withk=self.k_pw.k_pwis documented as the count for protein->water edges. The two relations have different densities, so the reuse couples an unrelated setting to PP. The branch runs only when the dataset carries no cached PP edges, but that is exactly the path where the value matters.Add a
k_ppparameter, or state the reuse in a comment so it is a deliberate choice.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/flow.py` around lines 527 - 537, Update the protein-protein fallback in the dynamic edge construction around build_dynamic_edges to use a dedicated k_pp neighbor-count parameter rather than k_pw. Add and propagate k_pp through the relevant flow configuration and call sites, preserving k_pw exclusively for protein-water edges.tests/test_flow.py (1)
422-461: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the water->protein rescue axis.
test_radius_strands_far_water_and_fallback_rescues_itcovers_add_knn_fallbackwithisolate_axis=1. Theisolate_axis=0branch remaps rows differently: it queries with the isolated sources and then swaps the returned rows. No test pins that remapping, so a row swap there would pass silently.Add a case that strands a protein atom far from every water and asserts that the rescued
EDGE_WPedges keep row 0 inside the water index range and row 1 inside the protein index range.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_flow.py` around lines 422 - 461, Add a test alongside test_radius_strands_far_water_and_fallback_rescues_it that places one protein atom far from all waters, enables radius isolation rescue with knn_fallback_k > 0, and inspects rescued EDGE_WP edges. Assert row 0 contains only valid water indices and row 1 contains only valid protein indices, pinning the isolate_axis=0 query-and-row-swap behavior in _add_knn_fallback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.md`:
- Around line 211-231: Update the Edge Construction section to document all four
dynamic_edge_policy values: auto, radius, knn, and knn_if_isolated. Describe
that auto resolves to knn_if_isolated for scaled_gaussian sampling and otherwise
follows the standard default behavior, and state that stranded-water rescue via
knn_fallback_k requires the resolved knn_if_isolated policy; positive fallback
values do not rescue under plain radius.
- Around line 306-308: Update the README options table to match
scripts/train.py: document dynamic_edge_policy’s default as auto and include
auto, radius, knn, and knn_if_isolated as valid policies. Revise the
knn_fallback_k description to state that the rescue applies only to
knn_if_isolated runs, while preserving its default and disabled value.
In `@scripts/inference.py`:
- Around line 279-281: Update the FlowMatcher construction in
scripts/inference.py to pass the recorded sampling_strategy from config,
defaulting to "uniform_ball" consistently with the earlier configuration
handling. Preserve the existing model and p_self_cond arguments while ensuring
integration uses the training run’s selected prior.
In `@scripts/train.py`:
- Around line 628-638: The training CLI must define the sampling_strategy
argument before it is read. In scripts/train.py lines 628-638, retain
sampling_strategy=args.sampling_strategy in the FlowMatcher construction; in
scripts/train.py lines 1101-1108, add the parse_args option with uniform_ball
and scaled_gaussian choices; and in scripts/inference.py lines 279-281, make the
corresponding argument wiring consistent as required by the existing FlowMatcher
configuration.
In `@src/flow.py`:
- Around line 498-499: Update the comment above rescue_isolated in the relevant
flow method to accurately describe that the extra pass applies to both
protein→water and water→protein edges, while preserving the rescue assignment
itself.
- Around line 265-283: Update the homogeneous branch in build_dynamic_edges to
return source indices in row 0 by using the appropriate radius_graph flow or
flipping its output. Apply max_neighbors through the source-side neighbor limit
rather than max_num_neighbors, while preserving the existing candidate cap and
non-homogeneous radius behavior.
---
Outside diff comments:
In `@scripts/train.py`:
- Around line 1101-1108: Pass the run’s sampling_strategy argument into the
FlowMatcher construction alongside the existing distortion parameters, ensuring
it uses the same resolved strategy as build_model. Preserve the current argument
wiring and FlowMatcher behavior for callers whose strategy is unspecified.
---
Nitpick comments:
In `@src/flow.py`:
- Around line 673-684: Update the constructor docstring’s Args section to
document the sampling_strategy parameter, including that it controls how the
“auto” strategy is resolved and affects edge construction. Place it alongside
the other edge-construction configuration arguments and describe its default or
accepted values using the existing symbols.
- Around line 527-537: Update the protein-protein fallback in the dynamic edge
construction around build_dynamic_edges to use a dedicated k_pp neighbor-count
parameter rather than k_pw. Add and propagate k_pp through the relevant flow
configuration and call sites, preserving k_pw exclusively for protein-water
edges.
In `@tests/test_flow.py`:
- Around line 422-461: Add a test alongside
test_radius_strands_far_water_and_fallback_rescues_it that places one protein
atom far from all waters, enables radius isolation rescue with knn_fallback_k >
0, and inspects rescued EDGE_WP edges. Assert row 0 contains only valid water
indices and row 1 contains only valid protein indices, pinning the
isolate_axis=0 query-and-row-swap behavior in _add_knn_fallback.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ba98ee21-f527-4166-aab9-b78c54fed4fd
📒 Files selected for processing (8)
README.mdscripts/inference.pyscripts/train.pysrc/constants.pysrc/flow.pytests/test_flow.pytests/test_forward.pytests/test_train_config.py
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (8)
src/flow.py:256
build_dynamic_edgestreats anypolicyvalue other than "knn" as the radius path, so typos or unexpected values silently change behavior. Since the docstring says the policy must be one ofDYNAMIC_EDGE_POLICIES, this should be validated and raise early.
# Same object
homogeneous = src_pos is dst_pos
if policy == "knn":
# Asked for each destination's nearest sources, so sources come back second.
README.md:90
- This says only PP edges are stored in the geometry cache and that every water-touching edge is rebuilt each forward pass, but
ProteinWaterUpdate.build_edgesexplicitly reuses cached PW edges when present (and there is a unit test asserting this behavior). The README should mention this exception so users understand when PW is rebuilt vs reused.
- Only PP edges are stored in the geometry cache; every water-touching edge is
rebuilt each forward pass, since water positions move during integration. See
[Edge Construction](#edge-construction)
README.md:215
- The Edge Construction table omits
autoandknn_if_isolated, and labelsradiusas the default, butscripts/train.pydefaults--dynamic_edge_policytoautoand the code supportsknn_if_isolated. Updating the table will prevent confusion when replaying configs or using CLI flags.
| `--dynamic_edge_policy` | Behaviour |
|-------------------------|-----------|
| `radius` (default) | Connect every pair within `--cutoff`, capped at `--max_neighbors` per source |
| `knn` | Connect a fixed number of nearest neighbours (`--k_pw`, `--k_ww`, `--k_wp`) |
README.md:231
- This blockquote implies that whether stranded waters are rescued is now solely
--knn_fallback_k’s job, but the code only enables rescue when the resolved policy isknn_if_isolated(includingautowithscaled_gaussian). Withdynamic_edge_policy=radius, rescue stays off even ifknn_fallback_k>0.
> Configs written before the radius/KNN split recorded a three-valued
> `dynamic_edge_policy` (`auto`, `radius`, `knn_if_isolated`). All three built a
> radius graph, so they load and map to `radius`; whether stranded waters are
> rescued is now `--knn_fallback_k`'s job.
README.md:306
- The documented default for
--dynamic_edge_policyisradius, but the CLI default inscripts/train.pyisauto. The README should match the actual flag default (and ideally list all supported values) to avoid confusion when starting new runs.
| `--dynamic_edge_policy` | `radius` | How water-touching edges are built: `radius` or `knn` (see [Edge Construction](#edge-construction)) |
src/flow.py:499
- The comment says only protein→water edges get the fallback pass, but the code also applies
_add_knn_fallbackto water→protein edges whenrescueis enabled. Please update the comment so it matches the actual behavior (or restrict the rescue logic to PW only if that was the intent).
# Only protein-water edges get the extra pass; waters keep protein context anyway.
rescue = self.rescue_isolated
scripts/train.py:256
- The
--knn_fallback_khelp text implies the rescue runs under--dynamic_edge_policy radius, but the implementation only enables rescue when the resolved policy isknn_if_isolated(includingautowithscaled_gaussian). As written, the CLI help is misleading.
help=(
"Nearest neighbours attached to waters the radius query stranded; "
"0 disables the rescue. Ignored under --dynamic_edge_policy knn "
"(default: 8)"
),
README.md:223
- This paragraph says
--knn_fallback_krescues stranded waters “underradius”, but the implementation explicitly does not rescue under plainradius(only underknn_if_isolated/auto+scaled_gaussian). The README should reflect the actual gating so users don’t expectradius+fallback to work.
This issue also appears on line 228 of the same file.
`--knn_fallback_k` repairs that. Under `radius`, any water the query stranded is
reconnected to that many nearest protein atoms regardless of distance. Set it to
`0` to disable. It has no effect under `knn`, which cannot strand a node.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (3)
README.md:214
- The Edge Construction table says
radiusis the default and only documentsradius/knn, but the CLI default inscripts/train.pyisautoand the code also supportsknn_if_isolated. This mismatch will confuse users about what happens when they omit--dynamic_edge_policy.
| `--dynamic_edge_policy` | Behaviour |
|-------------------------|-----------|
| `radius` (default) | Connect every pair within `--cutoff`, capped at `--max_neighbors` per source |
| `knn` | Connect a fixed number of nearest neighbours (`--k_pw`, `--k_ww`, `--k_wp`) |
src/flow.py:242
build_dynamic_edgesdocumentspolicyas one ofDYNAMIC_EDGE_POLICIES, but the implementation only special-cases"knn"and otherwise falls back to radius behavior. That means typos (or passing"knn_if_isolated") silently change behavior instead of failing fast, and the current homogenous-graph detection usessrc_pos is dst_poswhich misses cases where the same tensor is passed via a different view/copy, leaving self-loops/cap logic inconsistent.
policy: One of DYNAMIC_EDGE_POLICIES.
k: Nearest neighbours per destination, used when policy is "knn".
r: Distance cutoff in Angstroms, used when policy is "radius".
max_neighbors: Per-source cap on radius results.
batch_src: (N_src,) batch assignment for source nodes, or None.
README.md:223
- The README says
--knn_fallback_krescues stranded waters underradius, but the implementation only enables the rescue underknn_if_isolated(orautoresolving to it) and explicitly disables rescue for plainradiuseven whenknn_fallback_k > 0. The docs should match the actual behavior so users can reason about isolation handling.
`--knn_fallback_k` repairs that. Under `radius`, any water the query stranded is
reconnected to that many nearest protein atoms regardless of distance. Set it to
`0` to disable. It has no effect under `knn`, which cannot strand a node.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (4)
README.md:89
- README currently states PW edges are always built at runtime and that every water-touching edge is rebuilt each forward pass, but
ProteinWaterUpdate.build_edgesexplicitly supports using cached PW edges verbatim (e.g. the confidence pipeline). The docs should reflect that PW may be precomputed in some datasets/configurations.
- `('protein', 'pw', 'water')`: protein to water — built at runtime
- `('water', 'wp', 'protein')`: water to protein — built at runtime, ablatable
- `('water', 'ww', 'water')`: water-water edges — built at runtime, ablatable
- Only PP edges are stored in the geometry cache; every water-touching edge is
rebuilt each forward pass, since water positions move during integration. See
src/flow.py:255
homogeneous = src_pos is dst_posonly detects Python object identity. If callers pass two tensors that share the same underlying positions (e.g., views/clones/loaded copies), the function will treat the query as heterogeneous and may emit self-loops under the radius policy (and skip the self-loop filter under KNN). Use a storage/shape-based check instead so homogeneous graphs reliably drop self edges.
# Same object
homogeneous = src_pos is dst_pos
src/flow.py:677
dynamic_edge_policyis documented here as "one of DYNAMIC_EDGE_POLICIES", but the rest of the code/CLI also supports the recorded-config value "auto" (resolved viaresolve_edge_policy). Updating this docstring avoids confusion for callers.
dynamic_edge_policy: How water-touching edges are built, one of
DYNAMIC_EDGE_POLICIES. Default: "radius"
src/flow.py:370
- The docstring says PW/PP are always active, but
etypescurrently allows omitting them (including[]), which can lead to missing required relations or even an emptyGVPMultiEdgeConvsetup. If PW/PP must always be on, validate thatetypesincludes them (or update the docstring to match the actual contract).
unknown = [et for et in (etypes or []) if et not in ALL_EDGE_TYPES]
if unknown:
raise ValueError(
f"etypes must be a subset of {ALL_EDGE_TYPES}, got unknown {unknown}"
)
DorisMai
left a comment
There was a problem hiding this comment.
A few minor questions/comments, address them if you can before merging.
| else: | ||
| edge_index_dict[EDGE_PW] = torch.empty( | ||
| 2, 0, dtype=torch.long, device=device | ||
| # Protein-water and water-protein edges get the extra pass; water-water does not. |
There was a problem hiding this comment.
why does ww edge not get the rescue? also I see that the isolate_axis is different for pw vs wp, might worth a comment in __init__ to explain this asymmetry, as these two fallbacks are really to ensure that all waters always have neighbors to pass or receive messages.
| k_ww=config.get("k_ww") or 16, | ||
| cutoff=config.get("cutoff", 8.0), | ||
| max_neighbors=config.get("max_neighbors", 256), | ||
| dynamic_edge_policy=config.get("dynamic_edge_policy", "radius"), |
There was a problem hiding this comment.
presumably at this point you are only dealing with new training runs that used "radius"? otherwise the old config presumably doesn't save this info, and you don't have cli args in the inference script to overwrite this.
| Build the edge set for one batch under the active policy. | ||
|
|
||
| PP edges are read from the dataset (cached at preprocessing time). | ||
| PP and PW edges are read from the dataset when cached at preprocessing |
There was a problem hiding this comment.
I thought you only cache PP edges because water position changes? Why adding PW cache reading here, do you ever save it as cache?
| n_update_gvps: int = 2, | ||
| vector_gate: bool = True, | ||
| water_input_dim: int = 16, # 1 hot with oxygen, same as encoder | ||
| cutoff: float = 8.0, |
There was a problem hiding this comment.
it looks like this cutoff value is intended to be reused as graph_cutoff when doing uniform ball sampling, which at line 910 (outside diff) also defaults to 8.0 if the cutoff here is not set. Consider extract this as constant to enforce consistency over hard coded value. Also, is this in any way related to the constant RBF_CUTOFF which also happens to be 8.0? If the radial edge cutoff > RBF_CUTOFF, do you get unintended zeroing of features?
| dynamic_edge_policy="knn_if_isolated", | ||
| knn_fallback_k=knn_fallback_k, | ||
| ) | ||
| edge_index = updater.build_edges(data)[EDGE_PW] |
There was a problem hiding this comment.
consider also have a test for the fallback of WP edge
| def test_inference_build_model_from_config_replays_recorded_edge_policy(device): | ||
| """Every recorded config carries "auto". Replaying one must build a model, | ||
| not raise, and must land on the radius path those runs actually used.""" | ||
| config = { |
There was a problem hiding this comment.
do you not need to pass sampling_strategy here and check rescue? if training does scaled_gaussian and "auto" resolves to knn_if_isolated, but inference is radius, is this ok?
| k_pw=8, # keep <= n_water_per | ||
| k_ww=8, # keep <= n_water_per |
There was a problem hiding this comment.
there are a few more traces of these k_pw and k_ww arguments in this test file (lines 266, 334, and 379). If you didn't mean to test explicitly on knn as the edge policy, consider clean those up as well.
etypes,cutoff,max_neighbors,dynamic_edge_policy,knn_fallback_konProteinWaterUpdate, which previously hardcodedALL_EDGE_TYPES. This is the dependencyConfidenceGVPneeds.get_active_edge_types(disable_ww, disable_wp)to ablate WW/WP edges; PW and PP always stay on.build_knn_edges→build_dynamic_edges, supporting both radius and kNN queries, plus a fallback that reconnects nodes a radius query left with no edges in the case of sampling with a scaled gaussian.--k_pw/--k_wwwith--dynamic_edge_policy,--cutoff,--max_neighbors,--knn_fallback_k,--disable_ww,--disable_wp;inference.pyreads the same keys back fromconfig.json.Summary by CodeRabbit
New Features
Documentation
Bug Fixes