X-Git-Url: http://git.giacomolli.uk/onechat/blobdiff_plain/f59bb67ae1bc2c899ef4f6be9ce2ff6296c7ffcc..d50c22617aafed0d3d87bf4596e933b343a10b60:/turn_test.go diff --git a/turn_test.go b/turn_test.go index f1295e9..c378469 100644 --- a/turn_test.go +++ b/turn_test.go @@ -15,22 +15,22 @@ import ( ) func TestTurnRunsToolsUntilTheFinalAnswer(t *testing.T) { - server := newFakeResponses(t) - server.reply = func(w http.ResponseWriter, call fakeCall) { + server := newModelFake(t) + server.reply = func(w http.ResponseWriter, call ModelFakeCall) { if call.number == 0 { - writeEvents(w, completedEvent([]any{ - reasoningItem("rs_1", "opaque thought"), - functionCallItem("fc_1", "call_1", "shell", `{"command":"echo hi"}`), + modelWriteEvents(w, modelCompletedEvent([]any{ + modelReasoningItem("rs_1", "opaque thought"), + modelFunctionCallItem("fc_1", "call_1", "shell", `{"command":"echo hi"}`), }, 100, 0, 5)) return } - writeEvents(w, completedEvent([]any{messageItem("It said hi.")}, 120, 100, 5)) + modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("It said hi.")}, 120, 100, 5)) } test := newTestLoop(t, server) - _, err := test.loop.Submit("Run echo hi.") + _, err := test.loop.Submit(terminalSource, "Run echo hi.") require.NoError(t, err) test.events.WaitFor(t, "idle", 1) require.Equal(t, 2, server.Calls()) @@ -61,7 +61,7 @@ func TestTurnRunsToolsUntilTheFinalAnswer(t *testing.T) { require.Equal(t, []string{"user", "busy", "tool", "echo", "reply", "idle"}, test.events.Kinds()) var turns []string - for _, record := range readUsage(t, test.usagePath) { + for _, record := range modelReadUsage(t, test.usagePath) { turns = append(turns, record.Turn) } @@ -69,12 +69,12 @@ func TestTurnRunsToolsUntilTheFinalAnswer(t *testing.T) { } func TestFirstRequestHoldsTheViewTheStateAndTheMessage(t *testing.T) { - server := newFakeResponses(t) + server := newModelFake(t) test := newTestLoop(t, server) _, err := test.memory.Append("user", "an earlier message") require.NoError(t, err) - _, err = test.loop.Submit("The new message.") + _, err = test.loop.Submit(terminalSource, "The new message.") require.NoError(t, err) test.events.WaitFor(t, "idle", 1) @@ -86,27 +86,27 @@ func TestFirstRequestHoldsTheViewTheStateAndTheMessage(t *testing.T) { } func TestMessageDuringATurnJoinsTheNextRequest(t *testing.T) { - server := newFakeResponses(t) + server := newModelFake(t) arrived := make(chan struct{}) release := make(chan struct{}) - server.reply = func(w http.ResponseWriter, call fakeCall) { + server.reply = func(w http.ResponseWriter, call ModelFakeCall) { if call.number == 0 { close(arrived) <-release - writeEvents(w, completedEvent([]any{functionCallItem("fc_1", "call_1", "date", `{"id":0}`)}, 100, 0, 5)) + modelWriteEvents(w, modelCompletedEvent([]any{modelFunctionCallItem("fc_1", "call_1", "date", `{"id":0}`)}, 100, 0, 5)) return } - writeEvents(w, completedEvent([]any{messageItem("done")}, 100, 0, 5)) + modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("done")}, 100, 0, 5)) } test := newTestLoop(t, server) - _, err := test.loop.Submit("first") + _, err := test.loop.Submit(terminalSource, "first") require.NoError(t, err) <-arrived - _, err = test.loop.Submit("second, during the turn") + _, err = test.loop.Submit(terminalSource, "second, during the turn") require.NoError(t, err) close(release) @@ -123,24 +123,24 @@ func TestMessageDuringATurnJoinsTheNextRequest(t *testing.T) { } func TestMessageDuringTheFinalRequestStartsANewTurn(t *testing.T) { - server := newFakeResponses(t) + server := newModelFake(t) arrived := make(chan struct{}) release := make(chan struct{}) - server.reply = func(w http.ResponseWriter, call fakeCall) { + server.reply = func(w http.ResponseWriter, call ModelFakeCall) { if call.number == 0 { close(arrived) <-release } - writeEvents(w, completedEvent([]any{messageItem("answer")}, 100, 0, 5)) + modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("answer")}, 100, 0, 5)) } test := newTestLoop(t, server) - _, err := test.loop.Submit("first") + _, err := test.loop.Submit(terminalSource, "first") require.NoError(t, err) <-arrived - _, err = test.loop.Submit("second") + _, err = test.loop.Submit(terminalSource, "second") require.NoError(t, err) close(release) @@ -153,7 +153,7 @@ func TestMessageDuringTheFinalRequestStartsANewTurn(t *testing.T) { } func TestTurnWaitsForTheSummaries(t *testing.T) { - server := newFakeResponses(t) + server := newModelFake(t) summarizer := newFakeSummarizer() summarizer.gate = make(chan struct{}) test := newTestLoopWith(t, server, summarizer) @@ -161,7 +161,7 @@ func TestTurnWaitsForTheSummaries(t *testing.T) { _, err := test.memory.Append("echo", strings.Repeat("long output ", 100)) require.NoError(t, err) - _, err = test.loop.Submit("go on") + _, err = test.loop.Submit(terminalSource, "go on") require.NoError(t, err) time.Sleep(50 * time.Millisecond) @@ -174,20 +174,20 @@ func TestTurnWaitsForTheSummaries(t *testing.T) { } func TestInterruptEndsTheTurn(t *testing.T) { - server := newFakeResponses(t) + server := newModelFake(t) arrived := make(chan struct{}) release := make(chan struct{}) - server.reply = func(w http.ResponseWriter, call fakeCall) { + server.reply = func(w http.ResponseWriter, call ModelFakeCall) { if call.number == 0 { close(arrived) <-release } - writeEvents(w, completedEvent([]any{messageItem("answer")}, 100, 0, 5)) + modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("answer")}, 100, 0, 5)) } test := newTestLoop(t, server) - _, err := test.loop.Submit("a long task") + _, err := test.loop.Submit(terminalSource, "a long task") require.NoError(t, err) <-arrived @@ -199,20 +199,20 @@ func TestInterruptEndsTheTurn(t *testing.T) { require.Equal(t, []string{"user: a long task"}, test.Log(t)) require.False(t, test.loop.Interrupt()) - _, err = test.loop.Submit("again") + _, err = test.loop.Submit(terminalSource, "again") require.NoError(t, err) test.events.WaitFor(t, "idle", 2) require.Equal(t, "reply: answer", test.Log(t)[2]) } func TestFailedCallEndsTheTurnWithoutARetry(t *testing.T) { - server := newFakeResponses(t) - server.reply = func(w http.ResponseWriter, call fakeCall) { + server := newModelFake(t) + server.reply = func(w http.ResponseWriter, call ModelFakeCall) { http.Error(w, "busy", http.StatusServiceUnavailable) } test := newTestLoop(t, server) - _, err := test.loop.Submit("hello") + _, err := test.loop.Submit(terminalSource, "hello") require.NoError(t, err) test.events.WaitFor(t, "idle", 1) @@ -222,10 +222,10 @@ func TestFailedCallEndsTheTurnWithoutARetry(t *testing.T) { } func TestViewMessagesOnlyGrowBetweenTurns(t *testing.T) { - server := newFakeResponses(t) + server := newModelFake(t) test := newTestLoop(t, server) for n, text := range []string{"one", "two", "three"} { - _, err := test.loop.Submit(text) + _, err := test.loop.Submit(terminalSource, text) require.NoError(t, err) test.events.WaitFor(t, "idle", n+1) } @@ -327,7 +327,7 @@ func (r *eventRecorder) WaitFor(t *testing.T, kind string, count int) { }, 10*time.Second, time.Millisecond) } -func newTestLoop(t *testing.T, server *fakeResponses) *testLoop { +func newTestLoop(t *testing.T, server *ModelFake) *testLoop { t.Helper() return newTestLoopWith(t, server, newFakeSummarizer()) @@ -335,7 +335,7 @@ func newTestLoop(t *testing.T, server *fakeResponses) *testLoop { // newTestLoopWith returns a running loop on a new agent whose builds use // summarizer and whose commands run in a temporary directory. -func newTestLoopWith(t *testing.T, server *fakeResponses, summarizer Summarizer) *testLoop { +func newTestLoopWith(t *testing.T, server *ModelFake, summarizer Summarizer) *testLoop { t.Helper() agent, err := openAgent(t.TempDir()) @@ -353,7 +353,7 @@ func newTestLoopWith(t *testing.T, server *fakeResponses, summarizer Summarizer) usagePath: filepath.Join(t.TempDir(), "usage.jsonl"), } - client := newClient(server.URL, apiKey(testKey), agent.CacheKey(), test.usagePath) + client := newModelClient(server.URL, ModelAPIKey(modelTestKey), agent.CacheKey(), test.usagePath) test.loop, err = newLoop(agent, memory, client, clock.Now, test.events.Add) require.NoError(t, err) ctx, cancel := context.WithCancel(t.Context()) @@ -372,7 +372,7 @@ func newTestLoopWith(t *testing.T, server *fakeResponses, summarizer Summarizer) } // inputTexts returns the text of each user message of the input of call. -func inputTexts(t *testing.T, call fakeCall) []string { +func inputTexts(t *testing.T, call ModelFakeCall) []string { t.Helper() var body struct { @@ -402,22 +402,3 @@ func inputTexts(t *testing.T, call fakeCall) []string { return texts } - -func reasoningItem(id, encrypted string) map[string]any { - return map[string]any{ - "type": "reasoning", - "id": id, - "encrypted_content": encrypted, - "summary": []any{}, - } -} - -func functionCallItem(id, callID, name, arguments string) map[string]any { - return map[string]any{ - "type": "function_call", - "id": id, - "call_id": callID, - "name": name, - "arguments": arguments, - } -}