@gaunt-sloth/core 2.0.0-alpha.3 → 2.0.0-alpha.31
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/README.md +52 -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/defaults.d.ts +84 -0
- package/dist/config/defaults.js +99 -0
- package/dist/config/defaults.js.map +1 -0
- 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/jsonc.d.ts +12 -0
- package/dist/config/jsonc.js +41 -0
- package/dist/config/jsonc.js.map +1 -0
- package/dist/config/loader.d.ts +246 -0
- package/dist/config/loader.js +1321 -0
- package/dist/config/loader.js.map +1 -0
- 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 +2999 -0
- package/dist/config/schema.js +1519 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/shell-policy.d.ts +896 -0
- package/dist/config/shell-policy.js +750 -0
- package/dist/config/shell-policy.js.map +1 -0
- 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 +760 -0
- package/dist/config/types.js +13 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config.d.ts +34 -827
- package/dist/config.js +25 -657
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +46 -0
- package/dist/constants.js +46 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/GthAbstractAgent.d.ts +135 -2
- package/dist/core/GthAbstractAgent.js +496 -30
- package/dist/core/GthAbstractAgent.js.map +1 -1
- package/dist/core/GthAgentRunner.d.ts +568 -54
- package/dist/core/GthAgentRunner.js +1537 -136
- package/dist/core/GthAgentRunner.js.map +1 -1
- package/dist/core/GthLangChainAgent.d.ts +115 -0
- package/dist/core/GthLangChainAgent.js +644 -17
- 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/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 +75 -0
- package/dist/core/debugCapture.js +101 -0
- package/dist/core/debugCapture.js.map +1 -0
- package/dist/core/gthLeanAgentFactory.d.ts +9 -0
- package/dist/core/gthLeanAgentFactory.js +10 -0
- package/dist/core/gthLeanAgentFactory.js.map +1 -0
- package/dist/core/launchBanner.d.ts +120 -0
- package/dist/core/launchBanner.js +418 -0
- package/dist/core/launchBanner.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 +60 -0
- package/dist/core/reasoningBlocks.js +98 -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/runStats.d.ts +52 -0
- package/dist/core/runStats.js +118 -0
- package/dist/core/runStats.js.map +1 -0
- package/dist/core/shell/ShellCommandFailedError.d.ts +54 -0
- package/dist/core/shell/ShellCommandFailedError.js +68 -0
- package/dist/core/shell/ShellCommandFailedError.js.map +1 -0
- 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 +84 -0
- package/dist/core/shell/approvalStop.js +119 -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 +81 -0
- package/dist/core/shell/hardline.js +607 -0
- package/dist/core/shell/hardline.js.map +1 -0
- package/dist/core/shell/negotiation.d.ts +249 -0
- package/dist/core/shell/negotiation.js +355 -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 +935 -0
- package/dist/core/shell/rater.js +1473 -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/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 +294 -12
- package/dist/core/types.js.map +1 -1
- package/dist/history/historyFormat.d.ts +28 -0
- package/dist/history/historyFormat.js +127 -0
- package/dist/history/historyFormat.js.map +1 -0
- package/dist/history/historyStore.d.ts +198 -0
- package/dist/history/historyStore.js +482 -0
- package/dist/history/historyStore.js.map +1 -0
- package/dist/history/recordSession.d.ts +37 -0
- package/dist/history/recordSession.js +56 -0
- package/dist/history/recordSession.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +5 -10
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/deepseek.d.ts +1 -1
- package/dist/providers/deepseek.js +5 -10
- package/dist/providers/deepseek.js.map +1 -1
- 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 +52 -0
- package/dist/providers/geminiThinking.js +72 -0
- package/dist/providers/geminiThinking.js.map +1 -0
- package/dist/providers/google-genai.d.ts +1 -1
- package/dist/providers/google-genai.js +12 -11
- package/dist/providers/google-genai.js.map +1 -1
- package/dist/providers/groq.d.ts +1 -1
- package/dist/providers/groq.js +5 -10
- 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 +153 -6
- package/dist/providers/modelDiscovery.js +295 -41
- package/dist/providers/modelDiscovery.js.map +1 -1
- package/dist/providers/ollama.d.ts +19 -5
- package/dist/providers/ollama.js +60 -52
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +39 -10
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +4 -5
- package/dist/providers/openrouter.js +20 -35
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/vertexai.d.ts +1 -1
- package/dist/providers/vertexai.js +12 -11
- package/dist/providers/vertexai.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +5 -10
- 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 +60 -0
- package/dist/runtime/conversation.js +151 -0
- package/dist/runtime/conversation.js.map +1 -0
- package/dist/runtime/singleShot.d.ts +25 -5
- package/dist/runtime/singleShot.js +95 -36
- 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 +52 -0
- package/dist/utils/consoleUtils.js +72 -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.d.ts +24 -2
- package/dist/utils/fileUtils.js +54 -12
- package/dist/utils/fileUtils.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 +225 -0
- package/dist/utils/systemPromptNotes.js +340 -0
- package/dist/utils/systemPromptNotes.js.map +1 -0
- package/dist/utils/systemUtils.d.ts +49 -1
- package/dist/utils/systemUtils.js +67 -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 +66 -0
- package/dist/utils/untrustedText.js +80 -0
- package/dist/utils/untrustedText.js.map +1 -0
- package/package.json +22 -6
- package/schema/gsloth-config.schema.json +3134 -0
- 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
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/** Collapse whitespace and clip to `max` chars with an ellipsis, for one-line previews. */
|
|
2
|
+
function oneLine(text, max = 80) {
|
|
3
|
+
const s = (text ?? '').replace(/\s+/g, ' ').trim();
|
|
4
|
+
return s.length > max ? s.slice(0, max - 1) + '…' : s;
|
|
5
|
+
}
|
|
6
|
+
/** A compact `#id <ts> [command] model (conversation #cid)` header line for one turn. */
|
|
7
|
+
function headerLine(r) {
|
|
8
|
+
const parts = [`#${r.id}`, r.ts];
|
|
9
|
+
if (r.command)
|
|
10
|
+
parts.push(`[${r.command}]`);
|
|
11
|
+
if (r.model)
|
|
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})`);
|
|
17
|
+
return parts.join(' ');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Render FTS search hits: a header line per hit plus its snippet (or a prompt preview when the
|
|
21
|
+
* snippet is empty). Returns a friendly single line when there are none.
|
|
22
|
+
*/
|
|
23
|
+
export function formatSearchResults(results) {
|
|
24
|
+
if (results.length === 0)
|
|
25
|
+
return ['No matching sessions found.'];
|
|
26
|
+
const lines = [];
|
|
27
|
+
for (const r of results) {
|
|
28
|
+
lines.push(headerLine(r));
|
|
29
|
+
const detail = r.snippet && r.snippet.trim().length > 0 ? r.snippet : r.prompt;
|
|
30
|
+
const preview = oneLine(detail, 100);
|
|
31
|
+
if (preview)
|
|
32
|
+
lines.push(` ${preview}`);
|
|
33
|
+
}
|
|
34
|
+
return lines;
|
|
35
|
+
}
|
|
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) {
|
|
43
|
+
return [
|
|
44
|
+
'No conversations recorded yet. Enable history with `history.enabled: true` in your config.',
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
const lines = [];
|
|
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);
|
|
65
|
+
if (preview)
|
|
66
|
+
lines.push(` ${preview}`);
|
|
67
|
+
}
|
|
68
|
+
return lines;
|
|
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
|
+
}
|
|
90
|
+
/** Render the analytics summary: totals, top tools, per-command breakdown. */
|
|
91
|
+
export function formatInsightsSummary(insights) {
|
|
92
|
+
if (insights.sessionCount === 0) {
|
|
93
|
+
return [
|
|
94
|
+
'No sessions recorded yet. Enable history with `history.enabled: true` in your config.',
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
const lines = [];
|
|
98
|
+
lines.push(`Sessions: ${insights.sessionCount}`);
|
|
99
|
+
if (insights.firstTs && insights.lastTs) {
|
|
100
|
+
lines.push(`Span: ${insights.firstTs} → ${insights.lastTs}`);
|
|
101
|
+
}
|
|
102
|
+
// GS2-16: only surface the token/cost/top-tool lines when there is real data behind them.
|
|
103
|
+
// Older records (and providers that report no usage) leave these zero/empty; printing
|
|
104
|
+
// `Tokens: 0` / `$0.0000` / `(none recorded)` reads as "the run used nothing", which is
|
|
105
|
+
// misleading, so omit the line entirely instead. Sessions / Span / By-command always show.
|
|
106
|
+
if (insights.totalTokens > 0) {
|
|
107
|
+
lines.push(`Tokens: ${insights.totalTokens} total ` +
|
|
108
|
+
`(${insights.totalTokensInput} in / ${insights.totalTokensOutput} out)`);
|
|
109
|
+
}
|
|
110
|
+
// Cost is only ever recorded when a reliable price was available (the recorder never invents
|
|
111
|
+
// one), so a positive total is the signal that a cost line is meaningful.
|
|
112
|
+
if (insights.totalCostUsd > 0) {
|
|
113
|
+
lines.push(`Estimated cost: $${insights.totalCostUsd.toFixed(4)}`);
|
|
114
|
+
}
|
|
115
|
+
if (insights.perCommand.length > 0) {
|
|
116
|
+
lines.push('By command:');
|
|
117
|
+
for (const c of insights.perCommand)
|
|
118
|
+
lines.push(` ${c.command}: ${c.count}`);
|
|
119
|
+
}
|
|
120
|
+
if (insights.topTools.length > 0) {
|
|
121
|
+
lines.push('Top tools:');
|
|
122
|
+
for (const t of insights.topTools)
|
|
123
|
+
lines.push(` ${t.tool}: ${t.count}`);
|
|
124
|
+
}
|
|
125
|
+
return lines;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=historyFormat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyFormat.js","sourceRoot":"","sources":["../../src/history/historyFormat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/** Filename of the global history DB inside `~/.gsloth`. */
|
|
2
|
+
export declare const HISTORY_DB_FILENAME = "history.db";
|
|
3
|
+
/** A single persisted session record (all analytics fields optional; populated when available). */
|
|
4
|
+
export interface SessionRecord {
|
|
5
|
+
/**
|
|
6
|
+
* GS2-19 — the parent conversation this turn belongs to. When omitted, {@link HistoryStore.record}
|
|
7
|
+
* opens a fresh single-turn conversation for the row (so a bare single-shot run = a 1-turn
|
|
8
|
+
* conversation). Interactive sessions {@link HistoryStore.openConversation | open} one conversation
|
|
9
|
+
* up-front and pass its id here on every turn, grouping the whole chat under one conversation.
|
|
10
|
+
*/
|
|
11
|
+
conversationId?: number;
|
|
12
|
+
/** ISO-8601 timestamp; defaults to now when omitted. */
|
|
13
|
+
ts?: string;
|
|
14
|
+
/** Project / working directory the run happened in. */
|
|
15
|
+
project?: string;
|
|
16
|
+
/** Originating command (ask/chat/code/exec/…). */
|
|
17
|
+
command?: string;
|
|
18
|
+
/** Human-readable model/provider label. */
|
|
19
|
+
model?: string;
|
|
20
|
+
/** The user prompt / source that started the run (full-text indexed). */
|
|
21
|
+
prompt?: string;
|
|
22
|
+
/** The final assistant response text (full-text indexed). */
|
|
23
|
+
response?: string;
|
|
24
|
+
/** Prompt/input token count, when known. */
|
|
25
|
+
tokensInput?: number;
|
|
26
|
+
/** Completion/output token count, when known. */
|
|
27
|
+
tokensOutput?: number;
|
|
28
|
+
/** Estimated cost in USD, when known. */
|
|
29
|
+
costUsd?: number;
|
|
30
|
+
/** Names of tools invoked during the run, when known. */
|
|
31
|
+
tools?: string[];
|
|
32
|
+
/** Wall-clock duration of the run in milliseconds, when known. */
|
|
33
|
+
durationMs?: number;
|
|
34
|
+
}
|
|
35
|
+
/** A search hit: the stored record plus its id and a highlighted snippet. */
|
|
36
|
+
export interface SessionSearchResult extends SessionRecord {
|
|
37
|
+
id: number;
|
|
38
|
+
ts: string;
|
|
39
|
+
/** FTS5 snippet around the match (may be empty). */
|
|
40
|
+
snippet: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* GS2-19 — metadata for a conversation (a group of turns). Passed to
|
|
44
|
+
* {@link HistoryStore.openConversation} at interactive-session start.
|
|
45
|
+
*/
|
|
46
|
+
export interface ConversationMeta {
|
|
47
|
+
/** ISO-8601 start timestamp; defaults to now when omitted. */
|
|
48
|
+
ts?: string;
|
|
49
|
+
/** Project / working directory the conversation happened in. */
|
|
50
|
+
project?: string;
|
|
51
|
+
/** Originating command (chat/code/ask/exec/…). */
|
|
52
|
+
command?: string;
|
|
53
|
+
/** Human-readable model/provider label. */
|
|
54
|
+
model?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* GS2-19 — a conversation-grained listing row: the conversation's metadata plus the aggregate of
|
|
58
|
+
* its turns (how many, the timespan they cover, and a preview of the last one). This is the
|
|
59
|
+
* top-level unit `gth history list` shows, in place of isolated per-turn rows.
|
|
60
|
+
*/
|
|
61
|
+
export interface ConversationSummary {
|
|
62
|
+
id: number;
|
|
63
|
+
/** When the conversation was opened. */
|
|
64
|
+
startedTs: string;
|
|
65
|
+
project?: string;
|
|
66
|
+
command?: string;
|
|
67
|
+
model?: string;
|
|
68
|
+
/** Number of turns recorded under this conversation (0 for a conversation with no turns). */
|
|
69
|
+
turnCount: number;
|
|
70
|
+
/** Timestamp of the first / last turn, when any turns exist. */
|
|
71
|
+
firstTs?: string;
|
|
72
|
+
lastTs?: string;
|
|
73
|
+
/** Prompt / response of the most recent turn (a one-line preview source). */
|
|
74
|
+
lastPrompt?: string;
|
|
75
|
+
lastResponse?: string;
|
|
76
|
+
}
|
|
77
|
+
/** Aggregate analytics over the whole store (local only). */
|
|
78
|
+
export interface HistoryInsights {
|
|
79
|
+
sessionCount: number;
|
|
80
|
+
totalTokensInput: number;
|
|
81
|
+
totalTokensOutput: number;
|
|
82
|
+
totalTokens: number;
|
|
83
|
+
totalCostUsd: number;
|
|
84
|
+
/** Tool-name → invocation count, most-used first. */
|
|
85
|
+
topTools: {
|
|
86
|
+
tool: string;
|
|
87
|
+
count: number;
|
|
88
|
+
}[];
|
|
89
|
+
/** Command → run count, most-used first. */
|
|
90
|
+
perCommand: {
|
|
91
|
+
command: string;
|
|
92
|
+
count: number;
|
|
93
|
+
}[];
|
|
94
|
+
firstTs?: string;
|
|
95
|
+
lastTs?: string;
|
|
96
|
+
}
|
|
97
|
+
/** Options for opening a store. */
|
|
98
|
+
export interface OpenHistoryStoreOptions {
|
|
99
|
+
/**
|
|
100
|
+
* When false (the default for read-only callers), a missing DB file yields `null` instead of
|
|
101
|
+
* creating an empty database. Read commands pass `create: false` so `gth insights` never
|
|
102
|
+
* materialises a DB as a side effect; the recorder passes `create: true`.
|
|
103
|
+
*/
|
|
104
|
+
create?: boolean;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Turn arbitrary user text into a safe FTS5 MATCH expression: each whitespace-separated token is
|
|
108
|
+
* wrapped as a quoted string and AND-ed together. This avoids FTS5 syntax errors from stray
|
|
109
|
+
* operators (`AND`, `*`, `:`, parentheses, unbalanced quotes) in a user's query while still
|
|
110
|
+
* matching all of their words.
|
|
111
|
+
*/
|
|
112
|
+
export declare function toFtsMatchQuery(query: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* A thin, fail-soft wrapper over a `node:sqlite` connection holding the session history.
|
|
115
|
+
*
|
|
116
|
+
* Obtain one via {@link openHistoryStore} (which returns `null` if the DB can't be opened). Every
|
|
117
|
+
* method is defensive: on any SQLite error it returns a safe empty/zero result rather than
|
|
118
|
+
* throwing, so callers on a run's hot path never have to guard.
|
|
119
|
+
*/
|
|
120
|
+
export declare class HistoryStore {
|
|
121
|
+
private db;
|
|
122
|
+
private constructor();
|
|
123
|
+
/**
|
|
124
|
+
* Open (and lazily initialise) the store at `dbPath`. Returns `null` on any failure — a missing
|
|
125
|
+
* file when `create` is false, an unopenable/locked/corrupt DB, or a schema-init error — so the
|
|
126
|
+
* caller can simply skip history without a try/catch.
|
|
127
|
+
*/
|
|
128
|
+
static open(dbPath: string, options?: OpenHistoryStoreOptions): HistoryStore | null;
|
|
129
|
+
private initSchema;
|
|
130
|
+
/**
|
|
131
|
+
* GS2-19 — in-place, idempotent upgrade of a pre-existing GS2-7 DB (flat `sessions` rows, no
|
|
132
|
+
* grouping) to the conversation-grained model. Runs on every open (including read-only `list` /
|
|
133
|
+
* `search` opens, which open the file read-write): it adds the `conversation_id` column if an
|
|
134
|
+
* older `sessions` table lacks it, then back-fills each ungrouped turn into its own 1-turn
|
|
135
|
+
* conversation. After the first pass there are no ungrouped rows, so it is a cheap no-op.
|
|
136
|
+
*
|
|
137
|
+
* Fully fail-soft: a migration hiccup is swallowed here rather than nulling the store, so reads
|
|
138
|
+
* still work against whatever is already there and new turns just fall back to fresh 1-turn
|
|
139
|
+
* conversations. Never throws.
|
|
140
|
+
*/
|
|
141
|
+
private migrate;
|
|
142
|
+
/**
|
|
143
|
+
* GS2-19 — open a new conversation and return its id (or `null` on any error). Interactive
|
|
144
|
+
* sessions call this once at start, then pass the id on every {@link record} so all the session's
|
|
145
|
+
* turns group under it. A single-shot run does not need this: {@link record} opens a 1-turn
|
|
146
|
+
* conversation itself when no `conversationId` is supplied.
|
|
147
|
+
*/
|
|
148
|
+
openConversation(meta?: ConversationMeta): number | null;
|
|
149
|
+
/**
|
|
150
|
+
* Persist one session and its full-text index entry. Returns the new row id, or `null` on any
|
|
151
|
+
* error (the run continues regardless). The two inserts run in a transaction so a failure can't
|
|
152
|
+
* leave the FTS index out of sync with the base table.
|
|
153
|
+
*/
|
|
154
|
+
record(rec: SessionRecord): number | null;
|
|
155
|
+
/**
|
|
156
|
+
* Full-text search over prompt/response/command/project, best match first (FTS5 `rank`). User
|
|
157
|
+
* text is sanitised via {@link toFtsMatchQuery}; an empty or all-punctuation query returns `[]`.
|
|
158
|
+
* Any SQLite error yields `[]` (fail-soft).
|
|
159
|
+
*/
|
|
160
|
+
search(query: string, limit?: number): SessionSearchResult[];
|
|
161
|
+
/** Most recent sessions, newest first. Fail-soft ([] on error). */
|
|
162
|
+
listRecent(limit?: number): SessionSearchResult[];
|
|
163
|
+
/**
|
|
164
|
+
* GS2-19 — conversations newest-first, each with its turn count, timespan, and a preview of the
|
|
165
|
+
* last turn. This is the top-level unit for `gth history list` (the turn-grained {@link listRecent}
|
|
166
|
+
* remains for callers that want raw turns). Fail-soft ([] on error).
|
|
167
|
+
*
|
|
168
|
+
* Empty conversations are **excluded** (`HAVING COUNT(s.id) > 0`): a session opens its conversation
|
|
169
|
+
* at start (before any turn), so one that exits with zero turns would otherwise show as a
|
|
170
|
+
* contentless `turnCount: 0` row. The LEFT JOIN still keeps every conversation that has ≥1 turn —
|
|
171
|
+
* including back-filled 1-turn conversations, whose single turn satisfies the HAVING.
|
|
172
|
+
*/
|
|
173
|
+
listConversations(limit?: number): ConversationSummary[];
|
|
174
|
+
/**
|
|
175
|
+
* GS2-19 — all turns of one conversation in chronological (insert) order, so a search hit can be
|
|
176
|
+
* expanded into the whole thread it belonged to. Fail-soft ([] on error / unknown id).
|
|
177
|
+
*/
|
|
178
|
+
getConversationThread(conversationId: number): SessionRecord[];
|
|
179
|
+
/**
|
|
180
|
+
* Aggregate token/cost totals, a top-tool tally, and a per-command breakdown over the whole
|
|
181
|
+
* store. Tool tallying reads each row's JSON `tools` array in JS (robust to nulls). Fail-soft:
|
|
182
|
+
* returns a zeroed summary on any error.
|
|
183
|
+
*/
|
|
184
|
+
insights(topN?: number): HistoryInsights;
|
|
185
|
+
/** Close the underlying connection (fail-soft). */
|
|
186
|
+
close(): void;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Resolve the on-disk path of the history DB. Honors an explicit `dbPath` (from `history.dbPath`
|
|
190
|
+
* or a `--db` flag); otherwise the global `~/.gsloth/history.db`. When `dbPath` is omitted and
|
|
191
|
+
* `ensureDir` is true, the global dir is created so the recorder can write.
|
|
192
|
+
*/
|
|
193
|
+
export declare function resolveHistoryDbPath(dbPath?: string, ensureDir?: boolean): string;
|
|
194
|
+
/**
|
|
195
|
+
* Fail-soft open of the history store. Returns `null` (never throws) when the DB can't be opened
|
|
196
|
+
* or, for read-only callers (`create: false`, the default), when the file does not yet exist.
|
|
197
|
+
*/
|
|
198
|
+
export declare function openHistoryStore(dbPath: string, options?: OpenHistoryStoreOptions): HistoryStore | null;
|