Skip to content

fix(responses): 支持 Codex 多智能体协议与工具身份双向映射 - #45

Merged
maiphucgiang merged 1 commit into
maiphucgiang:devfrom
ItQianChen:feat/responses-multiagent-compat
Sep 26, 2026
Merged

maiphucgiang merged 1 commit into
maiphucgiang:devfrom
ItQianChen:feat/responses-multiagent-compat

Conversation

@ItQianChen

@ItQianChen ItQianChen commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

描述 (Description)

1. 背景与目标

在 Codex 官方客户端通过 /v1/responses 接口调用多智能体协作时,解决协作工具丢失、子智能体 Payload 丢失以及工具身份错位问题。本次调整基于上游最新 main 建立全新分支,根据 PR #44 的评审意见完成调整。

2. 主要改进 (Key Changes)

  1. 统一行尾为 LF:清除所有无关 CRLF 换行符,将代码变更严格收敛至逻辑实现。
  2. 基于 (namespace, name) 的双向工具身份映射 (ToolRegistry):
    • 普通工具(未声明命名空间)严格保持原始名称(如 collaboration__spawn_agent 不会被擅自修改);
    • 命名空间工具映射为 {namespace}__{name},若发生名称冲突通过安全索引自愈;不同命名空间下的同名工具(如 ns1.search 与 ns2.search)各自分配唯一名称;
    • 彻底移除对 __ 的硬编码切分与前缀猜测,工具名包含双下划线时(如 custom_ns.exec__command)能够精确还原身份;
    • 同步映射输入历史中的 function_call 与 tool_choice;
    • 确保发往上游前清除内部映射元数据(如 _tool_registry)。
  3. 多智能体正文提取与 Schema 纯净化:
    • 支持提取 agent_message 中挂载在 encrypted_content 属性下的明文文本;
    • 递归清理参数 Schema 中各层级的 "encrypted": true 客户端标记。
  4. 补充接口级回归测试:
    • 新增 tests/test_responses_multiagent.py,经由 /v1/responses 路由全面覆盖非流式、缓冲流式与实时流式,验证不同命名空间同名工具隔离、普通工具防篡改、含 __ 工具名还原及内部元数据纯净度。

3. 验证结果

python -m pytest tests/test_responses_adapter.py tests/test_responses_multiagent.py
# 30 passed in 0.41s

## Summary by Sourcery

Enable reliable Codex multi-agent tool interoperability through bidirectional tool identity mapping and clean Responses-to-Chat conversion.

New Features:
- Support Codex multi-agent Responses payloads, including additional tools, namespaced tools, and encrypted agent message content.

Bug Fixes:
- Preserve and restore tool identities across Responses and Chat Completions, including collisions, ordinary names containing double underscores, historical function calls, and tool choices.

Enhancements:
- Sanitize client-only encrypted schema markers and remove internal tool mapping metadata before forwarding requests upstream.

Tests:
- Add adapter and interface-level regression coverage for non-streaming, buffered streaming, and realtime streaming multi-agent Responses flows.

- 基于 (namespace, name) 建立 ToolRegistry 双向映射,解决同名工具冲突并保持未声明命名空间的普通工具原名
- 修复反向映射逻辑,移除硬编码前缀猜测,支持命名空间内包含双下划线名称的工具正确还原
- 同步转换输入历史中的 function_call 与 tool_choice 为上游对应函数名
- 递归清理工具参数 Schema 中的 'encrypted' 客户端私有标记,提取 agent_message 中的 encrypted_content
- 在发往上游前统一清除 _tool_registry 等内部私有元数据
- 统一全量修改文件行尾为 LF,杜绝无关格式差异
- 新增单元测试与覆盖非流式、缓冲流式及实时流式接口级回归测试
@sourcery-ai

sourcery-ai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Adds end-to-end Codex multi-agent support for /v1/responses by mapping namespaced tool identities losslessly across Responses and Chat formats, preserving agent payloads, sanitizing schemas, stripping internal metadata upstream, and validating behavior across all response modes.

Sequence diagram for Codex multi-agent Responses tool mapping

sequenceDiagram
    participant Codex
    participant ResponsesAdapter
    participant UpstreamChat
    participant StreamConverter

    Codex->>ResponsesAdapter: responses_request_to_chat(body)
    ResponsesAdapter->>ResponsesAdapter: _collect_raw_tools(tools)
    ResponsesAdapter->>ResponsesAdapter: _build_tool_registry_and_chat_tools(raw_tools)
    ResponsesAdapter->>ResponsesAdapter: _convert_input_items(items, tool_registry)
    ResponsesAdapter->>UpstreamChat: Chat request with mapped function names
    UpstreamChat-->>StreamConverter: function_call using upstream name
    StreamConverter->>StreamConverter: _fc_item(...)
    StreamConverter->>ResponsesAdapter: Responses function_call with namespace and original name
    ResponsesAdapter-->>Codex: /v1/responses output
Loading

File-Level Changes

Change Details Files
Introduces a bidirectional registry that preserves Responses tool identities while exposing collision-safe Chat-compatible names.
  • Collects tools from top-level and additional_tools entries, including recursively nested namespaces.
  • Preserves unnamespaced names, assigns unique namespace/name mappings, and serializes the mapping for response reconstruction.
  • Applies mappings to historical function calls and tool_choice without parsing double underscores heuristically.
  • Restores namespace and original tool name in non-streaming, buffered-streaming, and realtime responses.
  • Removes internal registry fields before forwarding requests upstream.
app/adapters/responses_adapter.py
converter.py
Adds multi-agent input handling and sanitizes client-only tool metadata before upstream conversion.
  • Extracts agent_message text from encrypted_content parts.
  • Ignores additional_tools items in the message sequence while registering their tools.
  • Recursively removes encrypted markers from parameter schemas.
  • Supports normalized names for tool definitions and maintains the existing conversion helper.
app/adapters/responses_adapter.py
Adds regression coverage for protocol conversion, identity isolation, and all Responses streaming modes.
  • Tests plain-tool preservation, namespace collisions, same-name tools across namespaces, and names containing double underscores.
  • Verifies tool_choice and historical function-call mapping, encrypted-content extraction, schema cleanup, and metadata removal.
  • Exercises /v1/responses in non-streaming, buffered streaming, and realtime streaming paths.
tests/test_responses_adapter.py
tests/test_responses_multiagent.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. If the registry maps a namespaced or historical tool call incorrectly, the upstream model can invoke the wrong function, and that function may perform an external side effect before the change is reverted. Reverting stops future misrouting but cannot undo tool actions already executed.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@maiphucgiang
maiphucgiang changed the base branch from main to dev September 26, 2026 14:50
@maiphucgiang
maiphucgiang merged commit 17820f9 into maiphucgiang:dev Sep 26, 2026
8 checks passed
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.

2 participants