@gaunt-sloth/core 2.0.0-alpha.9 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gsloth.review.md +2 -0
- package/README.md +71 -20
- package/dist/config/colour.d.ts +38 -0
- package/dist/config/colour.js +36 -0
- package/dist/config/colour.js.map +1 -0
- package/dist/config/configDiscovery.d.ts +79 -0
- package/dist/config/configDiscovery.js +80 -0
- package/dist/config/configDiscovery.js.map +1 -0
- package/dist/config/defaults.d.ts +20 -20
- package/dist/config/defaults.js +10 -8
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/filesystem-tools.d.ts +41 -0
- package/dist/config/filesystem-tools.js +56 -0
- package/dist/config/filesystem-tools.js.map +1 -0
- package/dist/config/loader.d.ts +171 -19
- package/dist/config/loader.js +1054 -144
- package/dist/config/loader.js.map +1 -1
- package/dist/config/mouse.d.ts +50 -0
- package/dist/config/mouse.js +44 -0
- package/dist/config/mouse.js.map +1 -0
- package/dist/config/profiles.d.ts +68 -0
- package/dist/config/profiles.js +93 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/config/providerKeys.d.ts +69 -0
- package/dist/config/providerKeys.js +69 -0
- package/dist/config/providerKeys.js.map +1 -0
- package/dist/config/schema.d.ts +2671 -138
- package/dist/config/schema.js +1361 -85
- package/dist/config/schema.js.map +1 -1
- package/dist/config/shell-policy.d.ts +899 -111
- package/dist/config/shell-policy.js +800 -70
- package/dist/config/shell-policy.js.map +1 -1
- package/dist/config/tool-descriptions.d.ts +211 -0
- package/dist/config/tool-descriptions.js +272 -0
- package/dist/config/tool-descriptions.js.map +1 -0
- package/dist/config/types.d.ts +352 -41
- package/dist/config/types.js +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/config.d.ts +35 -1
- package/dist/config.js +16 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +28 -1
- package/dist/constants.js +28 -1
- package/dist/constants.js.map +1 -1
- package/dist/core/GthAbstractAgent.d.ts +166 -11
- package/dist/core/GthAbstractAgent.js +484 -45
- package/dist/core/GthAbstractAgent.js.map +1 -1
- package/dist/core/GthAgentRunner.d.ts +543 -57
- package/dist/core/GthAgentRunner.js +1494 -140
- package/dist/core/GthAgentRunner.js.map +1 -1
- package/dist/core/GthLangChainAgent.d.ts +117 -2
- package/dist/core/GthLangChainAgent.js +602 -29
- package/dist/core/GthLangChainAgent.js.map +1 -1
- package/dist/core/approvals/annotations.d.ts +122 -0
- package/dist/core/approvals/annotations.js +137 -0
- package/dist/core/approvals/annotations.js.map +1 -0
- package/dist/core/approvals/grants.d.ts +216 -0
- package/dist/core/approvals/grants.js +469 -0
- package/dist/core/approvals/grants.js.map +1 -0
- package/dist/core/approvals/matcher.d.ts +202 -0
- package/dist/core/approvals/matcher.js +267 -0
- package/dist/core/approvals/matcher.js.map +1 -0
- package/dist/core/approvals/mcpSubjects.d.ts +40 -0
- package/dist/core/approvals/mcpSubjects.js +99 -0
- package/dist/core/approvals/mcpSubjects.js.map +1 -0
- package/dist/core/approvals/promptHeader.d.ts +28 -0
- package/dist/core/approvals/promptHeader.js +62 -0
- package/dist/core/approvals/promptHeader.js.map +1 -0
- package/dist/core/approvals/toolAnnotationSources.d.ts +105 -0
- package/dist/core/approvals/toolAnnotationSources.js +277 -0
- package/dist/core/approvals/toolAnnotationSources.js.map +1 -0
- package/dist/core/approvals/toolHost.d.ts +46 -0
- package/dist/core/approvals/toolHost.js +108 -0
- package/dist/core/approvals/toolHost.js.map +1 -0
- package/dist/core/debugCapture.d.ts +74 -0
- package/dist/core/debugCapture.js +100 -0
- package/dist/core/debugCapture.js.map +1 -0
- package/dist/core/gthLeanAgentFactory.d.ts +4 -4
- package/dist/core/gthLeanAgentFactory.js +4 -4
- package/dist/core/launchBanner.d.ts +127 -0
- package/dist/core/launchBanner.js +414 -0
- package/dist/core/launchBanner.js.map +1 -0
- package/dist/core/modelLabel.d.ts +19 -0
- package/dist/core/modelLabel.js +26 -0
- package/dist/core/modelLabel.js.map +1 -0
- package/dist/core/plainToolIndication.d.ts +15 -0
- package/dist/core/plainToolIndication.js +174 -0
- package/dist/core/plainToolIndication.js.map +1 -0
- package/dist/core/reasoningBlocks.d.ts +65 -0
- package/dist/core/reasoningBlocks.js +103 -0
- package/dist/core/reasoningBlocks.js.map +1 -0
- package/dist/core/refusal.d.ts +53 -0
- package/dist/core/refusal.js +133 -0
- package/dist/core/refusal.js.map +1 -0
- package/dist/core/runHeader.d.ts +38 -0
- package/dist/core/runHeader.js +42 -0
- package/dist/core/runHeader.js.map +1 -0
- package/dist/core/runStats.d.ts +14 -3
- package/dist/core/runStats.js +48 -3
- package/dist/core/runStats.js.map +1 -1
- package/dist/core/shell/ShellCommandFailedError.d.ts +3 -4
- package/dist/core/shell/ShellCommandFailedError.js +3 -4
- package/dist/core/shell/ShellCommandFailedError.js.map +1 -1
- package/dist/core/shell/abstention.d.ts +88 -0
- package/dist/core/shell/abstention.js +184 -0
- package/dist/core/shell/abstention.js.map +1 -0
- package/dist/core/shell/approvalCapture.d.ts +271 -0
- package/dist/core/shell/approvalCapture.js +108 -0
- package/dist/core/shell/approvalCapture.js.map +1 -0
- package/dist/core/shell/approvalStop.d.ts +123 -0
- package/dist/core/shell/approvalStop.js +269 -0
- package/dist/core/shell/approvalStop.js.map +1 -0
- package/dist/core/shell/arity.d.ts +6 -0
- package/dist/core/shell/arity.js +20 -6
- package/dist/core/shell/arity.js.map +1 -1
- package/dist/core/shell/denylist.d.ts +11 -0
- package/dist/core/shell/denylist.js +37 -0
- package/dist/core/shell/denylist.js.map +1 -0
- package/dist/core/shell/escalationSeverity.d.ts +141 -0
- package/dist/core/shell/escalationSeverity.js +89 -0
- package/dist/core/shell/escalationSeverity.js.map +1 -0
- package/dist/core/shell/framing.d.ts +190 -0
- package/dist/core/shell/framing.js +633 -0
- package/dist/core/shell/framing.js.map +1 -0
- package/dist/core/shell/hardline.d.ts +103 -0
- package/dist/core/shell/hardline.js +780 -0
- package/dist/core/shell/hardline.js.map +1 -0
- package/dist/core/shell/negotiation.d.ts +328 -0
- package/dist/core/shell/negotiation.js +488 -0
- package/dist/core/shell/negotiation.js.map +1 -0
- package/dist/core/shell/normalize.d.ts +44 -4
- package/dist/core/shell/normalize.js +61 -7
- package/dist/core/shell/normalize.js.map +1 -1
- package/dist/core/shell/openWorld.d.ts +263 -0
- package/dist/core/shell/openWorld.js +1188 -0
- package/dist/core/shell/openWorld.js.map +1 -0
- package/dist/core/shell/rater.d.ts +873 -0
- package/dist/core/shell/rater.js +1454 -0
- package/dist/core/shell/rater.js.map +1 -0
- package/dist/core/shell/raterModel.d.ts +41 -0
- package/dist/core/shell/raterModel.js +51 -0
- package/dist/core/shell/raterModel.js.map +1 -0
- package/dist/core/shell/raterVocabulary.d.ts +121 -0
- package/dist/core/shell/raterVocabulary.js +116 -0
- package/dist/core/shell/raterVocabulary.js.map +1 -0
- package/dist/core/shell/rejection.d.ts +69 -0
- package/dist/core/shell/rejection.js +38 -0
- package/dist/core/shell/rejection.js.map +1 -0
- package/dist/core/toolCallRepair/grammar.d.ts +41 -0
- package/dist/core/toolCallRepair/grammar.js +116 -0
- package/dist/core/toolCallRepair/grammar.js.map +1 -0
- package/dist/core/toolCallRepair/index.d.ts +2 -0
- package/dist/core/toolCallRepair/index.js +7 -0
- package/dist/core/toolCallRepair/index.js.map +1 -0
- package/dist/core/toolCallRepair/payload.d.ts +36 -0
- package/dist/core/toolCallRepair/payload.js +341 -0
- package/dist/core/toolCallRepair/payload.js.map +1 -0
- package/dist/core/toolCallRepair/promote.d.ts +45 -0
- package/dist/core/toolCallRepair/promote.js +90 -0
- package/dist/core/toolCallRepair/promote.js.map +1 -0
- package/dist/core/toolDisplay.d.ts +123 -0
- package/dist/core/toolDisplay.js +451 -0
- package/dist/core/toolDisplay.js.map +1 -0
- package/dist/core/toolOutputChannel.d.ts +95 -0
- package/dist/core/toolOutputChannel.js +165 -0
- package/dist/core/toolOutputChannel.js.map +1 -0
- package/dist/core/types.d.ts +349 -16
- package/dist/core/types.js.map +1 -1
- package/dist/history/historyFormat.d.ts +12 -3
- package/dist/history/historyFormat.js +50 -8
- package/dist/history/historyFormat.js.map +1 -1
- package/dist/history/historyStore.d.ts +77 -0
- package/dist/history/historyStore.js +173 -6
- package/dist/history/historyStore.js.map +1 -1
- package/dist/history/recordSession.d.ts +10 -1
- package/dist/history/recordSession.js +27 -0
- package/dist/history/recordSession.js.map +1 -1
- package/dist/providers/anthropic.js +12 -0
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/configurationPassthrough.d.ts +107 -0
- package/dist/providers/configurationPassthrough.js +148 -0
- package/dist/providers/configurationPassthrough.js.map +1 -0
- package/dist/providers/geminiSchemaSanitizer.d.ts +55 -0
- package/dist/providers/geminiSchemaSanitizer.js +347 -0
- package/dist/providers/geminiSchemaSanitizer.js.map +1 -0
- package/dist/providers/geminiThinking.d.ts +60 -0
- package/dist/providers/geminiThinking.js +92 -0
- package/dist/providers/geminiThinking.js.map +1 -0
- package/dist/providers/google-genai.js +18 -1
- package/dist/providers/google-genai.js.map +1 -1
- package/dist/providers/groq.js +12 -0
- package/dist/providers/groq.js.map +1 -1
- package/dist/providers/huggingface.d.ts +25 -0
- package/dist/providers/huggingface.js +69 -0
- package/dist/providers/huggingface.js.map +1 -0
- package/dist/providers/modelCatalog.d.ts +109 -0
- package/dist/providers/modelCatalog.js +245 -0
- package/dist/providers/modelCatalog.js.map +1 -0
- package/dist/providers/modelDiscovery.d.ts +99 -5
- package/dist/providers/modelDiscovery.js +191 -35
- package/dist/providers/modelDiscovery.js.map +1 -1
- package/dist/providers/ollama.d.ts +18 -4
- package/dist/providers/ollama.js +67 -37
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.js +34 -0
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +26 -4
- package/dist/providers/openrouter.js +83 -26
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/vertexai.js +19 -1
- package/dist/providers/vertexai.js.map +1 -1
- package/dist/providers/xai.js +20 -0
- package/dist/providers/xai.js.map +1 -1
- package/dist/runtime/askStructured.d.ts +105 -0
- package/dist/runtime/askStructured.js +120 -0
- package/dist/runtime/askStructured.js.map +1 -0
- package/dist/runtime/conversation.d.ts +64 -0
- package/dist/runtime/conversation.js +171 -0
- package/dist/runtime/conversation.js.map +1 -0
- package/dist/runtime/singleShot.d.ts +37 -6
- package/dist/runtime/singleShot.js +113 -67
- package/dist/runtime/singleShot.js.map +1 -1
- package/dist/runtime/structuredOutput.d.ts +104 -0
- package/dist/runtime/structuredOutput.js +393 -0
- package/dist/runtime/structuredOutput.js.map +1 -0
- package/dist/utils/ProgressIndicator.d.ts +21 -0
- package/dist/utils/ProgressIndicator.js +30 -3
- package/dist/utils/ProgressIndicator.js.map +1 -1
- package/dist/utils/aiignoreUtils.js.map +1 -1
- package/dist/utils/binaryOutputUtils.js.map +1 -1
- package/dist/utils/consoleUtils.d.ts +95 -0
- package/dist/utils/consoleUtils.js +112 -2
- package/dist/utils/consoleUtils.js.map +1 -1
- package/dist/utils/crashHandler.d.ts +87 -0
- package/dist/utils/crashHandler.js +128 -0
- package/dist/utils/crashHandler.js.map +1 -0
- package/dist/utils/debugDump.d.ts +134 -0
- package/dist/utils/debugDump.js +381 -0
- package/dist/utils/debugDump.js.map +1 -0
- package/dist/utils/debugUtils.d.ts +13 -4
- package/dist/utils/debugUtils.js +36 -13
- package/dist/utils/debugUtils.js.map +1 -1
- package/dist/utils/displayWidth.d.ts +53 -0
- package/dist/utils/displayWidth.js +195 -0
- package/dist/utils/displayWidth.js.map +1 -0
- package/dist/utils/fileUtils.js.map +1 -1
- package/dist/utils/globalConfigUtils.d.ts +14 -2
- package/dist/utils/globalConfigUtils.js +22 -4
- package/dist/utils/globalConfigUtils.js.map +1 -1
- package/dist/utils/llmUtils.d.ts +39 -8
- package/dist/utils/llmUtils.js +76 -8
- package/dist/utils/llmUtils.js.map +1 -1
- package/dist/utils/redactSecrets.d.ts +63 -0
- package/dist/utils/redactSecrets.js +286 -0
- package/dist/utils/redactSecrets.js.map +1 -0
- package/dist/utils/systemPromptNotes.d.ts +222 -0
- package/dist/utils/systemPromptNotes.js +338 -0
- package/dist/utils/systemPromptNotes.js.map +1 -0
- package/dist/utils/systemUtils.d.ts +18 -1
- package/dist/utils/systemUtils.js +38 -3
- package/dist/utils/systemUtils.js.map +1 -1
- package/dist/utils/toolMatching.d.ts +30 -0
- package/dist/utils/toolMatching.js +44 -0
- package/dist/utils/toolMatching.js.map +1 -0
- package/dist/utils/untrustedText.d.ts +86 -0
- package/dist/utils/untrustedText.js +101 -0
- package/dist/utils/untrustedText.js.map +1 -0
- package/package.json +21 -7
- package/schema/gsloth-config.schema.json +1921 -326
- package/dist/core/shell/allowlist.d.ts +0 -75
- package/dist/core/shell/allowlist.js +0 -187
- package/dist/core/shell/allowlist.js.map +0 -1
- package/dist/core/shell/judge.d.ts +0 -161
- package/dist/core/shell/judge.js +0 -261
- package/dist/core/shell/judge.js.map +0 -1
package/dist/core/types.d.ts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import type { GthConfig } from '#src/config.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { DeclaredToolAnnotations } from '#src/core/approvals/annotations.js';
|
|
3
|
+
import type { ApprovalSubject } from '#src/core/approvals/matcher.js';
|
|
4
|
+
import type { RaterNegotiationRound, ShellSafetyVerdict } from '#src/core/shell/rater.js';
|
|
3
5
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
4
6
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
5
7
|
import type { StructuredToolInterface } from '@langchain/core/tools';
|
|
6
8
|
import type { IterableReadableStream } from '@langchain/core/utils/stream';
|
|
7
9
|
import type { BaseCheckpointSaver } from '@langchain/langgraph';
|
|
10
|
+
/**
|
|
11
|
+
* The approval and shell types this module's own surface is written in, re-exported so a consumer
|
|
12
|
+
* of the root barrel can NAME each of them. Every one is the declared type of something already
|
|
13
|
+
* reachable here — {@link PendingToolInterrupt}'s `subject`, `safetyVerdict` and
|
|
14
|
+
* `negotiationRounds`, and {@link GthAgentInterface#getDeclaredMcpToolAnnotations} — so without
|
|
15
|
+
* them an embedder receives values it cannot type, which is precisely what writing a typed
|
|
16
|
+
* {@link ToolApprovalCallback} asks of it.
|
|
17
|
+
*
|
|
18
|
+
* They stay declared where they are: the matcher owns the subject it matches on and the rater owns
|
|
19
|
+
* the verdict it returns, so a type moved here to become exportable would sit apart from the code
|
|
20
|
+
* that decides it. The re-export is type-only and erases at emit, so the barrel gains no runtime
|
|
21
|
+
* edge.
|
|
22
|
+
*
|
|
23
|
+
* The two modules' **runtime** surface is deliberately not re-exported, including the closed
|
|
24
|
+
* vocabularies `RATER_OUTCOMES` and `ShellSafetyVerdictSchema` that {@link RaterOutcome} and
|
|
25
|
+
* {@link ShellSafetyVerdict} are derived from: a type alias resolves its referent inside the
|
|
26
|
+
* declaration file it is emitted into, so naming either type needs neither value in scope. Values
|
|
27
|
+
* stay reachable at their own deep paths (`@gaunt-sloth/core/core/shell/rater.js`,
|
|
28
|
+
* `@gaunt-sloth/core/core/approvals/matcher.js`) at the usual deep-path risk.
|
|
29
|
+
*
|
|
30
|
+
* `packages/core/spec/coreBarrelTypeSurface.spec.ts` pins this: it type-checks a probe against the
|
|
31
|
+
* built `dist/` declarations, so dropping a name here fails as a named missing export rather than
|
|
32
|
+
* as a later consumer's problem.
|
|
33
|
+
*/
|
|
34
|
+
export type { DeclaredToolAnnotations } from '#src/core/approvals/annotations.js';
|
|
35
|
+
export type { ApprovalSubject, McpToolApprovalSubject, ShellApprovalSubject, ToolApprovalSubject, } from '#src/core/approvals/matcher.js';
|
|
36
|
+
export type { RaterNegotiationRound, RaterOutcome, ShellSafetyVerdict, } from '#src/core/shell/rater.js';
|
|
8
37
|
export type Message = BaseMessage;
|
|
9
38
|
export type StatusUpdateCallback = (level: StatusLevel, message: string) => void;
|
|
10
39
|
/**
|
|
@@ -38,6 +67,28 @@ export interface GthRunStats {
|
|
|
38
67
|
tokensOutput?: number;
|
|
39
68
|
/** Names of tools invoked during the run (deduplicated); empty when no tools were used. */
|
|
40
69
|
tools: string[];
|
|
70
|
+
/**
|
|
71
|
+
* BATCH-21 — one record per executed tool result (`ToolMessage`) observed during the run, in
|
|
72
|
+
* arrival order and NOT deduplicated (a tool called twice yields two records), so `gth eval`'s
|
|
73
|
+
* tool-RESULT assertions (`must_error` / `tool_result_json_path`) can grade what a tool
|
|
74
|
+
* *returned*, not just that it was called. Optional (additive): producers that predate the field
|
|
75
|
+
* simply omit it; {@link runStats.js finalizeRunStats} always sets it.
|
|
76
|
+
*/
|
|
77
|
+
toolResults?: GthToolResult[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* BATCH-21 — one executed tool call's result, harvested from its `ToolMessage` by the GS2-16
|
|
81
|
+
* run-stats accumulator (`core/runStats.ts`). Fail-soft like everything else there: `content` is
|
|
82
|
+
* omitted when no text payload could be derived, and is size-capped
|
|
83
|
+
* ({@link runStats.js TOOL_RESULT_CONTENT_CAP}) so a giant payload can't bloat run stats.
|
|
84
|
+
*/
|
|
85
|
+
export interface GthToolResult {
|
|
86
|
+
/** The tool that produced the result (`ToolMessage.name`). */
|
|
87
|
+
name: string;
|
|
88
|
+
/** `true` iff the result carried LangChain's real error signal (`ToolMessage.status === 'error'`). */
|
|
89
|
+
isError: boolean;
|
|
90
|
+
/** The result payload as text (a non-string payload is JSON-stringified), capped in length. */
|
|
91
|
+
content?: string;
|
|
41
92
|
}
|
|
42
93
|
/**
|
|
43
94
|
* Typed events emitted by the agent's {@link GthAgentInterface#streamWithEvents} path.
|
|
@@ -66,6 +117,34 @@ export type AgentStreamEvent = {
|
|
|
66
117
|
} | {
|
|
67
118
|
type: 'tool_end';
|
|
68
119
|
id: string;
|
|
120
|
+
} | {
|
|
121
|
+
/**
|
|
122
|
+
* TUI-C17 — one live output chunk from an EXECUTING tool (a custom/dev toolkit child
|
|
123
|
+
* process's stdout/stderr, or its "Executing …" announcement), surfaced through the managed
|
|
124
|
+
* event stream instead of raw `process.stdout` so a renderer (the Ink TUI) can fold it into
|
|
125
|
+
* its view-model. Emitted by the tool-output channel merge
|
|
126
|
+
* (see `core/toolOutputChannel.js#mergeToolOutputIntoEvents`), NOT by `processEventStream`
|
|
127
|
+
* itself — consumers that don't opt into the merge (e.g. the AG-UI SSE encoder) never see it
|
|
128
|
+
* and the toolkits keep writing to stdout for them (today's headless behaviour).
|
|
129
|
+
*/
|
|
130
|
+
type: 'tool_output';
|
|
131
|
+
/**
|
|
132
|
+
* The tool call this chunk belongs to (LangChain's `ToolRunnableConfig.toolCall.id`,
|
|
133
|
+
* threaded through the toolkits), so a renderer can nest output under the exact call —
|
|
134
|
+
* TUI-C30 consumes this for per-call output previews. Optional only defensively: absent
|
|
135
|
+
* when the executing framework did not supply a tool call, in which case consumers should
|
|
136
|
+
* fall back to `name` attribution.
|
|
137
|
+
*/
|
|
138
|
+
id?: string;
|
|
139
|
+
/** The gth tool name (e.g. `run_shell_command`, a custom tool's name). Always known. */
|
|
140
|
+
name: string;
|
|
141
|
+
/** One verbatim streamed chunk of the child's stdout/stderr (or the notice text). */
|
|
142
|
+
chunk: string;
|
|
143
|
+
/**
|
|
144
|
+
* True when this chunk is the "🔧 Executing …" announcement rather than child output, so
|
|
145
|
+
* a richer renderer (TUI-C30) can style or strip it when previewing raw output lines.
|
|
146
|
+
*/
|
|
147
|
+
isNotice?: boolean;
|
|
69
148
|
} | {
|
|
70
149
|
type: 'tool_result';
|
|
71
150
|
id: string;
|
|
@@ -108,29 +187,168 @@ export interface PendingToolInterrupt {
|
|
|
108
187
|
name: string;
|
|
109
188
|
args: Record<string, unknown>;
|
|
110
189
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
190
|
+
* [[TUI-C67]] — **what kind of call this is, as the gate itself decided it** (§3.1/§4.7.5): a
|
|
191
|
+
* `shell` subject carrying the command, a `tool` subject, or an `mcpTool` subject carrying the
|
|
192
|
+
* user's own `mcpServers` key. It is the discriminator `decideToolApprovalInner` matched rules
|
|
193
|
+
* on, travelling to the surface so the prompt can branch on the same one.
|
|
194
|
+
*
|
|
195
|
+
* Both terminal approval surfaces used to open with *the agent wants to run a shell command*,
|
|
196
|
+
* which EXT-80 made false for the most common prompt in `manual` and `write` — a file write, an
|
|
197
|
+
* MCP call or a custom tool, each announced as a shell command.
|
|
198
|
+
* `core/approvals/promptHeader.ts` renders the sentence from this field for both of them;
|
|
199
|
+
* re-deriving the kind from {@link name} on each surface would be a second classifier, free to
|
|
200
|
+
* disagree with the one that gated the call.
|
|
201
|
+
*
|
|
202
|
+
* **The ACP server is currently that second classifier, and the rule above still stands.**
|
|
203
|
+
* `acpPermissions.ts` titles its permission request from its own `shellCommandOf`, keyed on
|
|
204
|
+
* {@link name} rather than on this field, which it never reads — a divergence pinned by an
|
|
205
|
+
* assertion in `packages/agent/spec/acpServer.spec.ts`. Closing it means reading this field there
|
|
206
|
+
* rather than the tool name, and that is [[TUI-C89]]'s work; do not read the divergence's
|
|
207
|
+
* existence as licence to re-derive the kind anywhere else.
|
|
208
|
+
*
|
|
209
|
+
* **The runner attaches it to every interrupt it hands the approval callback**, including the
|
|
210
|
+
* plainest case where nothing else on this interface is set. Optional only because an interrupt
|
|
211
|
+
* read back out of graph state (`getPendingToolInterrupts`) is assembled before any subject
|
|
212
|
+
* exists; a surface that renders through `promptHeader` and is handed one of those renders the
|
|
213
|
+
* generic tool sentence, never a wrong one.
|
|
214
|
+
*/
|
|
215
|
+
subject?: ApprovalSubject;
|
|
216
|
+
/**
|
|
217
|
+
* CFG-26 — when the AI rater escalated this `run_shell_command` to the human (rather than
|
|
218
|
+
* approving it or bouncing it back to the model), the rater's verdict is attached here so the
|
|
219
|
+
* approval surface can show an "AI rater (<tier>): <reason>" notice. Absent when the rater is
|
|
220
|
+
* off, or when the command reached the human without being rated.
|
|
115
221
|
*/
|
|
116
222
|
safetyVerdict?: ShellSafetyVerdict;
|
|
223
|
+
/**
|
|
224
|
+
* EXT-71 §3.2 — when this call reached the human because a declared `approvals.escalate` entry
|
|
225
|
+
* matched it, the entry that fired, rendered for display. It is the provenance the prompt shows:
|
|
226
|
+
* an escalation the user cannot trace to the line they wrote reads as the gate malfunctioning.
|
|
227
|
+
* Absent whenever the escalation came from the rung or the rater instead.
|
|
228
|
+
*/
|
|
229
|
+
escalatedBy?: string;
|
|
230
|
+
/**
|
|
231
|
+
* EXT-71 §6 — **what a sticky choice will store**, rendered in the object form the user would
|
|
232
|
+
* write in a config file, e.g. `{ "type": "shell", "matcher": "exact", "pattern": "npm test" }`.
|
|
233
|
+
* The menu MUST show this at the moment of the choice, on every surface: the user is shown the
|
|
234
|
+
* thing they are agreeing to rather than a generalization of it, which is what makes the display
|
|
235
|
+
* honest and cheap at once.
|
|
236
|
+
*
|
|
237
|
+
* **For a tool call the stored thing is the tool, not the arguments** (§4.7.4), so this reads
|
|
238
|
+
* e.g. `{ "type": "mcpTool", "server": "fetcher", "matcher": "exact", "pattern": "fetch_url",
|
|
239
|
+
* "host": "docs.internal.example" }`. That is the one place a grant is deliberately broader than
|
|
240
|
+
* what the human was shown, which is why the display carries the most weight there.
|
|
241
|
+
*
|
|
242
|
+
* Absent exactly where no sticky grant is on offer — a `catastrophic` outcome (§4.2 withdraws
|
|
243
|
+
* the persistent grants), a rung that remembers nothing, a command that does not statically
|
|
244
|
+
* resolve, or a tool call naming more than one host (which has no honest single-host entry) — so
|
|
245
|
+
* a prompt never advertises a control that has already been withdrawn.
|
|
246
|
+
*/
|
|
247
|
+
grantPreview?: string;
|
|
248
|
+
/**
|
|
249
|
+
* §6 — **the same grant in the words a menu control is written in**: `npm test` for a shell
|
|
250
|
+
* command, `tool gth_web_fetch (host docs.internal.example)` or `mcpTool jira/create_issue` for a
|
|
251
|
+
* tool call. It is what the *always approve* control names, so the control reads as
|
|
252
|
+
* *always approve this tool for this host* rather than as a bare key.
|
|
253
|
+
*
|
|
254
|
+
* It is rendered by `describeApprovalEntry` — the one-liner every other provenance message uses,
|
|
255
|
+
* including the §4.7.4 notice that later withdraws the grant. Sharing the renderer is the point:
|
|
256
|
+
* a menu that describes a grant differently from the notice that withdraws it is how a user stops
|
|
257
|
+
* trusting either.
|
|
258
|
+
*
|
|
259
|
+
* Present exactly when {@link grantPreview} is, since both are rendered from the one entry
|
|
260
|
+
* `recordApproval` would write.
|
|
261
|
+
*/
|
|
262
|
+
grantSummary?: string;
|
|
263
|
+
/**
|
|
264
|
+
* [[TUI-C26]] §6 — **what the menu's *always reject* choice will record**, in the object form the
|
|
265
|
+
* user would write in a config file. The deny mirror of {@link grantPreview}, shown at the moment
|
|
266
|
+
* of the choice for the same reason: a control that does not say what it stores is one the user
|
|
267
|
+
* has to guess at.
|
|
268
|
+
*
|
|
269
|
+
* **Its availability is NOT the grant's**, and reading one off the other is the mistake this
|
|
270
|
+
* field exists to prevent. The matcher's own rule is *undecidable → no match on the allow side, a
|
|
271
|
+
* match on the deny side*, so a command the gate cannot statically resolve **can** be refused
|
|
272
|
+
* permanently even though it can never be allowed permanently. `always reject` also stays offered
|
|
273
|
+
* on a `catastrophic` verdict, where §4.2 withdraws every sticky grant: sticky refusal is safe in
|
|
274
|
+
* every direction, and it is only the grant that is ever made harder.
|
|
275
|
+
*
|
|
276
|
+
* Absent only where the entry grammar cannot hold one at all — today, an MCP call whose server
|
|
277
|
+
* could not be attributed (the grammar's `server` cannot be empty). Absent means the control is
|
|
278
|
+
* **not offered**, never offered-and-disabled.
|
|
279
|
+
*/
|
|
280
|
+
denyPreview?: string;
|
|
281
|
+
/**
|
|
282
|
+
* §6 — the same deny entry in the words the control is written in, through the one-liner every
|
|
283
|
+
* other provenance message uses. Present exactly when {@link denyPreview} is, since both are
|
|
284
|
+
* rendered from the one entry the runner would record.
|
|
285
|
+
*/
|
|
286
|
+
denySummary?: string;
|
|
287
|
+
/**
|
|
288
|
+
* [[EXT-29]] §6 — **every round of the §5 negotiation that preceded this escalation**, oldest
|
|
289
|
+
* first, when one did.
|
|
290
|
+
*
|
|
291
|
+
* The user is not asked to rule on the final command in isolation: *that the agent proposed
|
|
292
|
+
* `git reset --hard origin/main` three times unchanged, against two rejections that each told it
|
|
293
|
+
* what to fix, is itself the most important thing on the screen, and it is invisible if only the
|
|
294
|
+
* last attempt is shown.* `core/shell/negotiation.ts`'s `renderNegotiationTranscript` is the
|
|
295
|
+
* shared renderer, so two surfaces cannot describe one exchange two ways.
|
|
296
|
+
*
|
|
297
|
+
* Absent for every escalation that had no negotiation — `catastrophic` (§4.2 gives it no rounds
|
|
298
|
+
* at all), a declared `approvals.escalate` entry, an unrated rung, a tool subject.
|
|
299
|
+
*/
|
|
300
|
+
negotiationRounds?: readonly RaterNegotiationRound[];
|
|
301
|
+
/**
|
|
302
|
+
* [[EXT-29]] §5.3 — **how many attempts the agent actually made**, counted since a human was last
|
|
303
|
+
* involved rather than since the last approved call.
|
|
304
|
+
*
|
|
305
|
+
* It is a separate number from `negotiationRounds.length` because an approved call clears the
|
|
306
|
+
* transcript, and a surface reading the array's length reports only the attempts that happened
|
|
307
|
+
* after the last one. On the escalation this was measured from, the agent proposed the same
|
|
308
|
+
* command five times, was refused every time, and the human was shown three — the two calls it
|
|
309
|
+
* made in between were `git stash` and `git status`, both approved, both erasing the rounds
|
|
310
|
+
* before them. Persistence is the single most decision-relevant fact this block carries, so
|
|
311
|
+
* under-reporting it by nearly half is not a cosmetic count.
|
|
312
|
+
*
|
|
313
|
+
* Present exactly when {@link negotiationRounds} is, and never smaller than its length.
|
|
314
|
+
*/
|
|
315
|
+
negotiationAttempts?: number;
|
|
117
316
|
}
|
|
118
317
|
/**
|
|
119
|
-
* Persistence scope for an `approve` decision (
|
|
318
|
+
* Persistence scope for an `approve` decision (spec §6):
|
|
120
319
|
* - `once` — run this single invocation only; remember nothing (the default).
|
|
121
|
-
* - `session` — remember
|
|
122
|
-
* instance, so
|
|
123
|
-
*
|
|
320
|
+
* - `session` — remember **this command**, as an `exact` entry (§3.1), for the life of this runner
|
|
321
|
+
* instance, so the same command stops re-prompting. A longer variant of it still asks: the menu
|
|
322
|
+
* never widens, and breadth is something a human writes in a config file.
|
|
323
|
+
* - `always` — additionally persist that entry to the project store
|
|
124
324
|
* (`.gsloth/.gsloth-settings/shell-allowlist.json`) so it survives across runs.
|
|
125
325
|
*/
|
|
126
326
|
export type ToolApprovalScope = 'once' | 'session' | 'always';
|
|
327
|
+
/**
|
|
328
|
+
* §6 — persistence scope for a `reject` decision, the *always reject* half of the escalation menu:
|
|
329
|
+
* - `once` — refuse this single invocation; remember nothing (the default).
|
|
330
|
+
* - `session` — additionally record a **deny** entry for this call, in the one entry grammar, for
|
|
331
|
+
* the life of this runner instance. The matcher consults it before anything else, so the next
|
|
332
|
+
* identical call is refused without reaching a person at all.
|
|
333
|
+
*
|
|
334
|
+
* **There is deliberately no `always`.** An `approve` can persist because there is a project store
|
|
335
|
+
* to persist it to; there is no persisted deny store, and inventing one is a decision about a file
|
|
336
|
+
* users will have to live with rather than a rendering choice. So the scopes here are the ones the
|
|
337
|
+
* gate can actually honour, and a control that promised more would be §6's own failure mode — an
|
|
338
|
+
* affordance offered and then quietly refused.
|
|
339
|
+
*/
|
|
340
|
+
export type ToolRejectScope = 'once' | 'session';
|
|
127
341
|
/**
|
|
128
342
|
* A consumer-supplied decision on a {@link PendingToolInterrupt}: approve runs the tool,
|
|
129
343
|
* reject feeds the model a tool-rejected message (with the optional reason).
|
|
130
344
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
345
|
+
* Each arm carries an optional scope; when absent it means `once` (backward compatible — a bare
|
|
346
|
+
* `{ type: 'approve' }` or `{ type: 'reject' }` still type-checks and behaves as the single-shot
|
|
347
|
+
* decision that persists nothing).
|
|
348
|
+
*
|
|
349
|
+
* The two scopes are **different types on purpose**. Sharing {@link ToolApprovalScope} would let a
|
|
350
|
+
* surface send `{ type: 'reject', scope: 'always' }`, which type-checks, promises a persistence
|
|
351
|
+
* nothing implements, and degrades to a session refusal with no diagnostic.
|
|
134
352
|
*/
|
|
135
353
|
export type ToolApprovalDecision = {
|
|
136
354
|
type: 'approve';
|
|
@@ -138,6 +356,7 @@ export type ToolApprovalDecision = {
|
|
|
138
356
|
} | {
|
|
139
357
|
type: 'reject';
|
|
140
358
|
message?: string;
|
|
359
|
+
scope?: ToolRejectScope;
|
|
141
360
|
};
|
|
142
361
|
/**
|
|
143
362
|
* Callback the {@link GthAgentRunner} invokes when a run suspends on a tool-approval
|
|
@@ -146,8 +365,62 @@ export type ToolApprovalDecision = {
|
|
|
146
365
|
* silently hang or auto-approve.
|
|
147
366
|
*/
|
|
148
367
|
export type ToolApprovalCallback = (pending: PendingToolInterrupt) => Promise<ToolApprovalDecision> | ToolApprovalDecision;
|
|
368
|
+
/**
|
|
369
|
+
* [[TUI-C68]] §6.1 — what the **attack banner** is about: the command whose own structure the
|
|
370
|
+
* rater called hostile, and the rater's explanation of what it saw. Both are untrusted text and a
|
|
371
|
+
* surface must paint them through `core/shell/framing`.
|
|
372
|
+
*
|
|
373
|
+
* A separate shape from {@link PendingToolInterrupt} because it is a separate question. An approval
|
|
374
|
+
* prompt asks *may this run*, and every control on its menu is a legitimate answer carrying a
|
|
375
|
+
* scope; this asks *do you believe the rating is wrong*, has exactly one way through, and offers no
|
|
376
|
+
* scope at all — so a surface cannot reach for a menu control that does not exist here.
|
|
377
|
+
*/
|
|
378
|
+
export interface PendingAttackHalt {
|
|
379
|
+
/** The command the rater rated an attack, as the model wrote it. Untrusted text. */
|
|
380
|
+
command: string;
|
|
381
|
+
/** The rater's own explanation of what the command's structure showed. Untrusted text. */
|
|
382
|
+
reason: string;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* §6.1 — the human's answer at the attack banner.
|
|
386
|
+
*
|
|
387
|
+
* **A string union rather than a boolean, and the polarity is deliberate.** `run-anyway` is the
|
|
388
|
+
* only value that runs anything; every other value — one a future surface invents, or `undefined`
|
|
389
|
+
* from a surface that forgot to return — stops the run. A boolean would put the irreversible answer
|
|
390
|
+
* one inverted comparison away, and there is nothing here worth being one typo from.
|
|
391
|
+
*/
|
|
392
|
+
export type AttackHaltAnswer = 'run-anyway' | 'stop';
|
|
393
|
+
/**
|
|
394
|
+
* §6.1 — callback the {@link GthAgentRunner} invokes when the rater rates a command an `attack`, so
|
|
395
|
+
* an interactive surface can show the red banner and let a human type their way past it.
|
|
396
|
+
*
|
|
397
|
+
* **Absent means halt**, exactly as an absent {@link ToolApprovalCallback} means the §6.2
|
|
398
|
+
* non-interactive exit. A surface that never wires this — a CI run, an AG-UI server, a surface
|
|
399
|
+
* nobody has written yet — keeps the halt, so forgetting fails safe. It may never block a
|
|
400
|
+
* non-interactive run, and no timeout turns waiting into a grant: waiting is something only a wired
|
|
401
|
+
* surface can cause.
|
|
402
|
+
*/
|
|
403
|
+
export type AttackHaltCallback = (halt: PendingAttackHalt) => Promise<AttackHaltAnswer> | AttackHaltAnswer;
|
|
404
|
+
/**
|
|
405
|
+
* GS2-95 — options for {@link GthAgentInterface#init} that name the run without changing how it
|
|
406
|
+
* behaves.
|
|
407
|
+
*/
|
|
408
|
+
export interface GthAgentInitOptions {
|
|
409
|
+
/**
|
|
410
|
+
* The name of the command the USER typed, for the run header only (`eval`, `batch`, `workflow`,
|
|
411
|
+
* `gth-batch`). Supplied by the command; the agent never invents it.
|
|
412
|
+
*
|
|
413
|
+
* It is a SEPARATE input from `command` because `command` is not a label: it selects the mode
|
|
414
|
+
* prompt (`readModePrompt`), the per-command approvals posture and the command-specific
|
|
415
|
+
* filesystem config. A command that runs its work through another verb's prompt — `gth eval`
|
|
416
|
+
* through `ask`, `gth batch` through `exec` — must be able to say its own name without moving the
|
|
417
|
+
* prompt it runs under. Omitted, the header falls back to the init verb, which is the right
|
|
418
|
+
* answer for every command whose verb IS its name.
|
|
419
|
+
*/
|
|
420
|
+
displayCommand?: string;
|
|
421
|
+
}
|
|
149
422
|
export interface GthAgentInterface {
|
|
150
|
-
init(command: GthCommand | undefined, configIn: GthConfig, checkpointSaver?: BaseCheckpointSaver | undefined): Promise<void>;
|
|
423
|
+
init(command: GthCommand | undefined, configIn: GthConfig, checkpointSaver?: BaseCheckpointSaver | undefined, options?: GthAgentInitOptions): Promise<void>;
|
|
151
424
|
invoke(messages: Message[], runConfig: RunnableConfig): Promise<string>;
|
|
152
425
|
stream(messages: Message[], runConfig: RunnableConfig): Promise<IterableReadableStream<string>>;
|
|
153
426
|
/**
|
|
@@ -172,6 +445,26 @@ export interface GthAgentInterface {
|
|
|
172
445
|
* approve/reject confirmation loop.
|
|
173
446
|
*/
|
|
174
447
|
getPendingToolInterrupts?(runConfig: RunnableConfig): Promise<PendingToolInterrupt[]>;
|
|
448
|
+
/**
|
|
449
|
+
* EXT-58 (spec §4.4) — the names of the tools registered with the graph at `init`. The runner
|
|
450
|
+
* intersects them with the built-in summaries table to tell the rater which already-granted
|
|
451
|
+
* built-ins it may offer as an alternative, so a suggestion can never name a tool the model does
|
|
452
|
+
* not have. Optional: an agent that does not track its tools simply omits it, and the rater then
|
|
453
|
+
* receives no granted list (and so suggests nothing).
|
|
454
|
+
*/
|
|
455
|
+
getRegisteredToolNames?(): string[];
|
|
456
|
+
/**
|
|
457
|
+
* EXT-70 (spec §4.7.1) — what the connected MCP servers declared about their own tools in their
|
|
458
|
+
* `tools/list` responses, keyed by the REGISTERED tool name (`mcp__<server>__<tool>`). The runner
|
|
459
|
+
* reads it as the `mcp` half of a declared-annotation lookup when it computes a call's effective
|
|
460
|
+
* annotation set.
|
|
461
|
+
*
|
|
462
|
+
* These are **claims, not credentials**: nothing here has been trusted, and an entry only becomes
|
|
463
|
+
* load-bearing where the user's `approvals.mcp` block believes that hint from that server.
|
|
464
|
+
* Optional — an agent that tracks no tools omits it, and every tool is then fail-closed, which is
|
|
465
|
+
* exactly what a fully distrustful configuration computes anyway.
|
|
466
|
+
*/
|
|
467
|
+
getDeclaredMcpToolAnnotations?(): ReadonlyMap<string, DeclaredToolAnnotations>;
|
|
175
468
|
/**
|
|
176
469
|
* GS2-16 — reset the per-run analytics accumulator so the NEXT turn's token/tool totals start
|
|
177
470
|
* from zero. Called by {@link GthAgentRunner} at each turn boundary (the runner is reused across
|
|
@@ -188,18 +481,58 @@ export interface GthAgentInterface {
|
|
|
188
481
|
}
|
|
189
482
|
/**
|
|
190
483
|
* Factory that produces a {@link GthAgentInterface} implementation. Injected into
|
|
191
|
-
* {@link GthAgentRunner} so embedders can swap the lean `GthLangChainAgent` (default,
|
|
192
|
-
*
|
|
193
|
-
* importing deepagents.
|
|
484
|
+
* {@link GthAgentRunner} so embedders can swap the lean `GthLangChainAgent` (the default, in
|
|
485
|
+
* core) for another graph builder without core ever importing it.
|
|
194
486
|
*/
|
|
195
487
|
export type GthAgentFactory = (statusUpdate: StatusUpdateCallback, resolvers?: AgentResolvers) => GthAgentInterface;
|
|
196
488
|
export type ToolsResolver = (config: GthConfig, command?: GthCommand) => Promise<StructuredToolInterface[]>;
|
|
197
489
|
export type ToolsCleanup = () => Promise<void>;
|
|
198
490
|
export type MiddlewareResolver = (middleware: any[] | undefined, config: GthConfig) => Promise<any[]>;
|
|
199
491
|
export type MiddlewareCleanup = () => Promise<void>;
|
|
492
|
+
/**
|
|
493
|
+
* EXT-32 — one connected MCP server's discovery `instructions` string (from its MCP `initialize`
|
|
494
|
+
* handshake), paired with the server name it came from. Captured once during tool resolution and
|
|
495
|
+
* reused: injected (fenced + per-server-labelled) into the composed system prompt, and available
|
|
496
|
+
* for [[TUI-C20]]'s MCP debug tab to render the same captured text. Only servers that actually
|
|
497
|
+
* supplied non-empty instructions appear here.
|
|
498
|
+
*/
|
|
499
|
+
export interface McpServerInstruction {
|
|
500
|
+
/** The configured MCP server name (the key under `config.mcpServers`). */
|
|
501
|
+
server: string;
|
|
502
|
+
/** The server-provided instructions text (trimmed, non-empty). */
|
|
503
|
+
instructions: string;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* A per-server MCP connection failure captured during the most recent {@link ToolsResolver} call.
|
|
507
|
+
* Recorded when a configured MCP server can't be reached (connection/handshake/auth error), so the
|
|
508
|
+
* failure — otherwise a transient `displayWarning` that scrolls away the moment the Ink TUI takes
|
|
509
|
+
* over the screen — can be re-surfaced persistently in the chrome AND named in the /debug MCP tab
|
|
510
|
+
* (which renders per configured server and would otherwise show only a bare "no tools" line, with
|
|
511
|
+
* no hint that the server never connected). Mirrors {@link McpServerInstruction}.
|
|
512
|
+
*/
|
|
513
|
+
export interface McpConnectionFailure {
|
|
514
|
+
/** The configured MCP server name (the key under `config.mcpServers`). */
|
|
515
|
+
server: string;
|
|
516
|
+
/** A concise, human-readable reason (the underlying connection error's message). */
|
|
517
|
+
reason: string;
|
|
518
|
+
}
|
|
200
519
|
export interface AgentResolvers {
|
|
201
520
|
resolveTools?: ToolsResolver;
|
|
202
521
|
cleanupTools?: ToolsCleanup;
|
|
203
522
|
resolveMiddleware?: MiddlewareResolver;
|
|
204
523
|
cleanupMiddleware?: MiddlewareCleanup;
|
|
524
|
+
/**
|
|
525
|
+
* EXT-32 — the per-server MCP discovery instructions captured during the most recent
|
|
526
|
+
* {@link ToolsResolver} call (empty when no MCP servers are configured or none supplied
|
|
527
|
+
* instructions). Optional: resolvers without MCP support simply omit it, and the prompt
|
|
528
|
+
* composition treats an absent accessor as "no instructions" (no MCP section is emitted).
|
|
529
|
+
*/
|
|
530
|
+
getMcpServerInstructions?(): McpServerInstruction[];
|
|
531
|
+
/**
|
|
532
|
+
* The per-server MCP connection failures captured during the most recent {@link ToolsResolver}
|
|
533
|
+
* call (empty when every configured server connected, or none is configured). Optional: resolvers
|
|
534
|
+
* without MCP support omit it, and callers treat an absent accessor as "no failures". Read by the
|
|
535
|
+
* TUI to surface a persistent notice and to annotate the /debug MCP tab.
|
|
536
|
+
*/
|
|
537
|
+
getMcpConnectionFailures?(): McpConnectionFailure[];
|
|
205
538
|
}
|
package/dist/core/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAmDA;;;;GAIG;AACH,MAAM,CAAN,IAAY,WAQX;AARD,WAAY,WAAW;IACrB,+CAAS,CAAA;IACT,6CAAQ,CAAA;IACR,mDAAW,CAAA;IACX,mDAAW,CAAA;IACX,mDAAW,CAAA;IACX,+CAAS,CAAA;IACT,iDAAU,CAAA;AACZ,CAAC,EARW,WAAW,KAAX,WAAW,QAQtB"}
|
|
@@ -7,13 +7,22 @@
|
|
|
7
7
|
* DB or a terminal. Every function is a pure `data -> string[]` transform (one display line per
|
|
8
8
|
* element); no I/O, no colour codes.
|
|
9
9
|
*/
|
|
10
|
-
import type { HistoryInsights, SessionSearchResult } from '#src/history/historyStore.js';
|
|
10
|
+
import type { ConversationSummary, HistoryInsights, SessionRecord, SessionSearchResult } from '#src/history/historyStore.js';
|
|
11
11
|
/**
|
|
12
12
|
* Render FTS search hits: a header line per hit plus its snippet (or a prompt preview when the
|
|
13
13
|
* snippet is empty). Returns a friendly single line when there are none.
|
|
14
14
|
*/
|
|
15
15
|
export declare function formatSearchResults(results: SessionSearchResult[]): string[];
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* GS2-19 — render a conversation-grained listing: one header + last-turn preview per conversation.
|
|
18
|
+
* The header carries the count / timespan / last message that make the conversation the top-level
|
|
19
|
+
* unit (`gth history list`), replacing the old flat per-turn list.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatConversationList(conversations: ConversationSummary[]): string[];
|
|
22
|
+
/**
|
|
23
|
+
* GS2-19 — render one conversation's full thread (all turns in order) for `gth history show <id>`.
|
|
24
|
+
* Each turn shows its prompt and response preview so a search hit can be expanded into context.
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatConversationThread(turns: SessionRecord[]): string[];
|
|
18
27
|
/** Render the analytics summary: totals, top tools, per-command breakdown. */
|
|
19
28
|
export declare function formatInsightsSummary(insights: HistoryInsights): string[];
|
|
@@ -3,13 +3,17 @@ function oneLine(text, max = 80) {
|
|
|
3
3
|
const s = (text ?? '').replace(/\s+/g, ' ').trim();
|
|
4
4
|
return s.length > max ? s.slice(0, max - 1) + '…' : s;
|
|
5
5
|
}
|
|
6
|
-
/** A compact `#id <ts> [command] model` header line for one
|
|
6
|
+
/** A compact `#id <ts> [command] model (conversation #cid)` header line for one turn. */
|
|
7
7
|
function headerLine(r) {
|
|
8
8
|
const parts = [`#${r.id}`, r.ts];
|
|
9
9
|
if (r.command)
|
|
10
10
|
parts.push(`[${r.command}]`);
|
|
11
11
|
if (r.model)
|
|
12
12
|
parts.push(r.model);
|
|
13
|
+
// GS2-19: a search hit resolves to the conversation it belongs to, so the reader can pull up the
|
|
14
|
+
// whole thread (`gth history show <cid>`). Older rows migrated from GS2-7 always have one now.
|
|
15
|
+
if (r.conversationId != null)
|
|
16
|
+
parts.push(`(conversation #${r.conversationId})`);
|
|
13
17
|
return parts.join(' ');
|
|
14
18
|
}
|
|
15
19
|
/**
|
|
@@ -29,22 +33,60 @@ export function formatSearchResults(results) {
|
|
|
29
33
|
}
|
|
30
34
|
return lines;
|
|
31
35
|
}
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
/**
|
|
37
|
+
* GS2-19 — render a conversation-grained listing: one header + last-turn preview per conversation.
|
|
38
|
+
* The header carries the count / timespan / last message that make the conversation the top-level
|
|
39
|
+
* unit (`gth history list`), replacing the old flat per-turn list.
|
|
40
|
+
*/
|
|
41
|
+
export function formatConversationList(conversations) {
|
|
42
|
+
if (conversations.length === 0) {
|
|
35
43
|
return [
|
|
36
|
-
'No
|
|
44
|
+
'No conversations recorded yet. Enable history with `history.enabled: true` in your config.',
|
|
37
45
|
];
|
|
38
46
|
}
|
|
39
47
|
const lines = [];
|
|
40
|
-
for (const
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
for (const c of conversations) {
|
|
49
|
+
const parts = [`#${c.id}`];
|
|
50
|
+
// Timespan across the conversation's turns; a 1-turn (or not-yet-started) conversation collapses
|
|
51
|
+
// to a single instant, so show one timestamp rather than an `a → a` range.
|
|
52
|
+
if (c.firstTs && c.lastTs && c.firstTs !== c.lastTs) {
|
|
53
|
+
parts.push(`${c.firstTs} → ${c.lastTs}`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
parts.push(c.lastTs ?? c.firstTs ?? c.startedTs);
|
|
57
|
+
}
|
|
58
|
+
if (c.command)
|
|
59
|
+
parts.push(`[${c.command}]`);
|
|
60
|
+
if (c.model)
|
|
61
|
+
parts.push(c.model);
|
|
62
|
+
parts.push(`(${c.turnCount} ${c.turnCount === 1 ? 'turn' : 'turns'})`);
|
|
63
|
+
lines.push(parts.join(' '));
|
|
64
|
+
const preview = oneLine(c.lastPrompt, 100);
|
|
43
65
|
if (preview)
|
|
44
66
|
lines.push(` ${preview}`);
|
|
45
67
|
}
|
|
46
68
|
return lines;
|
|
47
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* GS2-19 — render one conversation's full thread (all turns in order) for `gth history show <id>`.
|
|
72
|
+
* Each turn shows its prompt and response preview so a search hit can be expanded into context.
|
|
73
|
+
*/
|
|
74
|
+
export function formatConversationThread(turns) {
|
|
75
|
+
if (turns.length === 0)
|
|
76
|
+
return ['No turns found for that conversation.'];
|
|
77
|
+
const lines = [];
|
|
78
|
+
turns.forEach((t, i) => {
|
|
79
|
+
const header = t.ts ? `Turn ${i + 1} ${t.ts}` : `Turn ${i + 1}`;
|
|
80
|
+
lines.push(header);
|
|
81
|
+
const prompt = oneLine(t.prompt, 200);
|
|
82
|
+
if (prompt)
|
|
83
|
+
lines.push(` > ${prompt}`);
|
|
84
|
+
const response = oneLine(t.response, 200);
|
|
85
|
+
if (response)
|
|
86
|
+
lines.push(` ${response}`);
|
|
87
|
+
});
|
|
88
|
+
return lines;
|
|
89
|
+
}
|
|
48
90
|
/** Render the analytics summary: totals, top tools, per-command breakdown. */
|
|
49
91
|
export function formatInsightsSummary(insights) {
|
|
50
92
|
if (insights.sessionCount === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"historyFormat.js","sourceRoot":"","sources":["../../src/history/historyFormat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"historyFormat.js","sourceRoot":"","sources":["../../src/history/historyFormat.ts"],"names":[],"mappings":"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"}
|