@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.
Files changed (271) hide show
  1. package/README.md +52 -20
  2. package/dist/config/colour.d.ts +38 -0
  3. package/dist/config/colour.js +36 -0
  4. package/dist/config/colour.js.map +1 -0
  5. package/dist/config/defaults.d.ts +84 -0
  6. package/dist/config/defaults.js +99 -0
  7. package/dist/config/defaults.js.map +1 -0
  8. package/dist/config/filesystem-tools.d.ts +41 -0
  9. package/dist/config/filesystem-tools.js +56 -0
  10. package/dist/config/filesystem-tools.js.map +1 -0
  11. package/dist/config/jsonc.d.ts +12 -0
  12. package/dist/config/jsonc.js +41 -0
  13. package/dist/config/jsonc.js.map +1 -0
  14. package/dist/config/loader.d.ts +246 -0
  15. package/dist/config/loader.js +1321 -0
  16. package/dist/config/loader.js.map +1 -0
  17. package/dist/config/mouse.d.ts +50 -0
  18. package/dist/config/mouse.js +44 -0
  19. package/dist/config/mouse.js.map +1 -0
  20. package/dist/config/profiles.d.ts +68 -0
  21. package/dist/config/profiles.js +93 -0
  22. package/dist/config/profiles.js.map +1 -0
  23. package/dist/config/providerKeys.d.ts +69 -0
  24. package/dist/config/providerKeys.js +69 -0
  25. package/dist/config/providerKeys.js.map +1 -0
  26. package/dist/config/schema.d.ts +2999 -0
  27. package/dist/config/schema.js +1519 -0
  28. package/dist/config/schema.js.map +1 -0
  29. package/dist/config/shell-policy.d.ts +896 -0
  30. package/dist/config/shell-policy.js +750 -0
  31. package/dist/config/shell-policy.js.map +1 -0
  32. package/dist/config/tool-descriptions.d.ts +211 -0
  33. package/dist/config/tool-descriptions.js +272 -0
  34. package/dist/config/tool-descriptions.js.map +1 -0
  35. package/dist/config/types.d.ts +760 -0
  36. package/dist/config/types.js +13 -0
  37. package/dist/config/types.js.map +1 -0
  38. package/dist/config.d.ts +34 -827
  39. package/dist/config.js +25 -657
  40. package/dist/config.js.map +1 -1
  41. package/dist/constants.d.ts +46 -0
  42. package/dist/constants.js +46 -0
  43. package/dist/constants.js.map +1 -1
  44. package/dist/core/GthAbstractAgent.d.ts +135 -2
  45. package/dist/core/GthAbstractAgent.js +496 -30
  46. package/dist/core/GthAbstractAgent.js.map +1 -1
  47. package/dist/core/GthAgentRunner.d.ts +568 -54
  48. package/dist/core/GthAgentRunner.js +1537 -136
  49. package/dist/core/GthAgentRunner.js.map +1 -1
  50. package/dist/core/GthLangChainAgent.d.ts +115 -0
  51. package/dist/core/GthLangChainAgent.js +644 -17
  52. package/dist/core/GthLangChainAgent.js.map +1 -1
  53. package/dist/core/approvals/annotations.d.ts +122 -0
  54. package/dist/core/approvals/annotations.js +137 -0
  55. package/dist/core/approvals/annotations.js.map +1 -0
  56. package/dist/core/approvals/grants.d.ts +216 -0
  57. package/dist/core/approvals/grants.js +469 -0
  58. package/dist/core/approvals/grants.js.map +1 -0
  59. package/dist/core/approvals/matcher.d.ts +202 -0
  60. package/dist/core/approvals/matcher.js +267 -0
  61. package/dist/core/approvals/matcher.js.map +1 -0
  62. package/dist/core/approvals/mcpSubjects.d.ts +40 -0
  63. package/dist/core/approvals/mcpSubjects.js +99 -0
  64. package/dist/core/approvals/mcpSubjects.js.map +1 -0
  65. package/dist/core/approvals/toolAnnotationSources.d.ts +105 -0
  66. package/dist/core/approvals/toolAnnotationSources.js +277 -0
  67. package/dist/core/approvals/toolAnnotationSources.js.map +1 -0
  68. package/dist/core/approvals/toolHost.d.ts +46 -0
  69. package/dist/core/approvals/toolHost.js +108 -0
  70. package/dist/core/approvals/toolHost.js.map +1 -0
  71. package/dist/core/debugCapture.d.ts +75 -0
  72. package/dist/core/debugCapture.js +101 -0
  73. package/dist/core/debugCapture.js.map +1 -0
  74. package/dist/core/gthLeanAgentFactory.d.ts +9 -0
  75. package/dist/core/gthLeanAgentFactory.js +10 -0
  76. package/dist/core/gthLeanAgentFactory.js.map +1 -0
  77. package/dist/core/launchBanner.d.ts +120 -0
  78. package/dist/core/launchBanner.js +418 -0
  79. package/dist/core/launchBanner.js.map +1 -0
  80. package/dist/core/plainToolIndication.d.ts +15 -0
  81. package/dist/core/plainToolIndication.js +174 -0
  82. package/dist/core/plainToolIndication.js.map +1 -0
  83. package/dist/core/reasoningBlocks.d.ts +60 -0
  84. package/dist/core/reasoningBlocks.js +98 -0
  85. package/dist/core/reasoningBlocks.js.map +1 -0
  86. package/dist/core/refusal.d.ts +53 -0
  87. package/dist/core/refusal.js +133 -0
  88. package/dist/core/refusal.js.map +1 -0
  89. package/dist/core/runStats.d.ts +52 -0
  90. package/dist/core/runStats.js +118 -0
  91. package/dist/core/runStats.js.map +1 -0
  92. package/dist/core/shell/ShellCommandFailedError.d.ts +54 -0
  93. package/dist/core/shell/ShellCommandFailedError.js +68 -0
  94. package/dist/core/shell/ShellCommandFailedError.js.map +1 -0
  95. package/dist/core/shell/abstention.d.ts +88 -0
  96. package/dist/core/shell/abstention.js +184 -0
  97. package/dist/core/shell/abstention.js.map +1 -0
  98. package/dist/core/shell/approvalCapture.d.ts +271 -0
  99. package/dist/core/shell/approvalCapture.js +108 -0
  100. package/dist/core/shell/approvalCapture.js.map +1 -0
  101. package/dist/core/shell/approvalStop.d.ts +84 -0
  102. package/dist/core/shell/approvalStop.js +119 -0
  103. package/dist/core/shell/approvalStop.js.map +1 -0
  104. package/dist/core/shell/arity.d.ts +6 -0
  105. package/dist/core/shell/arity.js +20 -6
  106. package/dist/core/shell/arity.js.map +1 -1
  107. package/dist/core/shell/denylist.d.ts +11 -0
  108. package/dist/core/shell/denylist.js +37 -0
  109. package/dist/core/shell/denylist.js.map +1 -0
  110. package/dist/core/shell/escalationSeverity.d.ts +141 -0
  111. package/dist/core/shell/escalationSeverity.js +89 -0
  112. package/dist/core/shell/escalationSeverity.js.map +1 -0
  113. package/dist/core/shell/framing.d.ts +190 -0
  114. package/dist/core/shell/framing.js +633 -0
  115. package/dist/core/shell/framing.js.map +1 -0
  116. package/dist/core/shell/hardline.d.ts +81 -0
  117. package/dist/core/shell/hardline.js +607 -0
  118. package/dist/core/shell/hardline.js.map +1 -0
  119. package/dist/core/shell/negotiation.d.ts +249 -0
  120. package/dist/core/shell/negotiation.js +355 -0
  121. package/dist/core/shell/negotiation.js.map +1 -0
  122. package/dist/core/shell/normalize.d.ts +44 -4
  123. package/dist/core/shell/normalize.js +61 -7
  124. package/dist/core/shell/normalize.js.map +1 -1
  125. package/dist/core/shell/openWorld.d.ts +263 -0
  126. package/dist/core/shell/openWorld.js +1188 -0
  127. package/dist/core/shell/openWorld.js.map +1 -0
  128. package/dist/core/shell/rater.d.ts +935 -0
  129. package/dist/core/shell/rater.js +1473 -0
  130. package/dist/core/shell/rater.js.map +1 -0
  131. package/dist/core/shell/raterModel.d.ts +41 -0
  132. package/dist/core/shell/raterModel.js +51 -0
  133. package/dist/core/shell/raterModel.js.map +1 -0
  134. package/dist/core/shell/rejection.d.ts +69 -0
  135. package/dist/core/shell/rejection.js +38 -0
  136. package/dist/core/shell/rejection.js.map +1 -0
  137. package/dist/core/toolCallRepair/grammar.d.ts +41 -0
  138. package/dist/core/toolCallRepair/grammar.js +116 -0
  139. package/dist/core/toolCallRepair/grammar.js.map +1 -0
  140. package/dist/core/toolCallRepair/index.d.ts +2 -0
  141. package/dist/core/toolCallRepair/index.js +7 -0
  142. package/dist/core/toolCallRepair/index.js.map +1 -0
  143. package/dist/core/toolCallRepair/payload.d.ts +36 -0
  144. package/dist/core/toolCallRepair/payload.js +341 -0
  145. package/dist/core/toolCallRepair/payload.js.map +1 -0
  146. package/dist/core/toolCallRepair/promote.d.ts +45 -0
  147. package/dist/core/toolCallRepair/promote.js +90 -0
  148. package/dist/core/toolCallRepair/promote.js.map +1 -0
  149. package/dist/core/toolDisplay.d.ts +123 -0
  150. package/dist/core/toolDisplay.js +451 -0
  151. package/dist/core/toolDisplay.js.map +1 -0
  152. package/dist/core/toolOutputChannel.d.ts +95 -0
  153. package/dist/core/toolOutputChannel.js +165 -0
  154. package/dist/core/toolOutputChannel.js.map +1 -0
  155. package/dist/core/types.d.ts +294 -12
  156. package/dist/core/types.js.map +1 -1
  157. package/dist/history/historyFormat.d.ts +28 -0
  158. package/dist/history/historyFormat.js +127 -0
  159. package/dist/history/historyFormat.js.map +1 -0
  160. package/dist/history/historyStore.d.ts +198 -0
  161. package/dist/history/historyStore.js +482 -0
  162. package/dist/history/historyStore.js.map +1 -0
  163. package/dist/history/recordSession.d.ts +37 -0
  164. package/dist/history/recordSession.js +56 -0
  165. package/dist/history/recordSession.js.map +1 -0
  166. package/dist/index.d.ts +4 -0
  167. package/dist/index.js +4 -0
  168. package/dist/index.js.map +1 -1
  169. package/dist/providers/anthropic.d.ts +1 -1
  170. package/dist/providers/anthropic.js +5 -10
  171. package/dist/providers/anthropic.js.map +1 -1
  172. package/dist/providers/deepseek.d.ts +1 -1
  173. package/dist/providers/deepseek.js +5 -10
  174. package/dist/providers/deepseek.js.map +1 -1
  175. package/dist/providers/geminiSchemaSanitizer.d.ts +55 -0
  176. package/dist/providers/geminiSchemaSanitizer.js +347 -0
  177. package/dist/providers/geminiSchemaSanitizer.js.map +1 -0
  178. package/dist/providers/geminiThinking.d.ts +52 -0
  179. package/dist/providers/geminiThinking.js +72 -0
  180. package/dist/providers/geminiThinking.js.map +1 -0
  181. package/dist/providers/google-genai.d.ts +1 -1
  182. package/dist/providers/google-genai.js +12 -11
  183. package/dist/providers/google-genai.js.map +1 -1
  184. package/dist/providers/groq.d.ts +1 -1
  185. package/dist/providers/groq.js +5 -10
  186. package/dist/providers/groq.js.map +1 -1
  187. package/dist/providers/huggingface.d.ts +25 -0
  188. package/dist/providers/huggingface.js +69 -0
  189. package/dist/providers/huggingface.js.map +1 -0
  190. package/dist/providers/modelCatalog.d.ts +109 -0
  191. package/dist/providers/modelCatalog.js +245 -0
  192. package/dist/providers/modelCatalog.js.map +1 -0
  193. package/dist/providers/modelDiscovery.d.ts +153 -6
  194. package/dist/providers/modelDiscovery.js +295 -41
  195. package/dist/providers/modelDiscovery.js.map +1 -1
  196. package/dist/providers/ollama.d.ts +19 -5
  197. package/dist/providers/ollama.js +60 -52
  198. package/dist/providers/ollama.js.map +1 -1
  199. package/dist/providers/openai.d.ts +1 -1
  200. package/dist/providers/openai.js +39 -10
  201. package/dist/providers/openai.js.map +1 -1
  202. package/dist/providers/openrouter.d.ts +4 -5
  203. package/dist/providers/openrouter.js +20 -35
  204. package/dist/providers/openrouter.js.map +1 -1
  205. package/dist/providers/vertexai.d.ts +1 -1
  206. package/dist/providers/vertexai.js +12 -11
  207. package/dist/providers/vertexai.js.map +1 -1
  208. package/dist/providers/xai.d.ts +1 -1
  209. package/dist/providers/xai.js +5 -10
  210. package/dist/providers/xai.js.map +1 -1
  211. package/dist/runtime/askStructured.d.ts +105 -0
  212. package/dist/runtime/askStructured.js +120 -0
  213. package/dist/runtime/askStructured.js.map +1 -0
  214. package/dist/runtime/conversation.d.ts +60 -0
  215. package/dist/runtime/conversation.js +151 -0
  216. package/dist/runtime/conversation.js.map +1 -0
  217. package/dist/runtime/singleShot.d.ts +25 -5
  218. package/dist/runtime/singleShot.js +95 -36
  219. package/dist/runtime/singleShot.js.map +1 -1
  220. package/dist/runtime/structuredOutput.d.ts +104 -0
  221. package/dist/runtime/structuredOutput.js +393 -0
  222. package/dist/runtime/structuredOutput.js.map +1 -0
  223. package/dist/utils/ProgressIndicator.d.ts +21 -0
  224. package/dist/utils/ProgressIndicator.js +30 -3
  225. package/dist/utils/ProgressIndicator.js.map +1 -1
  226. package/dist/utils/aiignoreUtils.js.map +1 -1
  227. package/dist/utils/binaryOutputUtils.js.map +1 -1
  228. package/dist/utils/consoleUtils.d.ts +52 -0
  229. package/dist/utils/consoleUtils.js +72 -2
  230. package/dist/utils/consoleUtils.js.map +1 -1
  231. package/dist/utils/crashHandler.d.ts +87 -0
  232. package/dist/utils/crashHandler.js +128 -0
  233. package/dist/utils/crashHandler.js.map +1 -0
  234. package/dist/utils/debugDump.d.ts +134 -0
  235. package/dist/utils/debugDump.js +381 -0
  236. package/dist/utils/debugDump.js.map +1 -0
  237. package/dist/utils/debugUtils.d.ts +13 -4
  238. package/dist/utils/debugUtils.js +36 -13
  239. package/dist/utils/debugUtils.js.map +1 -1
  240. package/dist/utils/displayWidth.d.ts +53 -0
  241. package/dist/utils/displayWidth.js +195 -0
  242. package/dist/utils/displayWidth.js.map +1 -0
  243. package/dist/utils/fileUtils.d.ts +24 -2
  244. package/dist/utils/fileUtils.js +54 -12
  245. package/dist/utils/fileUtils.js.map +1 -1
  246. package/dist/utils/llmUtils.d.ts +39 -8
  247. package/dist/utils/llmUtils.js +76 -8
  248. package/dist/utils/llmUtils.js.map +1 -1
  249. package/dist/utils/redactSecrets.d.ts +63 -0
  250. package/dist/utils/redactSecrets.js +286 -0
  251. package/dist/utils/redactSecrets.js.map +1 -0
  252. package/dist/utils/systemPromptNotes.d.ts +225 -0
  253. package/dist/utils/systemPromptNotes.js +340 -0
  254. package/dist/utils/systemPromptNotes.js.map +1 -0
  255. package/dist/utils/systemUtils.d.ts +49 -1
  256. package/dist/utils/systemUtils.js +67 -3
  257. package/dist/utils/systemUtils.js.map +1 -1
  258. package/dist/utils/toolMatching.d.ts +30 -0
  259. package/dist/utils/toolMatching.js +44 -0
  260. package/dist/utils/toolMatching.js.map +1 -0
  261. package/dist/utils/untrustedText.d.ts +66 -0
  262. package/dist/utils/untrustedText.js +80 -0
  263. package/dist/utils/untrustedText.js.map +1 -0
  264. package/package.json +22 -6
  265. package/schema/gsloth-config.schema.json +3134 -0
  266. package/dist/core/shell/allowlist.d.ts +0 -75
  267. package/dist/core/shell/allowlist.js +0 -187
  268. package/dist/core/shell/allowlist.js.map +0 -1
  269. package/dist/core/shell/judge.d.ts +0 -161
  270. package/dist/core/shell/judge.js +0 -261
  271. package/dist/core/shell/judge.js.map +0 -1
