SharedChat Adapter Tool Bridge 与 systemd 托管修复记录
SharedChat Codex Adapter 已从“纯文本 Chat→Responses 转换器”升级为可支持 Hermes agent 工具调用的 bridge;SC-GPT-5.5(high) 已可通过 Hermes → CPA 8317 → SharedChat Adapter 8329 → SharedChat Responses 完成 tool_calls 发起与工具结果回灌。
保留 sharedchat-codex-adapter.service 作为 systemd --user 托管入口,继续通过 CPA alias SC-GPT-5.5(high) 使用,不再手动裸跑 Python 进程。
本地转换回归、SharedChat 上游 function_call 探针、adapter 8329 本地请求、CPA 8317 真实链路、双轮工具回灌均已验证通过。
代码落在 /home/ht/code/sharedchat_codex_adapter.py,回归测试落在 /home/ht/code/test_sharedchat_codex_adapter_bridge.py,服务单元为 /home/ht/.config/systemd/user/sharedchat-codex-adapter.service。
证据摘要
- 本地转换回归、SharedChat 上游 function_call 探针、adapter 8329 本地请求、CPA 8317 真实链路、双轮工具回灌均已验证通过。
行动清单
边界 / 风险
当前 tools 场景下 adapter 用 non-stream upstream + synthetic SSE。这保证 Hermes tool loop 正确,但不提供真实逐 token / 逐 delta tool_call streaming。 处理建议:除非明确需要低延迟 tool_call delta,否则保持当前保守实现。
output[].type=function_call call_id name arguments 如果 SharedChat 上游更换 Responses 格式,需要更新 _responses_tool_calls()。
bridge 已确保工具 schema 可达,但模型是否选择调用工具仍由模型行为决定。若需要强制调用,应使用 tool_choice。
完整记录
SharedChat Adapter Tool Bridge 与 systemd 托管修复记录
背景
本轮问题来自 WebUI 中一开始使用 SC-GPT-5.5(high) 时,助手回复“没有 terminal/web_search/skill_view 等工具”;切换到 gpt-5.5 后工具立即可用。排查后确认:Hermes/WebUI 工具注册本身正常,问题集中在 SC-GPT-5.5(high) 的 provider 路径。
实际链路为:
CPA 配置中 alias 映射:
根因
旧版 /home/ht/code/sharedchat_codex_adapter.py 是最小文本 adapter,仅转换:
modelmessages -> inputmax_tokens / max_completion_tokens -> max_output_tokenstemperaturetop_pstream
但没有处理:
- OpenAI Chat
tools - OpenAI Chat
tool_choice parallel_tool_calls- assistant 历史
tool_calls role=tool工具结果- Responses
function_call回 Chatmessage.tool_calls
因此 Hermes 虽然把工具 schema 交给模型请求,但经过 adapter 时被静默丢弃,上游模型看不到工具定义,只能以普通文本模型行为回复。
本次修改
1. 补 Chat Completions → Responses tools bridge
新增转换能力:
- Chat
tools[{type:function,function:{...}}]→ Responsestools[{type:function,name,description,parameters,strict}] - Chat
tool_choice→ Responsestool_choice parallel_tool_calls透传role=tool→ Responsesfunction_call_output- assistant prior
tool_calls→ Responsesfunction_call
2. 补 Responses → Chat tool_calls bridge
新增转换能力:
- Responses
output[].type=function_call→ OpenAI Chatmessage.tool_calls[] - function call
call_id/name/arguments保持 OpenAI-compatible 结构 - 存在 tool_calls 时,
finish_reason=tool_calls - 普通文本仍保持
message.content与finish_reason=stop
3. 处理 tools 场景 streaming
为了避免半成品 streaming tool delta 破坏 Hermes agent loop:
- 无 tools 的普通 streaming:继续使用原 Responses SSE → Chat chunk 路径。
- 有 tools 的 streaming:adapter 改为先非流式请求上游,再合成 OpenAI SSE,输出 role/content/tool_calls/final chunk。
这是当前最稳的兼容策略:优先保证工具调用闭环,而不是追求低延迟 token streaming。
4. 增加本地回归测试
新增:
覆盖:
- tools 不再被静默丢弃
- tool_choice 正确转换
- assistant tool_calls 与 role=tool 能回灌到 Responses input
- Responses function_call 能转回 OpenAI Chat tool_calls
- 普通文本响应不受影响
systemd 托管状态
服务单元:
当前单元内容:
已执行并确认:
运行态:
监听:
健康检查:
验证记录
1. 语法与本地回归测试
命令:
结果:
2. SharedChat 上游 function_call 探针
直接请求 https://new.sharedchat.cc/codex/v1/responses,携带 Responses tools 与强制 tool_choice,上游返回:
说明上游本身支持 function calling;旧问题不是上游能力缺失,而是 adapter 未桥接。
3. Adapter 本地 8329 探针
请求:
返回关键字段:
4. CPA 8317 真实链路探针
请求模型:
返回:
这证明完整两轮 agent loop 已闭环:
- 模型发起 tool_call。
- Hermes/调用方执行工具。
- tool result 回灌给模型。
- 模型基于工具结果继续自然语言回答。
影响范围
已改善
SC-GPT-5.5(high)可以像正常 Hermes agent 模型一样使用工具。- 不再因为 adapter 丢弃 tools 而误报“没有工具”。
- CPA alias 路径不需要改,Hermes 配置不需要改。
未改变
- CPA 主服务 8317 未重启、未修改。
- Hermes WebUI 未重启、未修改。
- SharedChat 上游凭证和 base URL 未变。
- 普通文本 Chat/SSE 行为保持兼容。
风险与边界
风险 1:streaming tool_calls 不是原生 delta
当前 tools 场景下 adapter 用 non-stream upstream + synthetic SSE。这保证 Hermes tool loop 正确,但不提供真实逐 token / 逐 delta tool_call streaming。
处理建议:除非明确需要低延迟 tool_call delta,否则保持当前保守实现。
风险 2:上游 Responses 事件格式未来可能变化
当前解析兼容常见字段:
output[].type=function_callcall_idnamearguments
如果 SharedChat 上游更换 Responses 格式,需要更新 _responses_tool_calls()。
风险 3:SC 模型是否主动调用工具仍受模型策略影响
bridge 已确保工具 schema 可达,但模型是否选择调用工具仍由模型行为决定。若需要强制调用,应使用 tool_choice。
回滚方式
如果需要回滚 adapter 代码:
- 恢复
/home/ht/code/sharedchat_codex_adapter.py到上一版。 - 执行:
如果只想临时绕开 SC 模型:
- Hermes 默认模型改回 CPA Codex/OAuth 主链路模型,例如
gpt-5.5。 - 或在会话中手动切换到已确认支持 tools 的模型。
后续建议
- 保留本地测试文件,后续改 adapter 时先跑:
- 如果继续接入新的 Responses-only provider,复用这套 bridge,不要再写只转文本的最小 adapter。
- 若后续要把
SC-GPT-5.5(high)设回默认模型,建议先在 Hermes WebUI 中用真实工具任务做一次人工 smoke:例如“查本机时间/查文件/查 GitHub release”,确认模型能发起工具调用。
关键路径索引
- Adapter:
/home/ht/code/sharedchat_codex_adapter.py - 回归测试:
/home/ht/code/test_sharedchat_codex_adapter_bridge.py - systemd unit:
/home/ht/.config/systemd/user/sharedchat-codex-adapter.service - env file:
/home/ht/.config/sharedchat-codex-adapter/env - CPA config:
/home/ht/cli-proxy-api/config.yaml - Adapter health:
http://127.0.0.1:8329/health - CPA endpoint:
http://127.0.0.1:8317/v1/chat/completions