MCPcopy Index your code
hub / github.com/docker/docker-agent / TestRunAgentPersistsSubSessionToStore

Function TestRunAgentPersistsSubSessionToStore

pkg/runtime/runtime_test.go:4073–4128  ·  view source on GitHub ↗

TestRunAgentPersistsSubSessionToStore is the regression test for the background-agent spend leak: run_background_agent sub-sessions were added to the parent's in-memory object but never written to the session store, so their tokens and cost were invisible to anything reading the store ($0 recorded f

(t *testing.T)

Source from the content-addressed store, hash-verified

4071// sub-session directly from runCollecting. This asserts the sub-session row
4072// reaches the store and carries the worker's recorded usage.
4073func TestRunAgentPersistsSubSessionToStore(t *testing.T) {
4074 t.Parallel()
4075
4076 // Worker produces real output and usage so the sub-session has a transcript.
4077 workerStream := newStreamBuilder().AddContent("worker done").AddStopWithUsage(100, 50).Build()
4078 parentProv := &mockProvider{id: "test/mock-model", stream: &mockStream{}}
4079 workerProv := &mockProvider{id: "test/mock-model", stream: workerStream}
4080
4081 worker := agent.New("worker", "Worker agent", agent.WithModel(workerProv))
4082 root := agent.New("root", "Root agent", agent.WithModel(parentProv))
4083 agent.WithSubAgents(worker)(root)
4084
4085 tm := team.New(team.WithAgents(root, worker))
4086
4087 store := session.NewInMemorySessionStore()
4088 rt, err := NewLocalRuntime(t.Context(), tm,
4089 WithSessionCompaction(false),
4090 WithModelStore(mockModelStore{}),
4091 WithSessionStore(store),
4092 )
4093 require.NoError(t, err)
4094
4095 // The parent must exist in the store before a sub-session can be linked
4096 // to it. Use UpdateSession (what OnRunStart calls) so the store holds its
4097 // own copy of the parent — exactly as in the real flow — rather than
4098 // aliasing the runtime's in-memory object.
4099 sess := session.New(session.WithUserMessage("Test"), session.WithToolsApproved(true))
4100 require.NoError(t, store.UpdateSession(t.Context(), sess))
4101
4102 result := rt.RunAgent(t.Context(), agenttool.RunParams{
4103 AgentName: "worker",
4104 Task: "do something",
4105 ParentSession: sess,
4106 })
4107 require.Empty(t, result.ErrMsg, "RunAgent should succeed")
4108
4109 // The store's copy of the parent must now contain the sub-session — not
4110 // just the runtime's in-memory object. Before the fix this was empty,
4111 // so the background agent's work was recorded nowhere durable.
4112 stored, err := store.GetSession(t.Context(), sess.ID)
4113 require.NoError(t, err)
4114
4115 var storedSubSessions []*session.Session
4116 for _, item := range stored.Messages {
4117 if item.SubSession != nil {
4118 storedSubSessions = append(storedSubSessions, item.SubSession)
4119 }
4120 }
4121 require.Len(t, storedSubSessions, 1,
4122 "the background sub-session must be persisted to the store, not just held in memory")
4123
4124 // The persisted sub-session must carry the worker's token usage so spend
4125 // accounting that reads the store sees real numbers, not nothing.
4126 assert.Positive(t, storedSubSessions[0].InputTokens+storedSubSessions[0].OutputTokens,
4127 "persisted sub-session must carry the worker's recorded token usage")
4128}
4129
4130// TestRunAgentPersistsSubSessionOnError covers the background-agent path

Callers

nothing calls this directly

Calls 15

UpdateSessionMethod · 0.95
RunAgentMethod · 0.95
GetSessionMethod · 0.95
NewFunction · 0.92
NewFunction · 0.92
WithAgentsFunction · 0.92
NewInMemorySessionStoreFunction · 0.92
NewFunction · 0.92
WithUserMessageFunction · 0.92
WithToolsApprovedFunction · 0.92
newStreamBuilderFunction · 0.85
NewLocalRuntimeFunction · 0.85

Tested by

no test coverage detected