Skip to content

runConversation

runConversation(source, _preamble, userMessages, config, resolvers?, command?, agentFactory?): Promise<ConversationTurnResult[]>

Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/runtime/conversation.ts:78

Run a scripted MULTI-TURN conversation and return one ConversationTurnResult per turn.

This is the conversational counterpart to ../runtime/singleShot.js runSingleShot (which is stateless — a fresh agent per call). It builds the agent + resolves tools ONCE, then runs each turn against the ACCUMULATED message history so cross-turn “memory” / identity behaviour is real, and cleans up ONCE at the end (reusing runSingleShot’s cleanup discipline — the resolvers are the caller’s to tear down, exactly as with runSingleShot).

History mechanism = stateless replay of the growing message array. Messages accumulate as [user1, ai1, user2, ai2, …]: per turn a HumanMessage(user) is appended, the agent runs on the WHOLE array, and its answer is appended as an AIMessage so the next turn sees it. The system prompt is NOT seeded here — the agent composes it via createAgent({ systemPrompt }) (BATCH-13; see runSingleShot), so the replayed array carries only human/assistant turns. Before each turn the runner’s thread is rotated (GthAgentRunner.resetThread) so the checkpointer starts empty and the replayed array is the sole history (no add_messages double-append). This mirrors the AG-UI server’s “client is the source of truth for history — it sends the full message list every turn” model and reuses the existing processMessages + resetThread machinery with no new agent surface. Known limitation (unverified pending a live pass): replay carries prior answers (as AIMessage text) but NOT prior tool-call / tool-result messages — a checkpointer- thread approach (send only the new message, let add_messages accumulate) would preserve those.

Per-turn tool capture (GS2-16): processMessages resets the analytics tally at its top, so getRunStats() read right after each turn returns THAT turn’s tool/token delta (not cumulative).

A turn that fails is recorded (ok:false, error) and the conversation STOPS (later turns depend on the broken context), so the returned array may be shorter than userMessages — the caller (gth eval’s runner) fails the un-run turns.

string

The source label (used for output/session-file naming), e.g. EVAL-<cellId>.

string

Deprecated/ignored (BATCH-13): the agent composes the system prompt itself (via createAgent({ systemPrompt })); seeding it here too produced a second system message that @langchain/anthropic rejects. Retained positionally so existing callers need no change.

string[]

The ordered user turns to send (one conversation).

GthConfig

The resolved config.

AgentResolvers

Optional agent resolvers (tools/middleware); the caller owns their cleanup.

GthCommand = 'ask'

The originating command (defaults to ask); selects the agent mode prompt.

GthAgentFactory

Optional backend factory (B5); omitted = the runner’s lean default.

Promise<ConversationTurnResult[]>

One ConversationTurnResult per turn attempted, in turn order.