)
func TestClientsSeeTheTurnAsItHappens(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{functionCallItem("fc_1", "call_1", "shell", `{"command":"echo hi"}`)}, 100, 0, 5))
+ modelWriteEvents(w, modelCompletedEvent([]any{modelFunctionCallItem("fc_1", "call_1", "shell", `{"command":"echo hi"}`)}, 100, 0, 5))
return
}
- writeEvents(w, completedEvent([]any{messageItem("It said hi.")}, 100, 0, 5))
+ modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("It said hi.")}, 100, 0, 5))
}
socket := startTestDaemon(t, server)
}
func TestStopInterruptsTheTurn(t *testing.T) {
- server := newFakeResponses(t)
+ server := newModelFake(t)
arrived := make(chan struct{})
release := make(chan struct{})
t.Cleanup(func() {
close(release)
})
- server.reply = func(w http.ResponseWriter, call fakeCall) {
+ server.reply = func(w http.ResponseWriter, call ModelFakeCall) {
close(arrived)
<-release
}
require.ErrorContains(t, err, "set ONECHAT_DIR to a shorter path")
}
+func TestDaemonWritesNoFileForALongSocketPath(t *testing.T) {
+ dir := filepath.Join(t.TempDir(), strings.Repeat("d", 100))
+ t.Setenv("ONECHAT_DIR", dir)
+
+ err := daemon(t.Context(), io.Discard)
+ require.ErrorContains(t, err, "set ONECHAT_DIR to a shorter path")
+
+ entries, err := os.ReadDir(dir)
+ require.NoError(t, err)
+ require.Empty(t, entries)
+}
+
func TestOneProcessHoldsTheTokens(t *testing.T) {
dir := t.TempDir()
lock, err := lockTokens(dir)
text: "Done.",
},
{
- name: "user message not shown",
- event: Event{Kind: "user", Text: "typed"},
+ name: "own user message not shown",
+ event: Event{Kind: "user", Text: "typed", Source: terminalSource},
text: "",
},
+ {
+ name: "user message of another source marked",
+ event: Event{Kind: "user", Text: "from the phone", Source: "telegram"},
+ text: "[telegram] from the phone",
+ },
{
name: "long result cut",
event: Event{Kind: "echo", Text: strings.Repeat("line\n", 12)},
// startTestDaemon serves a new agent on a socket in a temporary directory and
// returns the socket path. The commands of the agent run in a temporary
// directory.
-func startTestDaemon(t *testing.T, server *fakeResponses) string {
+func startTestDaemon(t *testing.T, server *ModelFake) string {
+ t.Helper()
+
+ return startTestDaemonWithBot(t, server, nil)
+}
+
+// startTestDaemonWithBot is startTestDaemon with bot, which can be nil.
+func startTestDaemonWithBot(t *testing.T, server *ModelFake, bot *TelegramBot) string {
t.Helper()
dir := t.TempDir()
listener, err := listenSocket(socket)
require.NoError(t, err)
- client := newClient(server.URL, apiKey(testKey), agent.CacheKey(), filepath.Join(agent.dir, "usage.jsonl"))
+ client := newModelClient(server.URL, ModelAPIKey(modelTestKey), agent.CacheKey(), filepath.Join(agent.dir, "usage.jsonl"))
ctx, cancel := context.WithCancel(t.Context())
done := make(chan error)
go func() {
- done <- serveAgent(ctx, listener, func(notify func(Event)) (*loop, error) {
+ done <- serveAgent(ctx, listener, bot, func(notify func(Event)) (*loop, error) {
return newLoop(agent, memory, client, clock.Now, notify)
})
}()