@@ -0,0 +1,341 @@
1
+ // EXT-35 — plain-text tool-call repair payload parser.
2
+ //
3
+ // Ported (TypeScript, gaunt-sloth house style) from the openclaw
4
+ // `@openclaw/tool-call-repair` reference (`packages/tool-call-repair/src/payload.ts`).
5
+ // Carries the three text-emitted tool-call dialects small/local models produce:
6
+ // • bracket: `[tool:name]{...json...}` / `[name]\n{...json...}[/name]`
7
+ // • XML-ish: `<function=name><parameter=key>value</parameter></function>`
8
+ // • Harmony: `<|channel|>commentary to=name code<|message|>{...json...}<|call|>`
9
+ // — plus the real gpt-oss variant (EXT-43) with a NAMESPACED name and a `<|constrain|>` marker:
10
+ // `<|channel|>commentary to=functions.get_weather<|constrain|>json<|message|>{...}<|call|>`
11
+ //
12
+ // {@link parseStandalonePlainTextToolCallBlocks} is STANDALONE-only by construction: it walks the
13
+ // WHOLE input and returns null the moment it hits text that is not a tool-call block, so prose that
14
+ // merely mentions a tool or contains brackets never parses as a call. Allow-list + payload-size
15
+ // gating are threaded through {@link PlainTextToolCallParseOptions}. The reference's streaming
16
+ // normalizer and user-visible strip helpers are intentionally omitted (not needed for promotion).
17
+ import { consumeLineBreak, END_TOOL_REQUEST, finalDotSegment, findJsonObjectEnd, HARMONY_CALL_MARKER, HARMONY_CHANNEL_MARKER, HARMONY_CONSTRAIN_MARKER, HARMONY_MESSAGE_MARKER, isHarmonyToolNameChar, isPlainTextToolNameChar, skipHorizontalWhitespace, skipWhitespace, } from './grammar.js';
18
+ /**
19
+ * The single source of truth for the plain-text tool-call payload cap (256 KB). A serialized call
20
+ * larger than this is never treated as a tool call. Re-exported from `./promote.js` (and the module
21
+ * index) as `MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES` — the public name — so there is ONE constant,
22
+ * not two duplicated literals. (EXT-43 unified the former `DEFAULT_MAX_PLAIN_TEXT_TOOL_PAYLOAD_BYTES`
23
+ * here with `promote.ts`'s copy.)
24
+ */
25
+ export const MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES = 256_000;
26
+ const utf8Encoder = new TextEncoder();
27
+ function utf8ByteLengthWithinLimit(text, start, end, maxBytes) {
28
+ if (end - start > maxBytes) {
29
+ return null;
30
+ }
31
+ const byteLength = utf8Encoder.encode(text.slice(start, end)).byteLength;
32
+ return byteLength <= maxBytes ? byteLength : null;
33
+ }
34
+ function parseBracketOpening(text, start) {
35
+ if (text[start] !== '[') {
36
+ return null;
37
+ }
38
+ let cursor = start + 1;
39
+ if (text.startsWith('tool:', cursor)) {
40
+ cursor += 'tool:'.length;
41
+ const nameStart = cursor;
42
+ while (isPlainTextToolNameChar(text[cursor])) {
43
+ cursor += 1;
44
+ }
45
+ if (cursor === nameStart || text[cursor] !== ']') {
46
+ return null;
47
+ }
48
+ return {
49
+ allowsOptionalXmlishClose: true,
50
+ end: cursor + 1,
51
+ name: text.slice(nameStart, cursor),
52
+ requiresClosing: false,
53
+ };
54
+ }
55
+ const nameStart = cursor;
56
+ while (isPlainTextToolNameChar(text[cursor])) {
57
+ cursor += 1;
58
+ }
59
+ if (cursor === nameStart || text[cursor] !== ']') {
60
+ return null;
61
+ }
62
+ const name = text.slice(nameStart, cursor);
63
+ cursor += 1;
64
+ cursor = skipHorizontalWhitespace(text, cursor);
65
+ const afterLineBreak = consumeLineBreak(text, cursor);
66
+ if (afterLineBreak === null) {
67
+ return null;
68
+ }
69
+ return { end: afterLineBreak, name, requiresClosing: true };
70
+ }
71
+ function parseHarmonyOpening(text, start) {
72
+ let cursor = start;
73
+ if (text.startsWith(HARMONY_CHANNEL_MARKER, cursor)) {
74
+ cursor += HARMONY_CHANNEL_MARKER.length;
75
+ }
76
+ const channelStart = cursor;
77
+ while (/[A-Za-z_]/.test(text[cursor] ?? '')) {
78
+ cursor += 1;
79
+ }
80
+ const channel = text.slice(channelStart, cursor);
81
+ if (channel !== 'commentary' && channel !== 'analysis' && channel !== 'final') {
82
+ return null;
83
+ }
84
+ cursor = skipHorizontalWhitespace(text, cursor);
85
+ if (!text.startsWith('to=', cursor)) {
86
+ return null;
87
+ }
88
+ cursor += 3;
89
+ // Tool name. EXT-43: accept the real gpt-oss NAMESPACED form (`to=functions.get_weather`) by
90
+ // scanning dot-inclusive chars, then take the FINAL dot-segment as the allow-listed tool name.
91
+ // The reference dotless form (`to=get_weather`) is the single-segment degenerate case.
92
+ const nameStart = cursor;
93
+ while (isHarmonyToolNameChar(text[cursor])) {
94
+ cursor += 1;
95
+ }
96
+ if (cursor === nameStart) {
97
+ return null;
98
+ }
99
+ const name = finalDotSegment(text.slice(nameStart, cursor));
100
+ if (!name) {
101
+ // Trailing-dot / empty final segment (e.g. `to=functions.`) is not a valid tool name.
102
+ return null;
103
+ }
104
+ cursor = skipHorizontalWhitespace(text, cursor);
105
+ // Payload-format marker between the header and the JSON. The reference grammar requires the
106
+ // literal `code` token; real gpt-oss instead emits `<|constrain|>json` (EXT-43). Accept EITHER —
107
+ // but a marker is still REQUIRED, so the widening does not relax prose-safety (a bare
108
+ // `commentary to=x {…}` never promotes).
109
+ if (text.startsWith('code', cursor)) {
110
+ cursor += 4;
111
+ }
112
+ else if (text.startsWith(HARMONY_CONSTRAIN_MARKER, cursor)) {
113
+ cursor += HARMONY_CONSTRAIN_MARKER.length;
114
+ // Optional constraint-format token that follows the marker (e.g. `json`).
115
+ cursor = skipHorizontalWhitespace(text, cursor);
116
+ while (isPlainTextToolNameChar(text[cursor])) {
117
+ cursor += 1;
118
+ }
119
+ }
120
+ else {
121
+ return null;
122
+ }
123
+ cursor = skipWhitespace(text, cursor);
124
+ if (text.startsWith(HARMONY_MESSAGE_MARKER, cursor)) {
125
+ cursor = skipWhitespace(text, cursor + HARMONY_MESSAGE_MARKER.length);
126
+ }
127
+ return { end: cursor, name, requiresClosing: false };
128
+ }
129
+ function parseXmlishFunctionOpening(text, start) {
130
+ const match = /^<function=([A-Za-z0-9_.:-]{1,120})>\s*/i.exec(text.slice(start));
131
+ if (!match?.[1]) {
132
+ return null;
133
+ }
134
+ return { end: start + match[0].length, name: match[1], requiresClosing: false };
135
+ }
136
+ function parseOpening(text, start) {
137
+ return parseBracketOpening(text, start) ?? parseHarmonyOpening(text, start);
138
+ }
139
+ function consumeJsonObject(text, start, maxPayloadBytes) {
140
+ const cursor = skipWhitespace(text, start);
141
+ if (text[cursor] !== '{') {
142
+ return null;
143
+ }
144
+ const end = findJsonObjectEnd(text, cursor, maxPayloadBytes);
145
+ if (end === null || utf8ByteLengthWithinLimit(text, cursor, end, maxPayloadBytes) === null) {
146
+ return null;
147
+ }
148
+ const rawJson = text.slice(cursor, end);
149
+ try {
150
+ const parsed = JSON.parse(rawJson);
151
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
152
+ return null;
153
+ }
154
+ return { end, value: parsed };
155
+ }
156
+ catch {
157
+ return null;
158
+ }
159
+ }
160
+ function parseClosing(text, start, name) {
161
+ const cursor = skipWhitespace(text, start);
162
+ if (text.startsWith(END_TOOL_REQUEST, cursor)) {
163
+ return cursor + END_TOOL_REQUEST.length;
164
+ }
165
+ const namedClosing = `[/${name}]`;
166
+ if (text.startsWith(namedClosing, cursor)) {
167
+ return cursor + namedClosing.length;
168
+ }
169
+ return null;
170
+ }
171
+ function parseOptionalHarmonyClosing(text, start) {
172
+ const cursor = skipWhitespace(text, start);
173
+ if (text.startsWith(HARMONY_CALL_MARKER, cursor)) {
174
+ return cursor + HARMONY_CALL_MARKER.length;
175
+ }
176
+ return start;
177
+ }
178
+ function parsePlainTextToolCallBlockAt(text, start, options) {
179
+ const opening = parseOpening(text, start);
180
+ if (!opening) {
181
+ return null;
182
+ }
183
+ const allowedToolNames = options?.allowedToolNames
184
+ ? new Set(options.allowedToolNames)
185
+ : undefined;
186
+ if (allowedToolNames && !allowedToolNames.has(opening.name)) {
187
+ return null;
188
+ }
189
+ const payload = consumeJsonObject(text, opening.end, options?.maxPayloadBytes ?? MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES);
190
+ if (!payload) {
191
+ return null;
192
+ }
193
+ const closingEnd = opening.requiresClosing
194
+ ? parseClosing(text, payload.end, opening.name)
195
+ : parseOptionalHarmonyClosing(text, payload.end);
196
+ if (closingEnd === null) {
197
+ return null;
198
+ }
199
+ return {
200
+ arguments: payload.value,
201
+ end: closingEnd,
202
+ name: opening.name,
203
+ raw: text.slice(start, closingEnd),
204
+ start,
205
+ };
206
+ }
207
+ function findXmlishParameterBlock(text, start) {
208
+ const cursor = skipWhitespace(text, start);
209
+ const openMatch = /^<parameter=([A-Za-z0-9_.:-]{1,120})>/i.exec(text.slice(cursor));
210
+ if (!openMatch?.[1]) {
211
+ return null;
212
+ }
213
+ const payloadStart = cursor + openMatch[0].length;
214
+ const closeMatch = /<\/parameter>/i.exec(text.slice(payloadStart));
215
+ if (!closeMatch) {
216
+ return null;
217
+ }
218
+ const closeStart = payloadStart + closeMatch.index;
219
+ const closeEnd = closeStart + closeMatch[0].length;
220
+ return {
221
+ closeStart,
222
+ end: closeEnd,
223
+ name: openMatch[1],
224
+ payloadStart,
225
+ start: cursor,
226
+ };
227
+ }
228
+ function extractXmlishParameterValue(text, start, end) {
229
+ let payloadStart = start;
230
+ let payloadEnd = end;
231
+ const afterOpeningLineBreak = consumeLineBreak(text, payloadStart);
232
+ if (afterOpeningLineBreak !== null) {
233
+ payloadStart = afterOpeningLineBreak;
234
+ if (payloadEnd > payloadStart && text[payloadEnd - 1] === '\n') {
235
+ payloadEnd -= 1;
236
+ if (payloadEnd > payloadStart && text[payloadEnd - 1] === '\r') {
237
+ payloadEnd -= 1;
238
+ }
239
+ }
240
+ else if (payloadEnd > payloadStart && text[payloadEnd - 1] === '\r') {
241
+ payloadEnd -= 1;
242
+ }
243
+ }
244
+ return text.slice(payloadStart, payloadEnd);
245
+ }
246
+ function consumeXmlishParameterBlock(text, start, maxPayloadBytes) {
247
+ const bounds = findXmlishParameterBlock(text, start);
248
+ if (!bounds) {
249
+ return null;
250
+ }
251
+ const byteLength = utf8ByteLengthWithinLimit(text, start, bounds.end, maxPayloadBytes);
252
+ if (byteLength === null) {
253
+ return null;
254
+ }
255
+ return {
256
+ byteLength,
257
+ end: bounds.end,
258
+ name: bounds.name,
259
+ value: extractXmlishParameterValue(text, bounds.payloadStart, bounds.closeStart),
260
+ };
261
+ }
262
+ function consumeXmlishFunctionClose(text, start) {
263
+ const cursor = skipWhitespace(text, start);
264
+ return text.slice(cursor).toLowerCase().startsWith('</function>')
265
+ ? cursor + '</function>'.length
266
+ : null;
267
+ }
268
+ function consumeOptionalXmlishFunctionClose(text, start) {
269
+ return consumeXmlishFunctionClose(text, start) ?? start;
270
+ }
271
+ function parseXmlishOpening(text, start) {
272
+ return parseBracketOpening(text, start) ?? parseXmlishFunctionOpening(text, start);
273
+ }
274
+ function parseXmlishPlainTextToolCallBlockAt(text, start, options) {
275
+ const opening = parseXmlishOpening(text, start);
276
+ if (!opening) {
277
+ return null;
278
+ }
279
+ const allowedToolNames = options?.allowedToolNames
280
+ ? new Set(options.allowedToolNames)
281
+ : undefined;
282
+ if (allowedToolNames && !allowedToolNames.has(opening.name)) {
283
+ return null;
284
+ }
285
+ const maxPayloadBytes = options?.maxPayloadBytes ?? MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES;
286
+ const args = {};
287
+ let cursor = opening.end;
288
+ let parameterCount = 0;
289
+ let payloadBytes = 0;
290
+ while (true) {
291
+ const parameter = consumeXmlishParameterBlock(text, cursor, maxPayloadBytes);
292
+ if (!parameter) {
293
+ break;
294
+ }
295
+ payloadBytes += parameter.byteLength;
296
+ if (payloadBytes > maxPayloadBytes) {
297
+ return null;
298
+ }
299
+ args[parameter.name] = parameter.value;
300
+ parameterCount += 1;
301
+ cursor = parameter.end;
302
+ }
303
+ if (parameterCount === 0) {
304
+ return null;
305
+ }
306
+ const end = opening.allowsOptionalXmlishClose
307
+ ? consumeOptionalXmlishFunctionClose(text, cursor)
308
+ : consumeXmlishFunctionClose(text, cursor);
309
+ if (end === null) {
310
+ return null;
311
+ }
312
+ return {
313
+ arguments: args,
314
+ end,
315
+ name: opening.name,
316
+ raw: text.slice(start, end),
317
+ start,
318
+ };
319
+ }
320
+ /**
321
+ * Parse the WHOLE input into standalone plain-text tool-call blocks, or return null if any part of
322
+ * it is not such a block. This all-or-nothing walk is the standalone-only gate: prose that merely
323
+ * mentions a tool name, contains brackets, or embeds a call inside a sentence never parses (the
324
+ * first non-block character aborts the parse). Allow-list + payload-cap gating are applied per
325
+ * block via {@link PlainTextToolCallParseOptions}.
326
+ */
327
+ export function parseStandalonePlainTextToolCallBlocks(text, options) {
328
+ const blocks = [];
329
+ let cursor = skipWhitespace(text, 0);
330
+ while (cursor < text.length) {
331
+ const block = parsePlainTextToolCallBlockAt(text, cursor, options) ??
332
+ parseXmlishPlainTextToolCallBlockAt(text, cursor, options);
333
+ if (!block) {
334
+ return null;
335
+ }
336
+ blocks.push(block);
337
+ cursor = skipWhitespace(text, block.end);
338
+ }
339
+ return blocks.length > 0 ? blocks : null;
340
+ }
341
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/core/toolCallRepair/payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { AIMessage } from '@langchain/core/messages';
2
+ /**
3
+ * A sane default cap on a single repaired call's serialized payload. A text blob larger than this
4
+ * is never treated as a tool call. Overridable per call so a test can assert the cap with a small
5
+ * value; production leaves it at the default. The single source of truth lives in `./payload.js`
6
+ * and is re-exported here under its public name (EXT-43 unified the former duplicated literal).
7
+ */
8
+ export { MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES } from './payload.js';
9
+ /** LangChain native tool-call shape (structurally a `ToolCall` from `@langchain/core/messages`). */
10
+ type NativeToolCall = {
11
+ id: string;
12
+ name: string;
13
+ args: Record<string, unknown>;
14
+ type: 'tool_call';
15
+ };
16
+ /** Gates for {@link textToNativeToolCalls} / {@link promoteTextEmittedToolCallMessage}. */
17
+ export interface TextToolCallRepairOptions {
18
+ /**
19
+ * The names of the tools bound to this run (the allow-list). Only a text-emitted call whose name
20
+ * is one of these promotes; an unknown name is left as text. An EMPTY set promotes nothing — the
21
+ * prose-safe default (no toolset ⇒ nothing is a call).
22
+ */
23
+ allowedToolNames: Iterable<string>;
24
+ /** Payload-size cap; defaults to {@link MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES}. */
25
+ maxPayloadBytes?: number;
26
+ }
27
+ /**
28
+ * Parse assistant `text` as one-or-more STANDALONE text-emitted tool calls and return them as
29
+ * native LangChain tool_calls, or `undefined` when the text is not a standalone call, names a tool
30
+ * outside the allow-list, or exceeds the payload cap. Fresh `id`s are minted per call (the model
31
+ * emitted none). Empty allow-list ⇒ `undefined` (never promote).
32
+ */
33
+ export declare function textToNativeToolCalls(text: string | undefined, options: TextToolCallRepairOptions): NativeToolCall[] | undefined;
34
+ /**
35
+ * Repair one assistant {@link AIMessage}: if it has NO native tool_calls but its content is a
36
+ * standalone text-emitted call (allow-listed, within the payload cap), return a NEW AIMessage that
37
+ * carries the promoted native tool_calls; otherwise return `undefined` (the caller keeps the
38
+ * original, so the native happy path is untouched).
39
+ *
40
+ * The returned message PRESERVES the original `id`. That is load-bearing: LangGraph's message-state
41
+ * reducer merges by id, so a same-id message REPLACES the original in graph state (rather than
42
+ * appending a duplicate/dangling assistant message). Content is cleared to '' since the raw
43
+ * text-call is now represented natively as tool_calls.
44
+ */
45
+ export declare function promoteTextEmittedToolCallMessage(message: AIMessage, options: TextToolCallRepairOptions): AIMessage | undefined;
@@ -0,0 +1,90 @@
1
+ // EXT-35 — promote a text-emitted tool call to a native LangChain tool_call.
2
+ //
3
+ // The LangChain-message adaptation of the openclaw `@openclaw/tool-call-repair` reference
4
+ // (`packages/tool-call-repair/src/promote.ts`'s `promoteStandalonePlainTextToolCallMessage`).
5
+ // Small/local models (Gemma, lmstudio, gpt-oss) often serialise a tool call as assistant TEXT
6
+ // rather than a native `tool_call`; the ReAct graph then sees no tool_calls and ends the turn
7
+ // ("no tool calls = done"), stalling the loop. This module rescues a STANDALONE text-emitted call
8
+ // by rewriting the assistant message into one carrying a native `tool_call`, so the graph routes to
9
+ // the tools node and the loop continues.
10
+ //
11
+ // Three hard gates keep prose from ever being misread as a call:
12
+ // 1. name allow-list — only a call whose tool name is in the bound toolset promotes (an empty
13
+ // allow-list promotes nothing, the prose-safe default);
14
+ // 2. payload-size cap — an oversized JSON blob is not treated as a call;
15
+ // 3. standalone-only — the message content must be ESSENTIALLY JUST the call (enforced by
16
+ // {@link parseStandalonePlainTextToolCallBlocks}'s whole-input walk).
17
+ //
18
+ // Unlike the reference we do NOT set a `stopReason`/`toolUse` flag: langchain's ReAct router keys
19
+ // purely off the presence of `tool_calls` on the last AIMessage, so promoting the tool_calls array
20
+ // is sufficient to continue the loop.
21
+ import { AIMessage } from '@langchain/core/messages';
22
+ import { randomUUID } from 'node:crypto';
23
+ import { MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES, parseStandalonePlainTextToolCallBlocks, } from './payload.js';
24
+ /**
25
+ * A sane default cap on a single repaired call's serialized payload. A text blob larger than this
26
+ * is never treated as a tool call. Overridable per call so a test can assert the cap with a small
27
+ * value; production leaves it at the default. The single source of truth lives in `./payload.js`
28
+ * and is re-exported here under its public name (EXT-43 unified the former duplicated literal).
29
+ */
30
+ export { MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES } from './payload.js';
31
+ /**
32
+ * Parse assistant `text` as one-or-more STANDALONE text-emitted tool calls and return them as
33
+ * native LangChain tool_calls, or `undefined` when the text is not a standalone call, names a tool
34
+ * outside the allow-list, or exceeds the payload cap. Fresh `id`s are minted per call (the model
35
+ * emitted none). Empty allow-list ⇒ `undefined` (never promote).
36
+ */
37
+ export function textToNativeToolCalls(text, options) {
38
+ const allowedToolNames = new Set(options.allowedToolNames);
39
+ // Prose-safety default: with no bound tools nothing can be a call.
40
+ if (allowedToolNames.size === 0) {
41
+ return undefined;
42
+ }
43
+ const trimmed = (text ?? '').trim();
44
+ if (!trimmed) {
45
+ return undefined;
46
+ }
47
+ const parseOptions = {
48
+ allowedToolNames,
49
+ maxPayloadBytes: options.maxPayloadBytes ?? MAX_TEXT_EMITTED_TOOL_CALL_PAYLOAD_BYTES,
50
+ };
51
+ const blocks = parseStandalonePlainTextToolCallBlocks(trimmed, parseOptions);
52
+ if (!blocks) {
53
+ return undefined;
54
+ }
55
+ return blocks.map((block) => ({
56
+ id: randomUUID(),
57
+ name: block.name,
58
+ args: block.arguments,
59
+ type: 'tool_call',
60
+ }));
61
+ }
62
+ /**
63
+ * Repair one assistant {@link AIMessage}: if it has NO native tool_calls but its content is a
64
+ * standalone text-emitted call (allow-listed, within the payload cap), return a NEW AIMessage that
65
+ * carries the promoted native tool_calls; otherwise return `undefined` (the caller keeps the
66
+ * original, so the native happy path is untouched).
67
+ *
68
+ * The returned message PRESERVES the original `id`. That is load-bearing: LangGraph's message-state
69
+ * reducer merges by id, so a same-id message REPLACES the original in graph state (rather than
70
+ * appending a duplicate/dangling assistant message). Content is cleared to '' since the raw
71
+ * text-call is now represented natively as tool_calls.
72
+ */
73
+ export function promoteTextEmittedToolCallMessage(message, options) {
74
+ // Happy path untouched: repair engages ONLY when there are no native tool_calls.
75
+ if (message.tool_calls && message.tool_calls.length > 0) {
76
+ return undefined;
77
+ }
78
+ const toolCalls = textToNativeToolCalls(message.text, options);
79
+ if (!toolCalls) {
80
+ return undefined;
81
+ }
82
+ return new AIMessage({
83
+ id: message.id,
84
+ content: '',
85
+ tool_calls: toolCalls,
86
+ additional_kwargs: message.additional_kwargs,
87
+ response_metadata: message.response_metadata,
88
+ });
89
+ }
90
+ //# sourceMappingURL=promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promote.js","sourceRoot":"","sources":["../../../src/core/toolCallRepair/promote.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,8FAA8F;AAC9F,8FAA8F;AAC9F,kGAAkG;AAClG,oGAAoG;AACpG,yCAAyC;AACzC,EAAE;AACF,iEAAiE;AACjE,gGAAgG;AAChG,6DAA6D;AAC7D,2EAA2E;AAC3E,4FAA4F;AAC5F,2EAA2E;AAC3E,EAAE;AACF,kGAAkG;AAClG,mGAAmG;AACnG,sCAAsC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,wCAAwC,EACxC,sCAAsC,GAEvC,MAAM,cAAc,CAAC;AAEtB;;;;;GAKG;AACH,OAAO,EAAE,wCAAwC,EAAE,MAAM,cAAc,CAAC;AAsBxE;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAwB,EACxB,OAAkC;IAElC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,mEAAmE;IACnE,IAAI,gBAAgB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,YAAY,GAAkC;QAClD,gBAAgB;QAChB,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,wCAAwC;KACrF,CAAC;IACF,MAAM,MAAM,GAAG,sCAAsC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC7E,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5B,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,SAAS;QACrB,IAAI,EAAE,WAAoB;KAC3B,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iCAAiC,CAC/C,OAAkB,EAClB,OAAkC;IAElC,iFAAiF;IACjF,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,SAAS,CAAC;QACnB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,SAAS;QACrB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;KAC7C,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,123 @@
1
+ /** The single canonical output-preview cap (lines). No other preview length exists anywhere. */
2
+ export declare const TOOL_OUTPUT_PREVIEW_LINES = 10;
3
+ /**
4
+ * Per-line cap for preview lines, in terminal COLUMNS (a one-line minified bundle must not flood a
5
+ * row). The `CHARS` in the name is historical; every cap here is a column budget, because a
6
+ * character count is not a width — see `#src/utils/displayWidth.js`.
7
+ */
8
+ export declare const TOOL_PREVIEW_LINE_MAX_CHARS = 200;
9
+ /** Per-value cap inside a params summary, in terminal COLUMNS. */
10
+ export declare const TOOL_PARAM_VALUE_MAX_CHARS = 48;
11
+ /** Whole params-summary cap (everything inside the parentheses), in terminal COLUMNS. */
12
+ export declare const TOOL_SUMMARY_MAX_CHARS = 120;
13
+ /** The overflow/truncation marker used everywhere in this module. */
14
+ export declare const ELLIPSIS = "\u2026";
15
+ /**
16
+ * Columns {@link ELLIPSIS} itself occupies, which every truncator has to reserve out of its budget
17
+ * before slicing. Derived rather than written as `1` so it stays true of whatever marker is used.
18
+ */
19
+ export declare const ELLIPSIS_WIDTH: number;
20
+ /**
21
+ * Style tag for one rendered line. The two surfaces map these to their own colour systems
22
+ * (Ink `<Text>` props / raw ANSI): `dim` = greyed preview text, `added`/`removed` = diff
23
+ * green/red. DL-8 colour semantics; monochrome surfaces render the raw text unchanged.
24
+ */
25
+ export type ToolDisplayStyle = 'dim' | 'added' | 'removed';
26
+ /** One line of a tool call's rendered body/preview. */
27
+ export interface ToolDisplayLine {
28
+ text: string;
29
+ style: ToolDisplayStyle;
30
+ }
31
+ /**
32
+ * Everything a formatter may look at for one tool call. Both surfaces build this from their
33
+ * own state (the TUI from `ToolCallViewModel`, the plain surface from the message stream).
34
+ */
35
+ export interface ToolCallDisplayInput {
36
+ /** The gth tool name (`read_file`, `run_shell_command`, a custom tool's name). */
37
+ name: string;
38
+ /** The raw streamed args JSON (possibly partial mid-stream, possibly invalid). */
39
+ argsText?: string;
40
+ /** The final model-facing tool result, when it has arrived. */
41
+ result?: string;
42
+ /** Live streamed child output (TUI only — the `tool_output` channel's accumulation). */
43
+ output?: string;
44
+ /** The real `ToolMessage.status === 'error'` signal (TUI-C7) — never sniffed from text. */
45
+ isError?: boolean;
46
+ /**
47
+ * True when the live child output ALREADY streamed raw to the user's terminal (the plain
48
+ * surface's default sink). Formatters then suppress the duplicated output body and render
49
+ * only the closing status — the TUI-C17 "output AND result repeat each other" dedupe.
50
+ */
51
+ liveOutputAlreadyShown?: boolean;
52
+ }
53
+ /**
54
+ * Tolerant parse of a (possibly partial) streamed args JSON. Mirrors the view-model's
55
+ * defensive posture: a half-streamed or malformed buffer never throws — it returns `null`.
56
+ */
57
+ export declare function parseToolArgsSafe(argsText: string | undefined): Record<string, unknown> | null;
58
+ /**
59
+ * Register the live config for inline-secret collection (TUI-C32 residual a). Resets the secret
60
+ * cache so the next {@link getDefaultSecrets} recomputes with the config's inline literals folded
61
+ * in. Idempotent; a later call with a fresh config supersedes the previous one.
62
+ */
63
+ export declare function setToolDisplayConfig(config: unknown): void;
64
+ /** Test seam: drop the cached secret literals + registered config so specs can vary both. */
65
+ export declare function resetToolDisplaySecretsCacheForTests(): void;
66
+ /**
67
+ * Parse the shared shell-result shape (`Executing '…'…\n\n<COMMAND_OUTPUT>…</COMMAND_OUTPUT>\n\n
68
+ * <status line>`). Returns the captured output body and the trailing status text, or `null`
69
+ * when the result is not shell-shaped.
70
+ */
71
+ export declare function parseCommandOutputResult(result: string | undefined): {
72
+ body: string;
73
+ tail: string;
74
+ } | null;
75
+ /**
76
+ * TUI-C32 residual c — is THIS tool call genuinely a shell-shaped result (name allows it AND the
77
+ * result actually carries the `<COMMAND_OUTPUT>` shape)? Used by the plain surface to decide
78
+ * `liveOutputAlreadyShown` (the child streamed live via the tool-output channel's default sink),
79
+ * so a non-shell tool whose result merely quotes the marker no longer has its body suppressed.
80
+ */
81
+ export declare function isShellShapedResult(name: string, result: string | undefined): boolean;
82
+ /** The registry glyph for a tool name (generic `⚙` when unknown). */
83
+ export declare function getToolGlyph(name: string): string;
84
+ /**
85
+ * One-line call summary: `name(arg=val, other=…)`. Key args only (per the registry entry, or
86
+ * all args for unknown tools), each value inlined + truncated, the whole parenthesised part
87
+ * capped at {@link TOOL_SUMMARY_MAX_CHARS}, and everything secret-redacted (literals +
88
+ * provider patterns). Unparsable (mid-stream/malformed) args render as `name(…)` — never a
89
+ * raw JSON dump. `secrets` defaults to the env-derived literals; pass explicitly for tests.
90
+ *
91
+ * Redaction runs BEFORE every truncation step (per value in {@link formatParamValue}, and again
92
+ * before the whole-summary cap): truncating first would bisect a literal secret longer than a
93
+ * cap so it no longer literal-matches, leaking its head into the rendered summary
94
+ * (fix-cycle-1 finding). The final pass over the assembled string is defense in depth only —
95
+ * `redactText` is idempotent, so re-redacting already-marked text is safe.
96
+ */
97
+ export declare function summariseToolCall(name: string, argsText: string | undefined, secrets?: readonly string[]): string;
98
+ /**
99
+ * The FULL (uncapped) body lines for a call: the registry formatter when one applies, else the
100
+ * shape-based shell formatter, else the generic fallback (live output lines, then the final
101
+ * result — both dim). Every line is secret-redacted. Used by the TUI's EXPANDED panel; cap it
102
+ * with {@link capToolDisplayLines} for the collapsed preview.
103
+ */
104
+ export declare function buildToolBodyLines(input: ToolCallDisplayInput, secrets?: readonly string[]): ToolDisplayLine[];
105
+ /**
106
+ * Apply the canonical render cap: at most `maxLines` lines (each char-capped at
107
+ * {@link TOOL_PREVIEW_LINE_MAX_CHARS} with `…`), plus a dim `… (+N more lines)` overflow
108
+ * marker when anything was cut. The marker line is IN ADDITION to the cap so exactly how much
109
+ * was hidden is always stated (DL-4 transparency).
110
+ */
111
+ export declare function capToolDisplayLines(lines: ToolDisplayLine[], maxLines?: number): ToolDisplayLine[];
112
+ /**
113
+ * The collapsed inline preview: {@link buildToolBodyLines} capped at the canonical
114
+ * {@link TOOL_OUTPUT_PREVIEW_LINES}.
115
+ */
116
+ export declare function buildToolPreviewLines(input: ToolCallDisplayInput, secrets?: readonly string[]): ToolDisplayLine[];
117
+ /**
118
+ * Render one styled line as a raw string for the plain surface. Each line is SELF-STYLED
119
+ * (its own SGR open + reset) so lines compose safely regardless of surrounding styling.
120
+ * With `colour` false the raw text is returned unchanged — the clean monochrome degradation
121
+ * for non-TTY/piped output (DL-7); diff lines still read via their `+`/`-` prefixes.
122
+ */
123
+ export declare function renderToolLineAnsi(line: ToolDisplayLine, colour: boolean): string;