fix(langgraph): implement content_not_contains condition in pure graph edge evaluator #100

Merged
CoreRasurae merged 1 commits from bugfix/m1-pure-graph-content-not-contains into master 2026-08-04 12:39:02 +00:00

1 Commits

Author SHA1 Message Date
CoreRasurae a0c2119cc3 fix(langgraph): implement content_not_contains condition in pure graph edge evaluator
CI / lint (pull_request) Successful in 53s
CI / typecheck (pull_request) Successful in 1m38s
CI / security (pull_request) Successful in 1m22s
CI / quality (pull_request) Successful in 1m57s
CI / build (pull_request) Successful in 58s
CI / integration_tests (pull_request) Successful in 3m31s
CI / unit_tests (pull_request) Successful in 6m3s
CI / coverage (pull_request) Successful in 6m5s
CI / status-check (pull_request) Successful in 16s
CI / benchmark (pull_request) Failing after 16m56s
CI / lint (push) Successful in 1m5s
CI / typecheck (push) Successful in 1m45s
CI / security (push) Successful in 2m11s
CI / quality (push) Successful in 2m18s
CI / build (push) Successful in 2m29s
CI / integration_tests (push) Successful in 3m5s
CI / unit_tests (push) Successful in 4m30s
CI / coverage (push) Successful in 5m7s
CI / status-check (push) Successful in 14s
CI / benchmark (push) Successful in 15m51s
PureLangGraph._evaluate_edge_condition() had no branch for
content_not_contains (Actor Configuration Standard §5.4), so it fell
into the "unknown condition type" catch-all and always returned True.
A classifier node with sibling content_contains/content_not_contains
edges (the classic if/else idiom) would traverse both edges whenever
the configured text was present, instead of the single edge intended.

Adds a content_not_contains branch mirroring the existing correct
implementations in nodes.py, bridge.py, and reactive/stream_router.py:
true when the text is absent from the (stringified) message content,
for both string and dict messages; falls back to True (not found, so
not contained) for any other message shape, matching the sibling
content_not_contains implementations' "absent" fallback rather than
content_contains's False fallback.

Removes @tdd_expected_fail from the issue #95 regression scenario now
that the fix makes it pass unconditionally, and adds direct
content_not_contains true/false coverage plus a sibling-edge scenario
for the text-absent direction. Adds a Robot integration test
(robot/pure_graph_sibling_edges.robot, robot/PureGraphLib.py) that
executes a real two-branch pure graph end-to-end and asserts exactly
one branch node runs for each direction.

Per rui.hu's PR #100 review: adds direct coverage of the non-string/
non-dict message fallback branch (previously untested) and updates the
step-definitions module docstring, which was stale about which method
the scenarios exercise. The reviewer's coverage-threshold-reconciliation
note is a pre-existing, project-wide config/doc mismatch out of scope
for this issue and was already addressed in review comments.

Verified locally (Forgejo CI is currently down): nox -s lint, format
--check, typecheck, unit_tests (2905/2905 scenarios) are green, and the
new fallback scenario covers the previously-uncovered line in
pure_graph.py.

ISSUES CLOSED: #95
Refs: #96
2026-08-04 12:14:41 +00:00