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 7e01b1062e
commit 81705a782e
2 changed files with 49 additions and 3 deletions

View File

@ -5,9 +5,11 @@ import (
"strings"
"testing"
"time"
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
)
// awaitOutputResult 的 decision 核心:
// output_send 不再假成功(plan.md 11.1):sent / error / unconfirmed 三态。
func TestAwaitOutputResult_Success(t *testing.T) {
res, err := awaitOutputResultWith(0, "qq", `{"x":1}`, func(pid int32, ch, args string) error {
@ -47,3 +49,44 @@ func TestAwaitOutputResult_Timeout(t *testing.T) {
t.Fatalf("expected status=unconfirmed, got %v", m["status"])
}
}
// applyStageResult 必须能表达「插件清空了 tool_calls/tool_results」——
// ABI v2 diff 回传(plan.md 11.3)下插件拒绝全部工具调用时会显式回传 []。
func TestApplyStageResult_ClearedSlicesAreApplied(t *testing.T) {
sc := &sdk.StageContext{
ToolCalls: []sdk.ToolCall{{ID: "t1", Name: "cmd_run"}},
ToolResults: []sdk.ToolResult{{CallID: "t1", Name: "cmd_run", Result: "x"}},
}
applyStageResult(sc, `{"tool_calls":[],"tool_results":[]}`)
if len(sc.ToolCalls) != 0 {
t.Fatalf("tool_calls 应被清空,实际 %v", sc.ToolCalls)
}
if len(sc.ToolResults) != 0 {
t.Fatalf("tool_results 应被清空,实际 %v", sc.ToolResults)
}
}
// diff 回传只带变更字段:未出现的键不得被改动(避免旧快照覆盖)。
func TestApplyStageResult_OnlyPresentKeysApplied(t *testing.T) {
sc := &sdk.StageContext{
RawMessage: "原始输入",
LLMText: "原始LLM",
FinalText: "原始最终",
ToolResults: []sdk.ToolResult{{CallID: "c1", Result: "已清洗"}},
}
// 只回传 final_text 的变更
applyStageResult(sc, `{"final_text":"新最终"}`)
if sc.FinalText != "新最终" {
t.Fatalf("final_text 应被应用,实际 %q", sc.FinalText)
}
if sc.RawMessage != "原始输入" {
t.Errorf("raw_message 未回传却被改动: %q", sc.RawMessage)
}
if sc.LLMText != "原始LLM" {
t.Errorf("llm_text 未回传却被改动: %q", sc.LLMText)
}
if len(sc.ToolResults) != 1 || sc.ToolResults[0].Result != "已清洗" {
t.Errorf("tool_results 未回传却被改动: %v", sc.ToolResults)
}
}