package rpc import ( "context" "io" "path/filepath" "testing" "agent-native/runtime" "agent-native/runtime/llm" "agent-native/runtime/session" ) func TestRPCSessionCommandsAndClient(t *testing.T) { dir := t.TempDir() store, err := session.Open(filepath.Join(dir, "s.jsonl")) if err != nil { t.Fatal(err) } if err := store.Append(llm.Message{Role: llm.RoleAssistant, Content: "ready"}); err != nil { t.Fatal(err) } agent := runtime.NewAgentSession(runtime.Config{ Model: "fake", Stream: func(ctx context.Context, model string, messages []llm.Message, td []llm.ToolDecl, opts llm.StreamOptions) <-chan llm.Event { ch := make(chan llm.Event, 1) ch <- llm.Event{Kind: llm.KindMessageEnd, Message: llm.Message{Role: llm.RoleAssistant, Content: "echo", StopReason: llm.StopEnd}} close(ch) return ch }, }) srv := &Server{Agent: agent, Store: store} clientIn, serverOut := io.Pipe() serverIn, clientOut := io.Pipe() go func() { defer serverOut.Close() buf := make([]byte, 4096) for { n, err := serverIn.Read(buf) if n > 0 { resp, herr := srv.Handle(context.Background(), buf[:n]) if herr == nil { _, _ = serverOut.Write(resp) } } if err != nil { return } } }() client := NewClient(clientOut, clientIn) resp, err := client.Call(context.Background(), Request{ID: "1", Type: "get_last_assistant_text"}) if err != nil || !resp.OK || resp.Text != "ready" { t.Fatalf("%+v %v", resp, err) } fork := filepath.Join(dir, "fork.jsonl") resp, err = client.Call(context.Background(), Request{Type: "fork", Path: fork}) if err != nil || !resp.OK { t.Fatalf("fork %+v %v", resp, err) } resp, err = client.Call(context.Background(), Request{Type: "prompt", Message: "hi"}) if err != nil || !resp.OK || resp.Text != "echo" { t.Fatalf("prompt %+v %v", resp, err) } htmlPath := filepath.Join(dir, "out.html") resp, err = client.Call(context.Background(), Request{Type: "export_html", Path: htmlPath}) if err != nil || !resp.OK { t.Fatalf("export %+v %v", resp, err) } _ = clientOut.Close() }