@gaunt-sloth/core 2.0.0-alpha.8 → 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
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module displayWidth
|
|
3
|
+
* The one place this repo answers "how many terminal COLUMNS does this string occupy, and where
|
|
4
|
+
* may I cut it". Everything that fits text to a terminal — the launch banner's field budgets, the
|
|
5
|
+
* tool-display caps — measures and slices through here.
|
|
6
|
+
*
|
|
7
|
+
* ## Why a code-point count is not a width
|
|
8
|
+
*
|
|
9
|
+
* `[...text].length` counts code points, which is right for UTF-16 safety and wrong for layout: a
|
|
10
|
+
* CJK ideograph or an emoji is ONE code point occupying TWO columns. Text measured that way reads
|
|
11
|
+
* as shorter than it renders, escapes whatever budget it was given, and wraps — and a wrapped
|
|
12
|
+
* continuation line starts back at column 0, which is precisely the failure the budgets exist to
|
|
13
|
+
* prevent. So the rule is: a value destined for a fixed column budget is measured with
|
|
14
|
+
* {@link displayWidth} and cut with {@link sliceToWidth} / {@link sliceEndToWidth}, never with
|
|
15
|
+
* `.length`, a spread, or `String.prototype.slice`.
|
|
16
|
+
*
|
|
17
|
+
* ## Why grapheme clusters are the cutting unit
|
|
18
|
+
*
|
|
19
|
+
* Slicing by code point is safe against halving a surrogate pair but not against halving a
|
|
20
|
+
* CLUSTER: a flag, a skin-toned or ZWJ-joined emoji, or a base letter plus its combining mark are
|
|
21
|
+
* several code points that a terminal draws as one glyph, and cutting between them produces
|
|
22
|
+
* mojibake or an orphaned mark. `Intl.Segmenter` gives the same cluster boundaries the width
|
|
23
|
+
* rules below are defined over, so the two agree by construction and a sliced string's width is
|
|
24
|
+
* exactly the sum of the widths of the clusters kept.
|
|
25
|
+
*
|
|
26
|
+
* ## What the slices expect: PLAIN text
|
|
27
|
+
*
|
|
28
|
+
* {@link displayWidth} is ANSI-aware and the slices are NOT, and that asymmetry is a contract
|
|
29
|
+
* rather than an oversight. An escape sequence is not one cluster — the terminal swallows it
|
|
30
|
+
* whole, but `ESC`, `[`, `3`, `5`, `m` segment as five, four of them printable — so the two
|
|
31
|
+
* disagree on an escape-bearing string and a slice can both under-fill its budget and cut inside
|
|
32
|
+
* a sequence. Feed the slices the text a user will read, and colour it afterwards; that is what
|
|
33
|
+
* every caller here does, since both render surfaces map a style tag to their own escapes at the
|
|
34
|
+
* very end. Making the slices ANSI-aware would change what a coloured preview line renders as,
|
|
35
|
+
* which is a decision for whoever needs it and not a silent detail of this module.
|
|
36
|
+
*
|
|
37
|
+
* That asymmetry is also why a slice decides "does the whole string fit?" two different ways. For
|
|
38
|
+
* plain text the cluster walk decides it: the widths of the clusters sum to the width of the
|
|
39
|
+
* string, so walking until the budget is blown answers the question and answers it WITHOUT
|
|
40
|
+
* touching the rest of the input — which is what keeps a megabyte-long preview line from being
|
|
41
|
+
* measured end to end before it is cut at column 200. Only escape-bearing text is measured whole
|
|
42
|
+
* first, because there the two rulers disagree and a coloured string that MEASURES as fitting must
|
|
43
|
+
* be handed back whole rather than cut short by the bytes of its own escapes.
|
|
44
|
+
*
|
|
45
|
+
* ## Why ambiguous-width characters stay NARROW — and the one place they must not
|
|
46
|
+
*
|
|
47
|
+
* `string-width` defaults to treating East-Asian "Ambiguous" characters as one column, and that
|
|
48
|
+
* default is load-bearing here rather than incidental: the sloth face is block elements, the
|
|
49
|
+
* wordmark is box-drawing, and `…` is U+2026 — all Ambiguous. Counting them as two columns would
|
|
50
|
+
* measure the 16-column face at 32 and shatter the layout it anchors. So {@link displayWidth} and
|
|
51
|
+
* {@link sliceToWidth} keep the default, and the specs pin the face at 16 and the wordmark at 19 so
|
|
52
|
+
* a change of that policy fails loudly instead of quietly doubling the art.
|
|
53
|
+
*
|
|
54
|
+
* That default is an **assumption about the reader's terminal**, and it is one this process cannot
|
|
55
|
+
* check: an Ambiguous character occupies one cell or two depending on how the terminal is
|
|
56
|
+
* configured, and several CJK locales — plus an option in xterm, urxvt and mlterm — choose two.
|
|
57
|
+
* For layout art that assumption is free, because being wrong only makes the art look wrong.
|
|
58
|
+
*
|
|
59
|
+
* It is **not** free where a budget is a security boundary. {@link maxDisplayWidth} and
|
|
60
|
+
* {@link sliceToMaxWidth} are the sanctioned exception: they measure Ambiguous as **two** columns,
|
|
61
|
+
* i.e. the widest a terminal can render the string, so text fitted with them fits under *either*
|
|
62
|
+
* policy. Use them wherever a row that overruns its budget would be wrapped by the terminal into a
|
|
63
|
+
* consequence rather than into an untidy screen — `core/shell/framing` frames untrusted text this
|
|
64
|
+
* way, because there a wrapped continuation line starts at column 0 and can forge a dialog's chrome.
|
|
65
|
+
* The cost is under-fill: on a terminal that does render Ambiguous narrow, such a row can stop short
|
|
66
|
+
* of its budget. Under-fill is cosmetic; overrun is not. True Wide characters (CJK ideographs,
|
|
67
|
+
* emoji, fullwidth forms) measure 2 under both, so the common CJK case is unaffected either way.
|
|
68
|
+
*/
|
|
69
|
+
import stringWidth from 'string-width';
|
|
70
|
+
/**
|
|
71
|
+
* Grapheme-cluster boundaries, i.e. what a terminal draws as one glyph. Built once: constructing
|
|
72
|
+
* an `Intl.Segmenter` is expensive relative to the short strings this module handles.
|
|
73
|
+
*/
|
|
74
|
+
const GRAPHEME_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
75
|
+
/**
|
|
76
|
+
* Terminal columns `text` occupies. Zero-width clusters (combining marks, default-ignorables)
|
|
77
|
+
* count 0, wide clusters (CJK, emoji, fullwidth forms) count 2, everything else 1. ANSI escape
|
|
78
|
+
* sequences are not counted, so a pre-coloured string measures as what the user sees — but the
|
|
79
|
+
* slices below do not share that awareness, so do not read this as a licence to feed them one.
|
|
80
|
+
*/
|
|
81
|
+
export function displayWidth(text) {
|
|
82
|
+
return stringWidth(text);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Terminal columns `text` occupies **at most** — the same measurement as {@link displayWidth} but
|
|
86
|
+
* counting East-Asian Ambiguous characters as two columns rather than one, which is the widest any
|
|
87
|
+
* terminal will render them.
|
|
88
|
+
*
|
|
89
|
+
* For a budget that must hold on a terminal whose ambiguous-width policy is unknown, this is the
|
|
90
|
+
* only sound ruler: it is the supremum over the policies a terminal can be configured with, so a
|
|
91
|
+
* string that fits under it fits under all of them. See the module docblock for when to reach for
|
|
92
|
+
* this rather than {@link displayWidth}.
|
|
93
|
+
*/
|
|
94
|
+
export function maxDisplayWidth(text) {
|
|
95
|
+
return stringWidth(text, { ambiguousIsNarrow: false });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The first grapheme cluster of `text`, or `''` when it is empty — i.e. the smallest piece a cut
|
|
99
|
+
* can leave behind, for a caller that has to make progress through a string one drawable glyph at
|
|
100
|
+
* a time.
|
|
101
|
+
*/
|
|
102
|
+
export function firstCluster(text) {
|
|
103
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(text))
|
|
104
|
+
return segment;
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
/** The clusters of `text`, in order — the only unit either slice is allowed to cut between. */
|
|
108
|
+
function clusters(text) {
|
|
109
|
+
const out = [];
|
|
110
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(text))
|
|
111
|
+
out.push(segment);
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Whether the whole-string measurement is the only ruler that can answer "does this fit" for
|
|
116
|
+
* `text` — true exactly when it carries an escape introducer (`ESC`, or the one-byte `CSI`), the
|
|
117
|
+
* two characters `string-width` itself strips on. On anything else the cluster widths sum to the
|
|
118
|
+
* whole-string width, so the walk decides the same question incrementally and a pre-measurement
|
|
119
|
+
* would be a second full pass over the input for nothing.
|
|
120
|
+
*/
|
|
121
|
+
function needsWholeStringMeasure(text) {
|
|
122
|
+
return text.includes('\u001B') || text.includes('\u009B');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The longest LEADING run of whole clusters whose total width is at most `maxWidth` — i.e. keep
|
|
126
|
+
* the head, lose the tail. Total (never throws): a non-positive `maxWidth` yields `''`.
|
|
127
|
+
*
|
|
128
|
+
* A cluster is kept only if it fits ENTIRELY, so the result can come back one column short of
|
|
129
|
+
* `maxWidth` when the next cluster is two columns wide. That is the point: half a wide glyph
|
|
130
|
+
* cannot be drawn, and spending the column anyway is how text over-runs its budget.
|
|
131
|
+
*
|
|
132
|
+
* The clusters are produced one at a time and the walk stops at the budget, so the cost is the
|
|
133
|
+
* length of the RESULT rather than the length of the input — the input here is a whole tool-output
|
|
134
|
+
* line, which is unbounded.
|
|
135
|
+
*/
|
|
136
|
+
export function sliceToWidth(text, maxWidth) {
|
|
137
|
+
return sliceHeadToWidth(text, maxWidth, displayWidth);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* {@link sliceToWidth} measured by {@link maxDisplayWidth} — the head that fits the budget on any
|
|
141
|
+
* terminal, whatever it does with Ambiguous characters. The cut for a budget that must hold rather
|
|
142
|
+
* than merely look right.
|
|
143
|
+
*/
|
|
144
|
+
export function sliceToMaxWidth(text, maxWidth) {
|
|
145
|
+
return sliceHeadToWidth(text, maxWidth, maxDisplayWidth);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The head-slice both public cuts are made of, given the ruler to measure with. The ruler is passed
|
|
149
|
+
* rather than chosen here so the whole-string shortcut and the cluster walk can never end up on
|
|
150
|
+
* different ones — measuring the shortcut narrow and the walk wide would hand back a string that
|
|
151
|
+
* overruns the very budget the caller asked to be held to.
|
|
152
|
+
*/
|
|
153
|
+
function sliceHeadToWidth(text, maxWidth, measure) {
|
|
154
|
+
if (maxWidth <= 0)
|
|
155
|
+
return '';
|
|
156
|
+
if (needsWholeStringMeasure(text) && measure(text) <= maxWidth)
|
|
157
|
+
return text;
|
|
158
|
+
let width = 0;
|
|
159
|
+
let kept = '';
|
|
160
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(text)) {
|
|
161
|
+
const clusterWidth = measure(segment);
|
|
162
|
+
if (width + clusterWidth > maxWidth)
|
|
163
|
+
break;
|
|
164
|
+
width += clusterWidth;
|
|
165
|
+
kept += segment;
|
|
166
|
+
}
|
|
167
|
+
return kept;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The longest TRAILING run of whole clusters whose total width is at most `maxWidth` — i.e. keep
|
|
171
|
+
* the tail, lose the head. The mirror of {@link sliceToWidth}, for values whose end is the
|
|
172
|
+
* informative part (a path's leaf directory).
|
|
173
|
+
*
|
|
174
|
+
* This one materialises the clusters: it walks backwards, and cluster boundaries are only
|
|
175
|
+
* derivable from the front. Its callers pass a path or a model id, so the input is a line rather
|
|
176
|
+
* than a file.
|
|
177
|
+
*/
|
|
178
|
+
export function sliceEndToWidth(text, maxWidth) {
|
|
179
|
+
if (maxWidth <= 0)
|
|
180
|
+
return '';
|
|
181
|
+
if (needsWholeStringMeasure(text) && displayWidth(text) <= maxWidth)
|
|
182
|
+
return text;
|
|
183
|
+
const all = clusters(text);
|
|
184
|
+
let width = 0;
|
|
185
|
+
let kept = '';
|
|
186
|
+
for (let index = all.length - 1; index >= 0; index--) {
|
|
187
|
+
const clusterWidth = displayWidth(all[index]);
|
|
188
|
+
if (width + clusterWidth > maxWidth)
|
|
189
|
+
break;
|
|
190
|
+
width += clusterWidth;
|
|
191
|
+
kept = all[index] + kept;
|
|
192
|
+
}
|
|
193
|
+
return kept;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=displayWidth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayWidth.js","sourceRoot":"","sources":["../../src/utils/displayWidth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileUtils.js","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"fileUtils.js","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,17 +9,29 @@ export declare function getGlobalGslothDir(): string;
|
|
|
9
9
|
* @returns The resolved path to the global .gsloth directory
|
|
10
10
|
*/
|
|
11
11
|
export declare function ensureGlobalGslothDir(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Composes the path a global config file would occupy inside an ARBITRARY global dir:
|
|
14
|
+
* `<globalDir>/<filename>`, or `<globalDir>/.gsloth-settings/<identityProfile>/<filename>` when a
|
|
15
|
+
* profile is named. Split out of {@link getGlobalGslothConfigReadPath} so the dir and the
|
|
16
|
+
* profile-segment rule are separable — a caller (or a test seam) that must substitute the global
|
|
17
|
+
* dir gets the real composition rule instead of reimplementing it and drifting from it.
|
|
18
|
+
*
|
|
19
|
+
* A blank/whitespace-only profile name counts as "no profile".
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveGlobalConfigPath(globalDir: string, filename: string, identityProfileRaw?: string): string;
|
|
12
22
|
/**
|
|
13
23
|
* Gets the read path for a global gsloth config file (e.g. `.gsloth.config.json`)
|
|
14
|
-
* inside the global `~/.gsloth` directory
|
|
24
|
+
* inside the global `~/.gsloth` directory (or `~/.gsloth/.gsloth-settings/<identityProfile>/`).
|
|
25
|
+
* Reuses the same global folder as MCP auth.
|
|
15
26
|
*
|
|
16
27
|
* This is a plain path resolver: it does NOT check for existence and does NOT create
|
|
17
28
|
* the directory. Callers should guard with `existsSync` before reading.
|
|
18
29
|
*
|
|
19
30
|
* @param filename The configuration filename (e.g. `.gsloth.config.json`)
|
|
31
|
+
* @param identityProfileRaw Optional identity profile subdirectory name within `.gsloth-settings`
|
|
20
32
|
* @returns The resolved path where the global configuration file would live
|
|
21
33
|
*/
|
|
22
|
-
export declare function getGlobalGslothConfigReadPath(filename: string): string;
|
|
34
|
+
export declare function getGlobalGslothConfigReadPath(filename: string, identityProfileRaw?: string): string;
|
|
23
35
|
/**
|
|
24
36
|
* Gets the write path for a global gsloth config file (e.g. `.gsloth.config.json`)
|
|
25
37
|
* inside the global `~/.gsloth` directory, ensuring the directory exists.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
|
-
import { GSLOTH_DIR, GSLOTH_AUTH } from '#src/constants.js';
|
|
4
|
+
import { GSLOTH_DIR, GSLOTH_SETTINGS_DIR, GSLOTH_AUTH } from '#src/constants.js';
|
|
5
5
|
/**
|
|
6
6
|
* Gets the global .gsloth directory path in the user's home directory
|
|
7
7
|
* @returns The resolved path to the global .gsloth directory
|
|
@@ -21,18 +21,36 @@ export function ensureGlobalGslothDir() {
|
|
|
21
21
|
}
|
|
22
22
|
return globalDir;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Composes the path a global config file would occupy inside an ARBITRARY global dir:
|
|
26
|
+
* `<globalDir>/<filename>`, or `<globalDir>/.gsloth-settings/<identityProfile>/<filename>` when a
|
|
27
|
+
* profile is named. Split out of {@link getGlobalGslothConfigReadPath} so the dir and the
|
|
28
|
+
* profile-segment rule are separable — a caller (or a test seam) that must substitute the global
|
|
29
|
+
* dir gets the real composition rule instead of reimplementing it and drifting from it.
|
|
30
|
+
*
|
|
31
|
+
* A blank/whitespace-only profile name counts as "no profile".
|
|
32
|
+
*/
|
|
33
|
+
export function resolveGlobalConfigPath(globalDir, filename, identityProfileRaw) {
|
|
34
|
+
const identityProfile = identityProfileRaw?.trim();
|
|
35
|
+
if (identityProfile) {
|
|
36
|
+
return resolve(globalDir, GSLOTH_SETTINGS_DIR, identityProfile, filename);
|
|
37
|
+
}
|
|
38
|
+
return resolve(globalDir, filename);
|
|
39
|
+
}
|
|
24
40
|
/**
|
|
25
41
|
* Gets the read path for a global gsloth config file (e.g. `.gsloth.config.json`)
|
|
26
|
-
* inside the global `~/.gsloth` directory
|
|
42
|
+
* inside the global `~/.gsloth` directory (or `~/.gsloth/.gsloth-settings/<identityProfile>/`).
|
|
43
|
+
* Reuses the same global folder as MCP auth.
|
|
27
44
|
*
|
|
28
45
|
* This is a plain path resolver: it does NOT check for existence and does NOT create
|
|
29
46
|
* the directory. Callers should guard with `existsSync` before reading.
|
|
30
47
|
*
|
|
31
48
|
* @param filename The configuration filename (e.g. `.gsloth.config.json`)
|
|
49
|
+
* @param identityProfileRaw Optional identity profile subdirectory name within `.gsloth-settings`
|
|
32
50
|
* @returns The resolved path where the global configuration file would live
|
|
33
51
|
*/
|
|
34
|
-
export function getGlobalGslothConfigReadPath(filename) {
|
|
35
|
-
return
|
|
52
|
+
export function getGlobalGslothConfigReadPath(filename, identityProfileRaw) {
|
|
53
|
+
return resolveGlobalConfigPath(getGlobalGslothDir(), filename, identityProfileRaw);
|
|
36
54
|
}
|
|
37
55
|
/**
|
|
38
56
|
* Gets the write path for a global gsloth config file (e.g. `.gsloth.config.json`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"globalConfigUtils.js","sourceRoot":"","sources":["../../src/utils/globalConfigUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"globalConfigUtils.js","sourceRoot":"","sources":["../../src/utils/globalConfigUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IAEvC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,SAAiB,EACjB,QAAgB,EAChB,kBAA2B;IAE3B,MAAM,eAAe,GAAG,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,OAAO,CAAC,SAAS,EAAE,mBAAmB,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAAgB,EAChB,kBAA2B;IAE3B,OAAO,uBAAuB,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC;AACrF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAAC,QAAgB;IAC7D,OAAO,OAAO,CAAC,qBAAqB,EAAE,EAAE,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,OAAO,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IACjC,uCAAuC;IACvC,qBAAqB,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IACtC,6CAA6C;IAC7C,MAAM,YAAY,GAAG,SAAS;SAC3B,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,WAAW,EAAE,CAAC;IAEjB,OAAO,OAAO,CAAC,OAAO,EAAE,GAAG,YAAY,OAAO,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/utils/llmUtils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
-
import { GthConfig } from '#src/config.js';
|
|
2
|
+
import { GthConfig, PromptSegmentName } from '#src/config.js';
|
|
3
|
+
import type { GthCommand } from '#src/core/types.js';
|
|
3
4
|
import { SystemMessage } from '@langchain/core/messages';
|
|
4
5
|
/**
|
|
5
6
|
* Creates new runnable config.
|
|
@@ -8,14 +9,43 @@ import { SystemMessage } from '@langchain/core/messages';
|
|
|
8
9
|
* and in another prototype project where I was importing Gaunt Sloth.
|
|
9
10
|
*/
|
|
10
11
|
export declare function getNewRunnableConfig(recursionLimit?: number): RunnableConfig;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
/** The config slice every prompt-segment read needs. */
|
|
13
|
+
type PromptReadConfig = Pick<GthConfig, 'prompts' | 'identityProfile' | 'noDefaultPrompts'>;
|
|
14
|
+
/**
|
|
15
|
+
* GS2-43 — the single composition point for one prompt segment, honouring the segment's
|
|
16
|
+
* `prompts.<segment>` config:
|
|
17
|
+
* - no setting → the segment's default-named file ({@link PROMPT_SEGMENT_FILES}), falling back
|
|
18
|
+
* to the bundled default unless `noDefaultPrompts` — exactly the pre-GS2-43 behaviour;
|
|
19
|
+
* - a `string` → shorthand for `{ path }`;
|
|
20
|
+
* - `enabled: false` → the segment is dropped entirely (returns `''`), even its bundled default;
|
|
21
|
+
* - `path` + `mode: 'replace'` (default) → the file replaces the built-in segment content;
|
|
22
|
+
* - `path` + `mode: 'append'` → the file content is appended after the built-in content.
|
|
23
|
+
*/
|
|
24
|
+
export declare function readPromptSegment(segment: PromptSegmentName, config: PromptReadConfig): string;
|
|
25
|
+
export declare function readBackstory(config: PromptReadConfig): string;
|
|
26
|
+
export declare function readGuidelines(config: Pick<GthConfig, 'prompts' | 'includeCurrentDateAfterGuidelines' | 'organization' | 'identityProfile' | 'noDefaultPrompts'> | string): string;
|
|
27
|
+
export declare function readReviewInstructions(config: PromptReadConfig | string): string;
|
|
28
|
+
export declare function readSystemPrompt(config: PromptReadConfig): string;
|
|
29
|
+
export declare function readChatPrompt(config: PromptReadConfig): string;
|
|
16
30
|
export declare function buildSystemMessages(config: GthConfig, modePrompt?: string | null): SystemMessage[];
|
|
17
|
-
export declare function readCodePrompt(config:
|
|
18
|
-
export declare function readExecPrompt(config:
|
|
31
|
+
export declare function readCodePrompt(config: PromptReadConfig): string;
|
|
32
|
+
export declare function readExecPrompt(config: PromptReadConfig): string;
|
|
33
|
+
/**
|
|
34
|
+
* GS2-79 — the SINGLE place a command's mode prompt is chosen, for every site that composes a
|
|
35
|
+
* system prompt via {@link buildSystemMessages}: both agent backends and the subagent profiles.
|
|
36
|
+
*
|
|
37
|
+
* It exists because the selection used to be an inline three-branch ternary copied to each of
|
|
38
|
+
* those sites, and a command missing from one copy is silently served the CHAT prompt — the
|
|
39
|
+
* default branch — rather than failing. That is how `review`/`pr` came to compose the chat prompt
|
|
40
|
+
* while the review instructions were smuggled in as a caller-side leading `SystemMessage`, which
|
|
41
|
+
* Anthropic rejects outright ("System messages are only permitted as the first passed message").
|
|
42
|
+
* One function means a new command is wired once, and `review`/`pr` cannot silently fall back to
|
|
43
|
+
* chat again.
|
|
44
|
+
*
|
|
45
|
+
* `review`/`pr` resolve to the REVIEW INSTRUCTIONS (`.gsloth.review.md`), which is what makes a
|
|
46
|
+
* review a review; every command without a mode prompt of its own keeps the chat prompt.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readModePrompt(command: GthCommand | undefined, config: PromptReadConfig): string;
|
|
19
49
|
/**
|
|
20
50
|
* Read a prompt file from the project config dir (honouring identity profiles), falling back
|
|
21
51
|
* to a packaged default unless `noDefaultPrompts` is set. Downstream packages owning their own
|
|
@@ -45,3 +75,4 @@ export declare function formatToolCalls(toolCalls: Array<{
|
|
|
45
75
|
name: string;
|
|
46
76
|
args?: Record<string, unknown>;
|
|
47
77
|
}>, maxLength?: number): string;
|
|
78
|
+
export {};
|
package/dist/utils/llmUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { GSLOTH_BACKSTORY, GSLOTH_CHAT_PROMPT, GSLOTH_CODE_PROMPT, GSLOTH_EXEC_PROMPT, GSLOTH_SYSTEM_PROMPT, } from '#src/constants.js';
|
|
2
|
+
import { GSLOTH_BACKSTORY, GSLOTH_CHAT_PROMPT, GSLOTH_CODE_PROMPT, GSLOTH_EXEC_PROMPT, GSLOTH_SYSTEM_PROMPT, PROJECT_GUIDELINES, PROJECT_REVIEW_INSTRUCTIONS, } from '#src/constants.js';
|
|
3
3
|
import { getGslothConfigReadPath, readFileFromInstallDir } from '#src/utils/fileUtils.js';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { debugLog } from '#src/utils/debugUtils.js';
|
|
@@ -17,14 +17,54 @@ export function getNewRunnableConfig(recursionLimit = 1000) {
|
|
|
17
17
|
configurable: { thread_id: randomUUID() },
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* GS2-43 — each prompt segment's default-named file. The `prompts.<segment>` config retargets,
|
|
22
|
+
* disables, or composes against these; with no config the segment resolves exactly as before
|
|
23
|
+
* (config-dir/project file of this name, else the bundled default).
|
|
24
|
+
*/
|
|
25
|
+
const PROMPT_SEGMENT_FILES = {
|
|
26
|
+
backstory: GSLOTH_BACKSTORY,
|
|
27
|
+
guidelines: PROJECT_GUIDELINES,
|
|
28
|
+
system: GSLOTH_SYSTEM_PROMPT,
|
|
29
|
+
chat: GSLOTH_CHAT_PROMPT,
|
|
30
|
+
code: GSLOTH_CODE_PROMPT,
|
|
31
|
+
exec: GSLOTH_EXEC_PROMPT,
|
|
32
|
+
review: PROJECT_REVIEW_INSTRUCTIONS,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* GS2-43 — the single composition point for one prompt segment, honouring the segment's
|
|
36
|
+
* `prompts.<segment>` config:
|
|
37
|
+
* - no setting → the segment's default-named file ({@link PROMPT_SEGMENT_FILES}), falling back
|
|
38
|
+
* to the bundled default unless `noDefaultPrompts` — exactly the pre-GS2-43 behaviour;
|
|
39
|
+
* - a `string` → shorthand for `{ path }`;
|
|
40
|
+
* - `enabled: false` → the segment is dropped entirely (returns `''`), even its bundled default;
|
|
41
|
+
* - `path` + `mode: 'replace'` (default) → the file replaces the built-in segment content;
|
|
42
|
+
* - `path` + `mode: 'append'` → the file content is appended after the built-in content.
|
|
43
|
+
*/
|
|
44
|
+
export function readPromptSegment(segment, config) {
|
|
45
|
+
const setting = config.prompts?.[segment];
|
|
46
|
+
const segmentConfig = typeof setting === 'string' ? { path: setting } : (setting ?? {});
|
|
47
|
+
if (segmentConfig.enabled === false) {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
const readBuiltIn = () => readPromptFile(PROMPT_SEGMENT_FILES[segment], config.identityProfile, config.noDefaultPrompts);
|
|
51
|
+
if (!segmentConfig.path) {
|
|
52
|
+
return readBuiltIn();
|
|
53
|
+
}
|
|
54
|
+
const fileContent = readPromptFile(segmentConfig.path, config.identityProfile, config.noDefaultPrompts);
|
|
55
|
+
if (segmentConfig.mode === 'append') {
|
|
56
|
+
return [readBuiltIn(), fileContent].filter(Boolean).join('\n');
|
|
57
|
+
}
|
|
58
|
+
return fileContent;
|
|
59
|
+
}
|
|
20
60
|
export function readBackstory(config) {
|
|
21
|
-
return
|
|
61
|
+
return readPromptSegment('backstory', config);
|
|
22
62
|
}
|
|
23
63
|
export function readGuidelines(config) {
|
|
24
64
|
if (typeof config === 'string') {
|
|
25
65
|
return readPromptFile(config, undefined);
|
|
26
66
|
}
|
|
27
|
-
const guidelines =
|
|
67
|
+
const guidelines = readPromptSegment('guidelines', config);
|
|
28
68
|
if (config.includeCurrentDateAfterGuidelines) {
|
|
29
69
|
const currentDate = new Date();
|
|
30
70
|
const orgName = config.organization?.name;
|
|
@@ -51,13 +91,13 @@ export function readReviewInstructions(config) {
|
|
|
51
91
|
if (typeof config === 'string') {
|
|
52
92
|
return readPromptFile(config, undefined);
|
|
53
93
|
}
|
|
54
|
-
return
|
|
94
|
+
return readPromptSegment('review', config);
|
|
55
95
|
}
|
|
56
96
|
export function readSystemPrompt(config) {
|
|
57
|
-
return
|
|
97
|
+
return readPromptSegment('system', config);
|
|
58
98
|
}
|
|
59
99
|
export function readChatPrompt(config) {
|
|
60
|
-
return
|
|
100
|
+
return readPromptSegment('chat', config);
|
|
61
101
|
}
|
|
62
102
|
export function buildSystemMessages(config, modePrompt) {
|
|
63
103
|
const parts = [readBackstory(config), readGuidelines(config)];
|
|
@@ -70,10 +110,38 @@ export function buildSystemMessages(config, modePrompt) {
|
|
|
70
110
|
return content.trim() ? [new SystemMessage(content)] : [];
|
|
71
111
|
}
|
|
72
112
|
export function readCodePrompt(config) {
|
|
73
|
-
return
|
|
113
|
+
return readPromptSegment('code', config);
|
|
74
114
|
}
|
|
75
115
|
export function readExecPrompt(config) {
|
|
76
|
-
return
|
|
116
|
+
return readPromptSegment('exec', config);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* GS2-79 — the SINGLE place a command's mode prompt is chosen, for every site that composes a
|
|
120
|
+
* system prompt via {@link buildSystemMessages}: both agent backends and the subagent profiles.
|
|
121
|
+
*
|
|
122
|
+
* It exists because the selection used to be an inline three-branch ternary copied to each of
|
|
123
|
+
* those sites, and a command missing from one copy is silently served the CHAT prompt — the
|
|
124
|
+
* default branch — rather than failing. That is how `review`/`pr` came to compose the chat prompt
|
|
125
|
+
* while the review instructions were smuggled in as a caller-side leading `SystemMessage`, which
|
|
126
|
+
* Anthropic rejects outright ("System messages are only permitted as the first passed message").
|
|
127
|
+
* One function means a new command is wired once, and `review`/`pr` cannot silently fall back to
|
|
128
|
+
* chat again.
|
|
129
|
+
*
|
|
130
|
+
* `review`/`pr` resolve to the REVIEW INSTRUCTIONS (`.gsloth.review.md`), which is what makes a
|
|
131
|
+
* review a review; every command without a mode prompt of its own keeps the chat prompt.
|
|
132
|
+
*/
|
|
133
|
+
export function readModePrompt(command, config) {
|
|
134
|
+
switch (command) {
|
|
135
|
+
case 'code':
|
|
136
|
+
return readCodePrompt(config);
|
|
137
|
+
case 'exec':
|
|
138
|
+
return readExecPrompt(config);
|
|
139
|
+
case 'review':
|
|
140
|
+
case 'pr':
|
|
141
|
+
return readReviewInstructions(config);
|
|
142
|
+
default:
|
|
143
|
+
return readChatPrompt(config);
|
|
144
|
+
}
|
|
77
145
|
}
|
|
78
146
|
/**
|
|
79
147
|
* Read a prompt file from the project config dir (honouring identity profiles), falling back
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../../src/utils/llmUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../../src/utils/llmUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* GS2-47 — a shared, reusable secret-redaction pass for diagnostic output.
|
|
4
|
+
*
|
|
5
|
+
* Built for `/debug-dump` ({@link file://./debugDump.ts}) but deliberately generic and
|
|
6
|
+
* dependency-free — it takes `env` as a PARAMETER rather than reading `process.env`, so the pass is
|
|
7
|
+
* pure, deterministic in tests, and reusable by GS2-48's crash-report handler (which hard-depends on
|
|
8
|
+
* this module). Nothing here reads ambient process state.
|
|
9
|
+
*
|
|
10
|
+
* DESIGN DECISION (settled by the coordinator, GS2-47): **PATTERN-ONLY** redaction — we do NOT scan
|
|
11
|
+
* for high-entropy strings. Rationale: pattern-only is safe to reason about and near-zero
|
|
12
|
+
* false-positive; entropy scanning catches marginally more but produces false-positive redactions
|
|
13
|
+
* the user has to squint through, degrading the dump's debug value. A high-entropy scanner is a
|
|
14
|
+
* DELIBERATELY-DEFERRED option (a config surface for it could be added later if ever warranted) and
|
|
15
|
+
* is intentionally NOT implemented here.
|
|
16
|
+
*
|
|
17
|
+
* Three techniques, in priority order:
|
|
18
|
+
* 1. [load-bearing] Known-secret VALUE substitution — collect the literal values of secret-named
|
|
19
|
+
* env vars + inline config secrets, then substitute every occurrence across ALL artifacts. This
|
|
20
|
+
* catches a leaked key wherever it surfaces (config, env, transcript, log) with no guessing.
|
|
21
|
+
* 2. Provider key/token PATTERNS — a tight, documented, prefix-anchored set of well-known key
|
|
22
|
+
* shapes plus explicit auth-header contexts. We never blanket-redact long alphanumeric strings.
|
|
23
|
+
* 3. Sensitive config-FIELD masking — mask the VALUES of secret-named config keys while preserving
|
|
24
|
+
* structure (the key stays; only the value becomes the marker).
|
|
25
|
+
*
|
|
26
|
+
* Fail-safe throughout: on any internal error the functions redact MORE (return the marker), never
|
|
27
|
+
* less — a redaction hiccup must never cause raw content to be emitted.
|
|
28
|
+
*/
|
|
29
|
+
/** The visible, greppable placeholder substituted for every redacted secret value. */
|
|
30
|
+
export declare const REDACTED = "<redacted>";
|
|
31
|
+
/**
|
|
32
|
+
* Collect the literal secret VALUES to substitute everywhere (technique 1), from two sources:
|
|
33
|
+
* - process-env vars whose NAME matches {@link SECRET_ENV_NAME_RE}, PLUS the specific var(s) named
|
|
34
|
+
* by any `apiKeyEnvironmentVariable` in the config;
|
|
35
|
+
* - non-empty inline secret field values in the config (technique 3's field names), so a key pasted
|
|
36
|
+
* inline is scrubbed wherever it *also* surfaces (transcript, log, env), not only in config.json.
|
|
37
|
+
*
|
|
38
|
+
* `env` is a PARAMETER — never read ambiently — so the pass is pure, reusable (GS2-48) and
|
|
39
|
+
* deterministic in tests. Values shorter than {@link MIN_SECRET_LITERAL_LENGTH} are skipped. The
|
|
40
|
+
* result is returned longest-first so an overlapping-substring secret can't leave a shorter one
|
|
41
|
+
* partially intact. Never throws (a hostile config getter is swallowed — patterns + structural
|
|
42
|
+
* masking still apply).
|
|
43
|
+
*/
|
|
44
|
+
export declare function collectSecretValues(config: unknown, env: Record<string, string | undefined>): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Redact a STRING: substitute every known literal secret value (technique 1, longest-first), then
|
|
47
|
+
* apply the provider key/auth patterns (technique 2). Never throws — on any error it returns the
|
|
48
|
+
* fully-withheld marker (fail safe: redact MORE, never emit the raw text). Applying it twice is
|
|
49
|
+
* safe (re-redacting already-redacted text is a no-op).
|
|
50
|
+
*/
|
|
51
|
+
export declare function redactText(text: string, secrets: readonly string[]): string;
|
|
52
|
+
/**
|
|
53
|
+
* Deep-redact an arbitrary value for serialization: mask the VALUES of secret-named fields
|
|
54
|
+
* (technique 3 — structure preserved: the key stays, only its value becomes the marker) and run
|
|
55
|
+
* {@link redactText} over every string leaf (techniques 1 + 2). Circular refs are broken; functions
|
|
56
|
+
* and bigints are rendered the way `safeStringify` would, so the result is JSON-safe. Pure — never
|
|
57
|
+
* mutates the input. `apiKeyEnvironmentVariable` is intentionally NOT masked (it is a var name).
|
|
58
|
+
*
|
|
59
|
+
* Intended for the CONFIG artifact (where field-name masking is wanted). Non-config artifacts use
|
|
60
|
+
* {@link redactText} over their stringified form instead (literal + pattern only), so a legitimate
|
|
61
|
+
* `token`/`secret`-named field in tool output is not blanket-masked.
|
|
62
|
+
*/
|
|
63
|
+
export declare function redactValue(value: unknown, secrets: readonly string[]): unknown;
|