GthAgentRunner
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:309
Agent simplifies interaction with LLM and reduces it to calling a few methods GthAgentRunner#init and GthAgentRunner#processMessages.
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new GthAgentRunner(
statusUpdate,resolvers?,agentFactory?):GthAgentRunner
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:473
Parameters
Section titled “Parameters”statusUpdate
Section titled “statusUpdate”resolvers?
Section titled “resolvers?”agentFactory?
Section titled “agentFactory?”Produces the GthAgentInterface the runner drives. Defaults to the lean GthLangChainAgent (core). The seam stays parameterised so a caller can drive the runner with a different graph builder without core depending on it.
Returns
Section titled “Returns”GthAgentRunner
Methods
Section titled “Methods”cleanup()
Section titled “cleanup()”cleanup():
Promise<void>
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:3176
Returns
Section titled “Returns”Promise<void>
getAgent()
Section titled “getAgent()”getAgent():
GthAgentInterface|null
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:3111
Returns
Section titled “Returns”GthAgentInterface | null
getAllowlistCounts()
Section titled “getAllowlistCounts()”getAllowlistCounts():
AllowlistCounts
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:626
CFG-26 — the allow-list sizes for the /approvals display: how many command prefixes the
human has trusted this session, and how many are persisted in the project file.
READ-ONLY BY CONSTRUCTION: it reports the persisted count only when the store has ALREADY
been loaded (or persistence is on and it can be read), and never through a path that would
CREATE the store as a side effect of showing a display — a status command must not mutate
session state. always: undefined therefore means “not loaded / persistence off”, which the
caller renders as — rather than a misleading 0.
Returns
Section titled “Returns”getApprovalCaptures()
Section titled “getApprovalCaptures()”getApprovalCaptures():
ApprovalDecisionCapture[]
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:612
[[TUI-C27]] — every gated decision this session made, oldest first, for the /debug-dump
archive.
Threaded by each surface into writeDebugDump, exactly as agent.lastModelRequest is: the
writer redacts it with the same pass it applies to every other artifact, and a surface that
does not thread it simply omits the file.
Returns
Section titled “Returns”getGrants()
Section titled “getGrants()”getGrants():
ApprovalGrant[]
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:765
§3/§4.7.4 — the grants themselves, for an approvals view that shows what was granted, when, and under which effective annotations. The counterpart of getAllowlistCounts, which answers only how many.
The declared config lists are deliberately NOT here. They are something a human wrote and
reviewed, they carry no grantedAt and no scope, and getAllowlistCounts already counts them
alongside these; mixing them in would present a config line as something the session granted.
Read-only in both senses. It never loads the persisted store — same rule as getAllowlistCounts: a display must not create the store in order to show it, so a session that has not yet needed the file lists its session grants alone. And every grant is deep-copied on the way out, because the stores hand back their live records: the copy on the way in is what makes a snapshot private to its grant, and handing the same object to a renderer would put what the gate matches against one property assignment away from any consumer.
Returns
Section titled “Returns”getMcpAnnotationTrust()
Section titled “getMcpAnnotationTrust()”getMcpAnnotationTrust():
McpAnnotationTrustView
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:796
§4.7.1 — which of each server’s annotation hints this session believes, for display.
Every key either side names is listed: a configured mcpServers key with no policy of its own
(which resolves through defaults), and a policy key naming a server the config does not have
(which is what a typo looks like). Resolution is trustedAnnotationHints, the same
function the gate derives effective annotations through, so the display cannot claim a
relationship the gate does not act on.
Returns
Section titled “Returns”getRefusals()
Section titled “getRefusals()”getRefusals():
ApprovalRefusal[]
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:653
CFG-27/[[EXT-107]] — every refusal in force, and which of the three lists holds it: the
declared approvals.deny entries, the escalation menu’s session-scoped refusals, and the ones
saved to the project’s deny file.
The origins are kept apart rather than concatenated into one list of strings, because they have different lifetimes and different owners and only two of the three can be lifted from here. A merged list makes liftRefusal impossible to describe honestly.
This is the one list. liftRefusal resolves its argument against exactly this sequence, so the number a user reads and the number they type cannot name different entries.
Numbering is 1-based, and the order is config → saved → session: the entries a user cannot lift here come first and stay put, so the numbers of the ones they can are not reshuffled by a config edit between two renderings.
Returns
Section titled “Returns”getRunStats()
Section titled “getRunStats()”getRunStats():
GthRunStats
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:3146
GS2-16 — the analytics harvested from the just-finished turn (token usage + invoked tools), to thread into the opt-in history recorder. Reads live from the agent when one is present, otherwise the snapshot captured at cleanup (the single-shot path reads post-cleanup). Never throws.
Returns
Section titled “Returns”getSessionApprovals()
Section titled “getSessionApprovals()”getSessionApprovals():
ResolvedApprovals
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:600
CFG-27 — the session’s current approvals posture (rung + rater profile + declared lists).
Returns
Section titled “Returns”init()
Section titled “init()”init(
command,configIn,checkpointSaver?,options?):Promise<void>
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:919
Init is split into a separate method. This may create a number of connections, and we’d better have an instance by that moment, for the case things will go wrong, so we can wrap init into try-catch and then call #cleanup within finally.
Parameters
Section titled “Parameters”command
Section titled “command”GthCommand | undefined
configIn
Section titled “configIn”checkpointSaver?
Section titled “checkpointSaver?”BaseCheckpointSaver<number>
options?
Section titled “options?”Returns
Section titled “Returns”Promise<void>
liftRefusal()
Section titled “liftRefusal()”liftRefusal(
index):ApprovalRefusalLift
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:719
[[EXT-107]] — lift one refusal, by its number in getRefusals. The escape hatch, and
the reason persisting a refusal is safe to ship: a saved refusal the user cannot find or undo
is a trap, and the person who hits it first is whoever pressed [d] by reflex and needed the
command an hour later. Telling them to delete a file they have not been told exists is not an
answer.
A saved refusal is removed from the file AND from the in-memory store, because it is in both — dropping only the file would leave the call refused for the rest of the session by a rule the display no longer shows.
A configured entry is reported, never removed. approvals.deny is something the user
wrote; rewriting their config file out from under them is not a thing a session command may do,
and silently no-oping would be worse. They are told where it lives.
stillSaved is the deletion that did not reach disk ([[EXT-149]]). The file rewrite can
fail after the in-memory removal has succeeded — a checkout that is not writable, a settings
directory that has gone — and the entry then comes back in the next session. The store now
answers that question (PersistedApprovalGrants.remove) instead of reporting every
removal as landed, so the notice can stop promising it will not come back.
Parameters
Section titled “Parameters”number
Returns
Section titled “Returns”processMessages()
Section titled “processMessages()”processMessages(
messages):Promise<string>
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:1046
processMessages deals with both streaming and non-streaming approaches.
Parameters
Section titled “Parameters”messages
Section titled “messages”Message[]
Returns
Section titled “Returns”Promise<string>
processMessagesWithEvents()
Section titled “processMessagesWithEvents()”processMessagesWithEvents(
messages,signal?):AsyncGenerator<AgentStreamEvent>
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:2977
Event-stream counterpart to processMessages: drives the agent’s typed
AgentStreamEvent path using the runner’s own thread-bound runConfig, so a
renderer (the Ink TUI) can present the same run the readline path renders via
consoleUtils while sharing the checkpointer thread for cross-turn memory.
Cancellation is via the supplied signal (the TUI’s Esc → AbortController); the
underlying streamWithEvents ends cleanly on abort or interrupt(). The string
path’s empty-stream retry/invoke fallback is intentionally NOT duplicated here — the
TUI renders the live event stream directly; revisit if empty-stream retries are needed.
Tool-approval round-trip (EXT-11): after the stream ends, a gated run_shell_command
leaves the graph suspended on a humanInTheLoopMiddleware interrupt rather than
completing. This is the event-stream counterpart to the readline path’s
resolveToolInterrupts: it drains any pending interrupts through
decideToolApproval (bypass → allow-list → rater → bridged human prompt), resumes via
streamWithEventsResume({ decisions }), and loops until the graph completes with no
pending interrupts — so the executed command’s output renders into the TUI. Without
this the TUI silently finalized an empty turn (approval gate was dead code on the
event-stream path).
Parameters
Section titled “Parameters”messages
Section titled “messages”Message[]
signal?
Section titled “signal?”AbortSignal
Returns
Section titled “Returns”AsyncGenerator<AgentStreamEvent>
resetThread()
Section titled “resetThread()”resetThread():
void
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:3162
Rotate the thread the runner drives by minting a fresh runConfig (new thread_id),
so subsequent turns start from an empty checkpointer thread rather than retrieving the
prior conversation. Used by the TUI’s /clear, which clears the on-screen transcript;
without this the model would still see the full history persisted under the old thread.
Rotating the thread_id (rather than deleting from the checkpointer) keeps this independent
of any checkpointer-specific delete API, mirroring how init() mints the initial config.
Returns
Section titled “Returns”void
setApprovalOutcomeCallback()
Section titled “setApprovalOutcomeCallback()”setApprovalOutcomeCallback(
callback):void
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:507
[[EXT-150]] — register the handler that is told what a human’s answer actually landed as.
Pass null to clear.
Separate from setToolApprovalCallback for the reason setAttackHaltCallback is
separate: it is a different question asked at a different moment. The approval callback is
consulted before anything is written and returns the human’s REQUEST; the scope that survives
is decided here afterwards, because [[EXT-149]] degrades an always whose write did not reach
disk to the session answer it really is. A surface with no way to hear that can only confirm
the key that was pressed — and core’s own ERROR naming the unwritten file then contradicts it.
It reports; it never decides. Nothing downstream reads it, so a surface that ignores it, or never wires it, changes no behaviour of the gate.
Parameters
Section titled “Parameters”callback
Section titled “callback”ApprovalOutcomeCallback | null
Returns
Section titled “Returns”void
setAttackHaltCallback()
Section titled “setAttackHaltCallback()”setAttackHaltCallback(
callback):void
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:520
[[TUI-C68]] §6.1 — register the handler that shows the attack banner, the one way a human
gets past an attack verdict. Pass null to clear.
Separate from setToolApprovalCallback because it is a separate question with an inverted default: an absent approval callback means this session has nobody to ask, and an absent one here means end the run. Wiring it is what an interactive surface opts into; every other surface keeps the halt (see attackHaltCallback).
Parameters
Section titled “Parameters”callback
Section titled “callback”AttackHaltCallback | null
Returns
Section titled “Returns”void
setMcpAnnotationTrust()
Section titled “setMcpAnnotationTrust()”setMcpAnnotationTrust(
server,hints,believe):McpAnnotationTrustChange
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:834
§4.7.1 — believe, or stop believing, specific hints from one server, for the life of this
session. The runtime half of approvals.mcp.servers.<key>.trustAnnotations (§9), so a user can
do from the TUI what they can do in config.
Per hint, never per server. hints names the hints this call moves and leaves every other
hint of that server’s exactly as it was, because believing a server’s readOnlyHint while
disbelieving its openWorldHint is a coherent position and the common one. A “trust this
server” flag is the design §4.7.1 rejects.
The previous set is what was IN FORCE, resolved through defaults. A server not named
under servers inherits defaults, and naming it makes it state its relationship in full (§9)
— so seeding from the empty set would mean that believing one more hint silently withdrew every
hint defaults had granted, which is a weakening the user did not ask for and would invalidate
their grants.
Session-scoped only. Nothing is written to config: the declared block is read-only input (§9.1), exactly as the rung is.
A trusted external annotation still never grants more than the same annotation grants one of
our own built-ins — that holds in core/approvals/annotations.ts by construction, and this
changes only which hints are read.
Parameters
Section titled “Parameters”server
Section titled “server”string
readonly ("readOnlyHint" | "destructiveHint" | "idempotentHint" | "openWorldHint")[]
believe
Section titled “believe”boolean
Returns
Section titled “Returns”setNegotiationDisplay()
Section titled “setNegotiationDisplay()”setNegotiationDisplay(
display):void
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:534
[[TUI-C69]] §5.4/§5.5 — declare that this surface is showing the negotiation as it happens.
Pass null to clear.
§5.4’s requirement is not decoration: “the spec’s own justification for letting the agent argue with the rater at all is that a human can watch it, and an argument conducted in the dark is a different thing from one that can be interrupted.” Wiring this is a surface saying it has somewhere to draw that, which is also what makes §5.5’s hold meaningful — see negotiationDisplay for why one seam carries both.
Parameters
Section titled “Parameters”display
Section titled “display”NegotiationDisplay | null
Returns
Section titled “Returns”void
setSessionApprovalRung()
Section titled “setSessionApprovalRung()”setSessionApprovalRung(
rung):"manual"|"write"|"assisted"|"auto"|"bypass"
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:594
CFG-27 — switch the session-scoped rung (/approvals <rung>). Idempotent; returns the NEW
rung so the caller can render a notice. Session-scoped only — nothing is written to config,
and the declared allow/deny lists are unaffected (they are config input, not session state).
Parameters
Section titled “Parameters”"manual" | "write" | "assisted" | "auto" | "bypass"
Returns
Section titled “Returns”"manual" | "write" | "assisted" | "auto" | "bypass"
setToolApprovalCallback()
Section titled “setToolApprovalCallback()”setToolApprovalCallback(
callback):void
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/GthAgentRunner.ts:489
Register the tool-approval handler the runner calls when a run suspends on a tool-approval
interrupt (the interactive readline session wires a y/n prompt here). Pass null to clear.
Without a handler the runner rejects pending tool calls (see toolApprovalCallback).
Parameters
Section titled “Parameters”callback
Section titled “callback”ToolApprovalCallback | null
Returns
Section titled “Returns”void