Why: F14 source half - exec.ProcessEvent lacked CallID and outcome fields, forcing consumers to pair events by tool name and mark every end ok; cancellations and failures displayed as success downstream. Evidence: loop/adapter tests pass (verify-u11a.json); pairing, denial, cancellation and concurrent-callback cases added. Impact: new omitempty fields only; legacy events unchanged. Refs: feature/agent-stack-audit-remediation-b2 U11a
53 lines
1.5 KiB
Go
53 lines
1.5 KiB
Go
package runtime
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"agent-native/runtime/llm"
|
|
"agent-native/runtime/tools"
|
|
)
|
|
|
|
// TestLoopToolEventsCarryCallID 验证 tool_execution_start/end 事件带工具调用
|
|
// ID:并行执行下消费方按 ID 配对(回归锚点,防止字段被删后顺序假设回归)。
|
|
func TestLoopToolEventsCarryCallID(t *testing.T) {
|
|
hits := 0
|
|
reg := tools.NewRegistry(t.TempDir())
|
|
reg.Register(hitTool{hits: &hits})
|
|
var starts, ends []Event
|
|
res, err := Run(context.Background(), Config{
|
|
Model: "fake",
|
|
Tools: reg,
|
|
Stream: script(
|
|
llm.Message{Role: llm.RoleAssistant, StopReason: llm.StopToolCalls, ToolCalls: []llm.ToolCall{{
|
|
ID: "call-7", Name: "echo", Arguments: `{}`,
|
|
}}},
|
|
llm.Message{Role: llm.RoleAssistant, Content: "done", StopReason: llm.StopEnd},
|
|
),
|
|
OnEvent: func(ev Event) {
|
|
switch ev.Type {
|
|
case "tool_execution_start":
|
|
starts = append(starts, ev)
|
|
case "tool_execution_end":
|
|
ends = append(ends, ev)
|
|
}
|
|
},
|
|
}, llm.Message{Role: llm.RoleUser, Content: "go"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if hits != 1 || len(starts) != 1 || len(ends) != 1 {
|
|
t.Fatalf("hits=%d starts=%d ends=%d", hits, len(starts), len(ends))
|
|
}
|
|
if starts[0].CallID != "call-7" || starts[0].Tool != "echo" {
|
|
t.Fatalf("start = %+v", starts[0])
|
|
}
|
|
if ends[0].CallID != "call-7" || ends[0].Tool != "echo" {
|
|
t.Fatalf("end = %+v", ends[0])
|
|
}
|
|
if ends[0].Status != "ok" || ends[0].ErrorReason != "" {
|
|
t.Fatalf("successful end must be ok with empty ErrorReason: %+v", ends[0])
|
|
}
|
|
_ = res
|
|
}
|