Skip to content

fix: 对齐 langgraph-api 的 config/context 互斥与同步语义(runs + assistants) - #65

Merged
webup merged 9 commits into
ob-labs:developfrom
LiangMuYuan:feature/align-context-config
Aug 5, 2026
Merged

fix: 对齐 langgraph-api 的 config/context 互斥与同步语义(runs + assistants)#65
webup merged 9 commits into
ob-labs:developfrom
LiangMuYuan:feature/align-context-config

Conversation

@LiangMuYuan

@LiangMuYuan LiangMuYuan commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • config.configurablecontext 同时非空时返回 400(对齐 langgraph-api 的互斥语义)
  • 两者互相同步:传 context 时写回 config["configurable"];只传 configurable 时推导为 context
  • 图无 context_schema 时,context 不再被静默丢弃,而是通过 config["configurable"] 传递给图,老式节点(读 configurable)可读
  • run 准备阶段(run_preparation.py):assistant 的 config 也作为默认值合并进 run(此前只合并 context,存在 assistant.config.configurable 上的参数运行时读不到)
  • assistant 创建/更新(api/assistants.py):创建和 PATCH 时按 langgraph-api 语义镜像同步 config.configurablecontext(只传一个自动推导另一个;两个都传返回 400)
  • 新增单元/集成测试:互斥校验、双向同步、context_schema 字段过滤、API 层 400、assistant 创建/更新镜像同步

修复方式

execute_run() 在注入内部 key(thread_id / checkpoint 等)之前,先按 langgraph-api 语义处理用户参数:

  • config.configurablecontext 均非空 → ValueErrorapi/runs.py_validate_supported_run_controls 对 runs / stateless runs 直接返回 400)
  • 仅传 context → 镜像到 config["configurable"]
  • 仅传 configurable → 推导为 explicit_context,供 _resolve_run_context 过滤后传给图的 context 参数

_prepare_run()run_preparation.py)把 assistant 的 configcontext 都作为默认值合并进 run kwargs(assistant 为默认、请求覆盖,configurable 子层深合并)。

create_assistant / patch_assistantapi/assistants.py)通过 _consolidate_config_context() 镜像同步 config.configurablecontext,与 langgraph-api 的 ops 层约定一致。

Test Plan

  • uv run pytest tests/unit/test_run_executor.py tests/unit/test_run_controls_validation.py -q(26 passed)
  • uv run pytest tests/integration/test_runs_compat.py tests/integration/test_runs_streaming.py -q(33 passed)
  • uv run pytest tests/integration/test_assistants_config_context_sync.py -q(7 passed)
  • uv run pytest -q(789 passed, 24 skipped,WSL2 Ubuntu 24.04 全量通过)

Target Branch Check

  • feature/* PRs target develop
  • release/* PRs target main
  • hotfix/* PRs target main

Closes #64

- config.configurable 与 context 同时非空时返回 400(对齐 langgraph-api)
- 两者互相同步:传 context 写回 configurable,传 configurable 推导为 context
- 无 context_schema 时 context 仍通过 configurable 传递给图(老式节点可读)

Closes ob-labs#64
- execute_run 不再对合并后的 context 做互斥校验(run_preparation 会合并 assistant 默认 context,两者同时非空是合法场景)
- 互斥 400 仅保留在 API 层,针对客户端原始请求(对齐 langgraph-api)
- context 与 configurable 保持同步/镜像:context 合并进 configurable,仅 configurable 时推导为 context
- 新增集成测试:400 互斥、assistant context + 客户端 configurable 成功、context 参数落 checkpoint metadata
@LiangMuYuan LiangMuYuan changed the title fix(runs): 对齐 langgraph-api 的 config/context 互斥与同步语义 fix: 对齐 langgraph-api 的 config/context 互斥与同步语义(runs + assistants) Aug 4, 2026

@webup webup left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking issue at src/agentseek_api/api/assistants.py:148: if_exists="do_nothing" returns the existing assistant before _consolidate_config_context() runs. Reproduction: create a fixed assistant ID, then POST the same ID with if_exists="do_nothing", non-empty config.configurable, and non-empty context; the endpoint returns 200, while the locked langgraph-api 0.9.0 implementation validates the conflict first and returns 400. Please move the validation/consolidation before this early return and add a regression test for the idempotent-create retry path.

@LiangMuYuan

Copy link
Copy Markdown
Contributor Author

Thanks for the review! This is fixed in 9e287a6.

create_assistant now runs _consolidate_config_context() before the if_exists=do_nothing early return, so the config/context mutual-exclusion check (both non-empty -> 400) is enforced even on idempotent-create retries, matching langgraph-api's consolidate_config_and_context ordering.

Added regression test test_create_do_nothing_retry_still_validates_config_context_conflict covering:

  • retry with a conflicting config.configurable + context -> 400
  • non-conflicting retry -> 200 and returns the existing assistant

Verified on Linux (WSL2): related assistant/config-context tests 57 passed, full tests/unit 531 passed.

@webup webup left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original if_exists="do_nothing" validation blocker is fixed in 9e287a6, but one required follow-up remains on this exact head.

tests/e2e/test_langsmith_compat_live.py:156-157 still sends both a non-empty config.configurable and context. Under the new compatibility contract this correctly returns 400, while _create_assistant() still asserts 200. This currently fails all six MySQL/PostgreSQL database matrix jobs. Please send only one representation in this live test and verify the mirrored value in the response.

Separately, the four Docker/Redis jobs are failing because the generated image resolves mcp>=1.27.1 to mcp 2.0.0, where Server.list_tools() is no longer available. That is not introduced by this PR diff, but the exact-head checks still need a green rerun after it is addressed.

Local verification on 9e287a6: 788 passed, 5 skipped; coverage 90.61%; focused compatibility tests, Ruff, lockfile check, and diff check all pass.

@webup webup left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved on exact head 973738b.

The live database-backed E2E now validates both context-to-config mirroring on create and config-to-context mirroring on patch without sending mutually exclusive inputs. The package also constrains the v1 MCP SDK to <2, so fresh/Docker installs no longer resolve the breaking 2.0 API.

Verification: local coverage suite 788 passed, 5 skipped (90.61%); fresh Python 3.12 install selected MCP 1.29.0 and initialized the low-level server API; exact-head GitHub Actions completed 18/18 checks successfully, including all MySQL/PostgreSQL matrices, Redis durable execution, and CLI Docker Runtime.

@webup
webup merged commit cd9d3c7 into ob-labs:develop Aug 5, 2026
17 checks passed
@webup

webup commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Thanks @LiangMuYuan for the contribution and the quick follow-up on the config/context compatibility fixes. The final update passed the full CI matrix and has now been squash-merged.

@LiangMuYuan
LiangMuYuan deleted the feature/align-context-config branch August 5, 2026 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: config.configurable 与 context 处理与 langgraph-api 不一致

2 participants