Files
tutti/packages/agent/daemon/runtime/codex_appserver_websearch_test.go
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

106 lines
3.5 KiB
Go

package agentruntime
import "testing"
// The Codex app-server webSearch item is {id, query, action?}; for a `search`
// action the real query lives in action.query or action.queries[], while the
// top-level `query` is frequently empty. These tests lock in that the daemon
// reads the action so the GUI does not render an empty web-search row.
func TestAppServerWebSearchReadsActionQuery(t *testing.T) {
item := map[string]any{
"id": "ws_1",
"type": "webSearch",
"status": "completed",
"query": "",
"action": map[string]any{"type": "search", "query": "tutti release notes"},
}
update, ok := appServerItemToolCallUpdate(item, true)
if !ok {
t.Fatalf("expected webSearch item to produce an update")
}
rawInput, _ := update["rawInput"].(map[string]any)
if got := asString(rawInput["query"]); got != "tutti release notes" {
t.Fatalf("rawInput.query = %q, want %q", got, "tutti release notes")
}
action, _ := rawInput["action"].(map[string]any)
if got := asString(action["query"]); got != "tutti release notes" {
t.Fatalf("action.query = %q, want %q", got, "tutti release notes")
}
}
func TestAppServerWebSearchReadsActionQueriesArray(t *testing.T) {
item := map[string]any{
"id": "ws_2",
"type": "webSearch",
"status": "completed",
"action": map[string]any{
"type": "search",
"queries": []any{"first query", "second query"},
},
}
update, ok := appServerItemToolCallUpdate(item, true)
if !ok {
t.Fatalf("expected webSearch item to produce an update")
}
rawInput, _ := update["rawInput"].(map[string]any)
if got := asString(rawInput["query"]); got != "first query" {
t.Fatalf("rawInput.query = %q, want %q", got, "first query")
}
searchQuery, _ := rawInput["search_query"].([]any)
if len(searchQuery) != 2 {
t.Fatalf("rawInput.search_query = %#v, want 2 entries", rawInput["search_query"])
}
}
// The Codex web search streams an empty input on `started` and the real query
// only on `completed`. The completed activity event must carry that input or the
// query is dropped when it merges with the empty started payload.
func TestAcpToolCallEventCompletedCarriesWebSearchInput(t *testing.T) {
completed := map[string]any{
"sessionUpdate": "tool_call_update",
"toolCallId": "ws_42",
"kind": "fetch",
"status": "completed",
"rawInput": map[string]any{
"query": "tutti release notes",
"action": map[string]any{"type": "search", "query": "tutti release notes"},
},
}
session := Session{Provider: "codex", AgentSessionID: "agent-ws", RoomID: "room-ws"}
event, ok := acpToolCallEventWithID(session, "evt-1", "turn-1", completed)
if !ok {
t.Fatalf("expected completed web search update to produce an event")
}
if event.Type != EventCallCompleted {
t.Fatalf("event.Type = %q, want EventCallCompleted", event.Type)
}
input, _ := event.Payload.Metadata["input"].(map[string]any)
if got := asString(input["query"]); got != "tutti release notes" {
t.Fatalf("completed event input.query = %q, want %q (raw=%#v)", got, "tutti release notes", event.Payload.Metadata["input"])
}
}
func TestAppServerWebSearchTopLevelQueryFallback(t *testing.T) {
item := map[string]any{
"id": "ws_3",
"type": "webSearch",
"query": "legacy top-level query",
}
update, ok := appServerItemToolCallUpdate(item, false)
if !ok {
t.Fatalf("expected webSearch item to produce an update")
}
rawInput, _ := update["rawInput"].(map[string]any)
if got := asString(rawInput["query"]); got != "legacy top-level query" {
t.Fatalf("rawInput.query = %q, want %q", got, "legacy top-level query")
}
}