Files
Agent-Native/rpc/server_test.go
weichenandCursor 6fd1d441a9
ci / vet-and-test (pull_request) Successful in 45s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Keep tool pairs and fold reminders into the last result
Why: Old tool results were filling the window, compaction could split a tool group or commit a stale summary, and reminders arrived as extra user messages.
Evidence: Compaction retries a conflict and opens the circuit after three failures; clearing keeps the last five tool results; a stale file write is rejected; RPC reports started, queued, or handled.
Impact: Requests over the context window replace older tool results with a placeholder. Rewriting an existing file now requires a read in the same run. Subagent text over 32000 characters is capped.
Refs: feature/context-engineering
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 16:19:36 +00:00

76 lines
2.2 KiB
Go

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" || resp.Status != "handled" {
t.Fatalf("prompt %+v %v", resp, err)
}
resp, err = client.Call(context.Background(), Request{Type: "steer", Message: "later"})
if err != nil || !resp.OK || resp.Status != "started" {
t.Fatalf("steer %+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()
}