fix(cabi): applyStageResult 支持 diff 回传(plan 11.3 配套)

外部插件 bridge 模板改为只回传变更字段后(SDK 仓 5648519),内核侧配套:
- applyStageResult 的 tool_calls/tool_results 去掉 len(v)>0 拦截——改为键存在即应用,
  使插件「清空全部工具调用」的显式回传 [] 能被表达(旧插件仅 len>0 才带键,不误清空)
- 逐字段应用,未回传的键保持原值(diff 语义:只改变更字段,不覆盖他人改写)
- output_test.go 新增 TestApplyStageResult_ClearedSlicesAreApplied / _OnlyPresentKeysApplied

验证: go build exit 0; go test ./internal/plugin/... ./internal/agent/... 全绿
This commit is contained in:
dev
2026-08-31 12:30:04 +08:00
parent b74ee15321
commit 9bb9cb3b1a
2 changed files with 49 additions and 3 deletions

View File

@ -360,7 +360,10 @@ func applyStageResult(sc *sdk.StageContext, resultJSON string) {
vv := v
sc.Response = &vv
}
if v, ok := m["tool_calls"].([]interface{}); ok && len(v) > 0 {
if v, ok := m["tool_calls"].([]interface{}); ok {
// 注意不要加 len(v)>0 条件:ABI v2 diff 回传(plan.md 11.3)下,插件拒绝全部
// 工具调用时会显式回传 `[]`,必须能表达「清空」。旧插件(全量回传)仅在
// len>0 时才带该键,因此不会因此变更而被误清空。
if b, err := json.Marshal(v); err == nil {
var tcs []sdk.ToolCall
if json.Unmarshal(b, &tcs) == nil {
@ -368,7 +371,7 @@ func applyStageResult(sc *sdk.StageContext, resultJSON string) {
}
}
}
if v, ok := m["tool_results"].([]interface{}); ok && len(v) > 0 {
if v, ok := m["tool_results"].([]interface{}); ok {
if b, err := json.Marshal(v); err == nil {
var trs []sdk.ToolResult
if json.Unmarshal(b, &trs) == nil {