@caupulican/pi-adaptative 0.81.9 → 0.81.13
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/CHANGELOG.md +26 -0
- package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +152 -0
- package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +128 -0
- package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +201 -0
- package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +141 -0
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +5 -0
- package/dist/cli/list-models.js.map +1 -1
- package/dist/core/agent-session.d.ts +46 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +394 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/delegation/worker-actions.d.ts +2 -1
- package/dist/core/delegation/worker-actions.d.ts.map +1 -1
- package/dist/core/delegation/worker-actions.js +34 -2
- package/dist/core/delegation/worker-actions.js.map +1 -1
- package/dist/core/extensions/types.d.ts +3 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/failure-corpus.d.ts +27 -1
- package/dist/core/failure-corpus.d.ts.map +1 -1
- package/dist/core/failure-corpus.js +33 -11
- package/dist/core/failure-corpus.js.map +1 -1
- package/dist/core/model-registry.d.ts +3 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +12 -4
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/models/adaptation-store.d.ts +79 -0
- package/dist/core/models/adaptation-store.d.ts.map +1 -0
- package/dist/core/models/adaptation-store.js +196 -0
- package/dist/core/models/adaptation-store.js.map +1 -0
- package/dist/core/session-analytics.d.ts +24 -1
- package/dist/core/session-analytics.d.ts.map +1 -1
- package/dist/core/session-analytics.js +75 -0
- package/dist/core/session-analytics.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +10 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +4 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +8 -0
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/tool-repair-health.d.ts +3 -0
- package/dist/core/tool-repair-health.d.ts.map +1 -0
- package/dist/core/tool-repair-health.js +63 -0
- package/dist/core/tool-repair-health.js.map +1 -0
- package/dist/core/tool-repair-settings.d.ts +11 -0
- package/dist/core/tool-repair-settings.d.ts.map +1 -0
- package/dist/core/tool-repair-settings.js +18 -0
- package/dist/core/tool-repair-settings.js.map +1 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +0 -9
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +10 -7
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +15 -9
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +7 -3
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +21 -4
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +5 -3
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +61 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +16 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +47 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/index.md +1 -0
- package/docs/models.md +5 -1
- package/docs/rpc.md +75 -0
- package/docs/settings.md +22 -0
- package/docs/tool-repair.md +83 -0
- package/docs/usage.md +3 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +6 -4
- package/docs/bug-ledger.md +0 -134
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { compactRetainedDetails, MAX_TUI_RETAINED_DETAILS_BYTES } from \"@caupulican/pi-agent-core\";\nimport { truncateHead } from \"@caupulican/pi-agent-core/node\";\nimport { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { type ThemeBg, theme } from \"../theme/theme.ts\";\nimport { renderTitleBadge, titleBadge } from \"./tool-title.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\n// Components only use built-in definitions for display (renderers, grouping), so one\n// toolset per cwd is shared instead of allocating a full toolset per scrollback component.\nconst builtInDefinitionsByCwd = new Map<string, ReturnType<typeof createAllToolDefinitions>>();\n\nfunction getBuiltInToolDefinitions(cwd: string): ReturnType<typeof createAllToolDefinitions> {\n\tlet definitions = builtInDefinitionsByCwd.get(cwd);\n\tif (!definitions) {\n\t\tdefinitions = createAllToolDefinitions(cwd);\n\t\tbuiltInDefinitionsByCwd.set(cwd, definitions);\n\t}\n\treturn definitions;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\ttoolGroup: string | undefined;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition<any, any>[\"renderCall\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition<any, any>[\"renderResult\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate resolveToolGroup(): string | undefined {\n\t\tconst configuredGroup = this.toolDefinition?.toolGroup ?? this.builtInToolDefinition?.toolGroup;\n\t\tif (configuredGroup !== undefined) {\n\t\t\tconst trimmed = configuredGroup.trim();\n\t\t\treturn trimmed || undefined;\n\t\t}\n\t\tconst defaultGroup = this.toolName.trim();\n\t\treturn defaultGroup || undefined;\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined, toolGroupSummary = false): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t\ttoolGroupSummary,\n\t\t};\n\t}\n\n\tprivate humanizeToolName(name: string): string {\n\t\tconst words = name\n\t\t\t.replace(/[_-]+/g, \" \")\n\t\t\t.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean);\n\t\tif (words.length === 0) return name;\n\t\treturn words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(\" \");\n\t}\n\n\tprivate getDisplayLabel(): string {\n\t\tconst label = (this.toolDefinition?.label ?? this.builtInToolDefinition?.label)?.trim();\n\t\tif (this.builtInToolDefinition) return label || this.toolName;\n\t\tif (!label || label === this.toolName) return this.humanizeToolName(this.toolName);\n\t\treturn label;\n\t}\n\n\tresetInvocation(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t): void {\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(this.cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.executionStarted = false;\n\t\tthis.argsComplete = false;\n\t\tthis.isPartial = true;\n\t\tthis.result = undefined;\n\t\tthis.callRendererComponent = undefined;\n\t\tthis.resultRendererComponent = undefined;\n\t\tthis.rendererState = {};\n\t\tthis.convertedImages.clear();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate titleBadgeStatus(): \"pending\" | \"running\" | \"success\" | \"error\" {\n\t\tif (this.result?.isError) return \"error\";\n\t\tif (this.isPartial) return this.executionStarted ? \"running\" : \"pending\";\n\t\treturn \"success\";\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn titleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// The fallback also serves results whose custom renderer threw; without a\n\t\t// display bound, a renderer bug degrades into dumping the full payload.\n\t\tconst truncation = truncateHead(output);\n\t\tif (!truncation.truncated) {\n\t\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t\t}\n\t\tconst note = theme.fg(\n\t\t\t\"dim\",\n\t\t\t`[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`,\n\t\t);\n\t\treturn new Text(`${theme.fg(\"toolOutput\", truncation.content)}\\n${note}`, 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\t// Final results live in the chat scrollback for the rest of the process.\n\t\t// Oversized details would pin large payloads per tool call, so retain the\n\t\t// same compacted form a resumed session would see.\n\t\tif (!isPartial) compactRetainedDetails(result, MAX_TUI_RETAINED_DETAILS_BYTES);\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\tgetBackgroundColor(): ThemeBg {\n\t\tif (this.isPartial) return \"toolPendingBg\";\n\t\tif (this.result?.isError) return \"toolErrorBg\";\n\t\treturn \"toolSuccessBg\";\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\trenderCallSummary(width: number): string[] {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tlet component: Component;\n\t\tif (!callRenderer) {\n\t\t\tcomponent = this.createCallFallback();\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tcomponent = callRenderer(this.args, theme, this.getRenderContext(undefined, true));\n\t\t\t} catch {\n\t\t\t\tcomponent = this.createCallFallback();\n\t\t\t}\n\t\t}\n\t\treturn component.render(width);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst bgFn = (text: string) => theme.bg(this.getBackgroundColor(), text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\thasContent = true;\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = renderTitleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\t// Same display bound as createResultFallback: unknown tools must not\n\t\t\t// dump arbitrarily large payloads into the scrollback.\n\t\t\tconst truncation = truncateHead(output);\n\t\t\tif (truncation.truncated) {\n\t\t\t\ttext += `\\n${truncation.content}\\n${theme.fg(\"dim\", `[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`)}`;\n\t\t\t} else {\n\t\t\t\ttext += `\\n${output}`;\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcompactRetainedDetails,\n\tMAX_TUI_RETAINED_DETAILS_BYTES,\n\ttype ToolCallRepairInfo,\n} from \"@caupulican/pi-agent-core\";\nimport { truncateHead } from \"@caupulican/pi-agent-core/node\";\nimport { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { type ThemeBg, theme } from \"../theme/theme.ts\";\nimport { renderTitleBadge, titleBadge } from \"./tool-title.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n\trepair?: ToolCallRepairInfo;\n}\n\n// Components only use built-in definitions for display (renderers, grouping), so one\n// toolset per cwd is shared instead of allocating a full toolset per scrollback component.\nconst builtInDefinitionsByCwd = new Map<string, ReturnType<typeof createAllToolDefinitions>>();\n\nfunction getBuiltInToolDefinitions(cwd: string): ReturnType<typeof createAllToolDefinitions> {\n\tlet definitions = builtInDefinitionsByCwd.get(cwd);\n\tif (!definitions) {\n\t\tdefinitions = createAllToolDefinitions(cwd);\n\t\tbuiltInDefinitionsByCwd.set(cwd, definitions);\n\t}\n\treturn definitions;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate repair: ToolCallRepairInfo | undefined;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\ttoolGroup: string | undefined;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.repair = options.repair;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition<any, any>[\"renderCall\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition<any, any>[\"renderResult\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate resolveToolGroup(): string | undefined {\n\t\tconst configuredGroup = this.toolDefinition?.toolGroup ?? this.builtInToolDefinition?.toolGroup;\n\t\tif (configuredGroup !== undefined) {\n\t\t\tconst trimmed = configuredGroup.trim();\n\t\t\treturn trimmed || undefined;\n\t\t}\n\t\tconst defaultGroup = this.toolName.trim();\n\t\treturn defaultGroup || undefined;\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined, toolGroupSummary = false): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t\trepair: this.repair,\n\t\t\ttoolGroupSummary,\n\t\t};\n\t}\n\n\tprivate humanizeToolName(name: string): string {\n\t\tconst words = name\n\t\t\t.replace(/[_-]+/g, \" \")\n\t\t\t.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean);\n\t\tif (words.length === 0) return name;\n\t\treturn words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(\" \");\n\t}\n\n\tprivate getDisplayLabel(): string {\n\t\tconst label = (this.toolDefinition?.label ?? this.builtInToolDefinition?.label)?.trim();\n\t\tif (this.builtInToolDefinition) return label || this.toolName;\n\t\tif (!label || label === this.toolName) return this.humanizeToolName(this.toolName);\n\t\treturn label;\n\t}\n\n\tresetInvocation(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\trepair?: ToolCallRepairInfo,\n\t): void {\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.repair = repair;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(this.cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.executionStarted = false;\n\t\tthis.argsComplete = false;\n\t\tthis.isPartial = true;\n\t\tthis.result = undefined;\n\t\tthis.callRendererComponent = undefined;\n\t\tthis.resultRendererComponent = undefined;\n\t\tthis.rendererState = {};\n\t\tthis.convertedImages.clear();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate titleBadgeStatus(): \"pending\" | \"running\" | \"success\" | \"error\" {\n\t\tif (this.result?.isError) return \"error\";\n\t\tif (this.isPartial) return this.executionStarted ? \"running\" : \"pending\";\n\t\treturn \"success\";\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn titleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t}\n\n\tprivate createRepairMarker(): Component | undefined {\n\t\treturn this.repair?.repaired ? new Text(theme.fg(\"dim\", \"[repaired arguments]\"), 0, 0) : undefined;\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// The fallback also serves results whose custom renderer threw; without a\n\t\t// display bound, a renderer bug degrades into dumping the full payload.\n\t\tconst truncation = truncateHead(output);\n\t\tif (!truncation.truncated) {\n\t\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t\t}\n\t\tconst note = theme.fg(\n\t\t\t\"dim\",\n\t\t\t`[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`,\n\t\t);\n\t\treturn new Text(`${theme.fg(\"toolOutput\", truncation.content)}\\n${note}`, 0, 0);\n\t}\n\n\tupdateArgs(args: any, repair?: ToolCallRepairInfo): void {\n\t\tthis.args = args;\n\t\tthis.repair = repair;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(repair?: ToolCallRepairInfo): void {\n\t\tthis.repair = repair;\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\t// Final results live in the chat scrollback for the rest of the process.\n\t\t// Oversized details would pin large payloads per tool call, so retain the\n\t\t// same compacted form a resumed session would see.\n\t\tif (!isPartial) compactRetainedDetails(result, MAX_TUI_RETAINED_DETAILS_BYTES);\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\tgetBackgroundColor(): ThemeBg {\n\t\tif (this.isPartial) return \"toolPendingBg\";\n\t\tif (this.result?.isError) return \"toolErrorBg\";\n\t\treturn \"toolSuccessBg\";\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\trenderCallSummary(width: number): string[] {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tlet component: Component;\n\t\tif (!callRenderer) {\n\t\t\tcomponent = this.createCallFallback();\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tcomponent = callRenderer(this.args, theme, this.getRenderContext(undefined, true));\n\t\t\t} catch {\n\t\t\t\tcomponent = this.createCallFallback();\n\t\t\t}\n\t\t}\n\t\treturn component.render(width);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst bgFn = (text: string) => theme.bg(this.getBackgroundColor(), text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\thasContent = true;\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst repairMarker = this.createRepairMarker();\n\t\t\tif (repairMarker) {\n\t\t\t\trenderContainer.addChild(repairMarker);\n\t\t\t\thasContent = true;\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = renderTitleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t\tif (this.repair?.repaired) {\n\t\t\ttext += `\\n${theme.fg(\"dim\", \"[repaired arguments]\")}`;\n\t\t}\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\t// Same display bound as createResultFallback: unknown tools must not\n\t\t\t// dump arbitrarily large payloads into the scrollback.\n\t\t\tconst truncation = truncateHead(output);\n\t\t\tif (truncation.truncated) {\n\t\t\t\ttext += `\\n${truncation.content}\\n${theme.fg(\"dim\", `[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`)}`;\n\t\t\t} else {\n\t\t\t\ttext += `\\n${output}`;\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { compactRetainedDetails, MAX_TUI_RETAINED_DETAILS_BYTES } from "@caupulican/pi-agent-core";
|
|
1
|
+
import { compactRetainedDetails, MAX_TUI_RETAINED_DETAILS_BYTES, } from "@caupulican/pi-agent-core";
|
|
2
2
|
import { truncateHead } from "@caupulican/pi-agent-core/node";
|
|
3
3
|
import { Box, Container, getCapabilities, Image, Spacer, Text } from "@caupulican/pi-tui";
|
|
4
4
|
import { createAllToolDefinitions } from "../../../core/tools/index.js";
|
|
@@ -29,6 +29,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
29
29
|
toolName;
|
|
30
30
|
toolCallId;
|
|
31
31
|
args;
|
|
32
|
+
repair;
|
|
32
33
|
expanded = false;
|
|
33
34
|
showImages;
|
|
34
35
|
imageWidthCells;
|
|
@@ -48,6 +49,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
48
49
|
this.toolName = toolName;
|
|
49
50
|
this.toolCallId = toolCallId;
|
|
50
51
|
this.args = args;
|
|
52
|
+
this.repair = options.repair;
|
|
51
53
|
this.toolDefinition = toolDefinition;
|
|
52
54
|
this.builtInToolDefinition = getBuiltInToolDefinitions(cwd)[toolName];
|
|
53
55
|
this.toolGroup = this.resolveToolGroup();
|
|
@@ -126,6 +128,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
126
128
|
expanded: this.expanded,
|
|
127
129
|
showImages: this.showImages,
|
|
128
130
|
isError: this.result?.isError ?? false,
|
|
131
|
+
repair: this.repair,
|
|
129
132
|
toolGroupSummary,
|
|
130
133
|
};
|
|
131
134
|
}
|
|
@@ -148,10 +151,11 @@ export class ToolExecutionComponent extends Container {
|
|
|
148
151
|
return this.humanizeToolName(this.toolName);
|
|
149
152
|
return label;
|
|
150
153
|
}
|
|
151
|
-
resetInvocation(toolName, toolCallId, args, toolDefinition) {
|
|
154
|
+
resetInvocation(toolName, toolCallId, args, toolDefinition, repair) {
|
|
152
155
|
this.toolName = toolName;
|
|
153
156
|
this.toolCallId = toolCallId;
|
|
154
157
|
this.args = args;
|
|
158
|
+
this.repair = repair;
|
|
155
159
|
this.toolDefinition = toolDefinition;
|
|
156
160
|
this.builtInToolDefinition = getBuiltInToolDefinitions(this.cwd)[toolName];
|
|
157
161
|
this.toolGroup = this.resolveToolGroup();
|
|
@@ -178,6 +182,9 @@ export class ToolExecutionComponent extends Container {
|
|
|
178
182
|
status: this.titleBadgeStatus(),
|
|
179
183
|
});
|
|
180
184
|
}
|
|
185
|
+
createRepairMarker() {
|
|
186
|
+
return this.repair?.repaired ? new Text(theme.fg("dim", "[repaired arguments]"), 0, 0) : undefined;
|
|
187
|
+
}
|
|
181
188
|
createResultFallback() {
|
|
182
189
|
const output = this.getTextOutput();
|
|
183
190
|
if (!output) {
|
|
@@ -192,11 +199,13 @@ export class ToolExecutionComponent extends Container {
|
|
|
192
199
|
const note = theme.fg("dim", `[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`);
|
|
193
200
|
return new Text(`${theme.fg("toolOutput", truncation.content)}\n${note}`, 0, 0);
|
|
194
201
|
}
|
|
195
|
-
updateArgs(args) {
|
|
202
|
+
updateArgs(args, repair) {
|
|
196
203
|
this.args = args;
|
|
204
|
+
this.repair = repair;
|
|
197
205
|
this.updateDisplay();
|
|
198
206
|
}
|
|
199
|
-
markExecutionStarted() {
|
|
207
|
+
markExecutionStarted(repair) {
|
|
208
|
+
this.repair = repair;
|
|
200
209
|
this.executionStarted = true;
|
|
201
210
|
this.updateDisplay();
|
|
202
211
|
this.ui.requestRender();
|
|
@@ -315,6 +324,11 @@ export class ToolExecutionComponent extends Container {
|
|
|
315
324
|
hasContent = true;
|
|
316
325
|
}
|
|
317
326
|
}
|
|
327
|
+
const repairMarker = this.createRepairMarker();
|
|
328
|
+
if (repairMarker) {
|
|
329
|
+
renderContainer.addChild(repairMarker);
|
|
330
|
+
hasContent = true;
|
|
331
|
+
}
|
|
318
332
|
if (this.result) {
|
|
319
333
|
const resultRenderer = this.getResultRenderer();
|
|
320
334
|
if (!resultRenderer) {
|
|
@@ -387,6 +401,9 @@ export class ToolExecutionComponent extends Container {
|
|
|
387
401
|
label: this.getDisplayLabel(),
|
|
388
402
|
status: this.titleBadgeStatus(),
|
|
389
403
|
});
|
|
404
|
+
if (this.repair?.repaired) {
|
|
405
|
+
text += `\n${theme.fg("dim", "[repaired arguments]")}`;
|
|
406
|
+
}
|
|
390
407
|
const content = JSON.stringify(this.args, null, 2);
|
|
391
408
|
if (content) {
|
|
392
409
|
text += `\n\n${content}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { compactRetainedDetails, MAX_TUI_RETAINED_DETAILS_BYTES } from \"@caupulican/pi-agent-core\";\nimport { truncateHead } from \"@caupulican/pi-agent-core/node\";\nimport { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { type ThemeBg, theme } from \"../theme/theme.ts\";\nimport { renderTitleBadge, titleBadge } from \"./tool-title.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\n// Components only use built-in definitions for display (renderers, grouping), so one\n// toolset per cwd is shared instead of allocating a full toolset per scrollback component.\nconst builtInDefinitionsByCwd = new Map<string, ReturnType<typeof createAllToolDefinitions>>();\n\nfunction getBuiltInToolDefinitions(cwd: string): ReturnType<typeof createAllToolDefinitions> {\n\tlet definitions = builtInDefinitionsByCwd.get(cwd);\n\tif (!definitions) {\n\t\tdefinitions = createAllToolDefinitions(cwd);\n\t\tbuiltInDefinitionsByCwd.set(cwd, definitions);\n\t}\n\treturn definitions;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\ttoolGroup: string | undefined;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition<any, any>[\"renderCall\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition<any, any>[\"renderResult\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate resolveToolGroup(): string | undefined {\n\t\tconst configuredGroup = this.toolDefinition?.toolGroup ?? this.builtInToolDefinition?.toolGroup;\n\t\tif (configuredGroup !== undefined) {\n\t\t\tconst trimmed = configuredGroup.trim();\n\t\t\treturn trimmed || undefined;\n\t\t}\n\t\tconst defaultGroup = this.toolName.trim();\n\t\treturn defaultGroup || undefined;\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined, toolGroupSummary = false): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t\ttoolGroupSummary,\n\t\t};\n\t}\n\n\tprivate humanizeToolName(name: string): string {\n\t\tconst words = name\n\t\t\t.replace(/[_-]+/g, \" \")\n\t\t\t.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean);\n\t\tif (words.length === 0) return name;\n\t\treturn words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(\" \");\n\t}\n\n\tprivate getDisplayLabel(): string {\n\t\tconst label = (this.toolDefinition?.label ?? this.builtInToolDefinition?.label)?.trim();\n\t\tif (this.builtInToolDefinition) return label || this.toolName;\n\t\tif (!label || label === this.toolName) return this.humanizeToolName(this.toolName);\n\t\treturn label;\n\t}\n\n\tresetInvocation(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t): void {\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(this.cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.executionStarted = false;\n\t\tthis.argsComplete = false;\n\t\tthis.isPartial = true;\n\t\tthis.result = undefined;\n\t\tthis.callRendererComponent = undefined;\n\t\tthis.resultRendererComponent = undefined;\n\t\tthis.rendererState = {};\n\t\tthis.convertedImages.clear();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate titleBadgeStatus(): \"pending\" | \"running\" | \"success\" | \"error\" {\n\t\tif (this.result?.isError) return \"error\";\n\t\tif (this.isPartial) return this.executionStarted ? \"running\" : \"pending\";\n\t\treturn \"success\";\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn titleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// The fallback also serves results whose custom renderer threw; without a\n\t\t// display bound, a renderer bug degrades into dumping the full payload.\n\t\tconst truncation = truncateHead(output);\n\t\tif (!truncation.truncated) {\n\t\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t\t}\n\t\tconst note = theme.fg(\n\t\t\t\"dim\",\n\t\t\t`[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`,\n\t\t);\n\t\treturn new Text(`${theme.fg(\"toolOutput\", truncation.content)}\\n${note}`, 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\t// Final results live in the chat scrollback for the rest of the process.\n\t\t// Oversized details would pin large payloads per tool call, so retain the\n\t\t// same compacted form a resumed session would see.\n\t\tif (!isPartial) compactRetainedDetails(result, MAX_TUI_RETAINED_DETAILS_BYTES);\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\tgetBackgroundColor(): ThemeBg {\n\t\tif (this.isPartial) return \"toolPendingBg\";\n\t\tif (this.result?.isError) return \"toolErrorBg\";\n\t\treturn \"toolSuccessBg\";\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\trenderCallSummary(width: number): string[] {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tlet component: Component;\n\t\tif (!callRenderer) {\n\t\t\tcomponent = this.createCallFallback();\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tcomponent = callRenderer(this.args, theme, this.getRenderContext(undefined, true));\n\t\t\t} catch {\n\t\t\t\tcomponent = this.createCallFallback();\n\t\t\t}\n\t\t}\n\t\treturn component.render(width);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst bgFn = (text: string) => theme.bg(this.getBackgroundColor(), text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\thasContent = true;\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = renderTitleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\t// Same display bound as createResultFallback: unknown tools must not\n\t\t\t// dump arbitrarily large payloads into the scrollback.\n\t\t\tconst truncation = truncateHead(output);\n\t\t\tif (truncation.truncated) {\n\t\t\t\ttext += `\\n${truncation.content}\\n${theme.fg(\"dim\", `[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`)}`;\n\t\t\t} else {\n\t\t\t\ttext += `\\n${output}`;\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcompactRetainedDetails,\n\tMAX_TUI_RETAINED_DETAILS_BYTES,\n\ttype ToolCallRepairInfo,\n} from \"@caupulican/pi-agent-core\";\nimport { truncateHead } from \"@caupulican/pi-agent-core/node\";\nimport { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@caupulican/pi-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { type ThemeBg, theme } from \"../theme/theme.ts\";\nimport { renderTitleBadge, titleBadge } from \"./tool-title.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n\trepair?: ToolCallRepairInfo;\n}\n\n// Components only use built-in definitions for display (renderers, grouping), so one\n// toolset per cwd is shared instead of allocating a full toolset per scrollback component.\nconst builtInDefinitionsByCwd = new Map<string, ReturnType<typeof createAllToolDefinitions>>();\n\nfunction getBuiltInToolDefinitions(cwd: string): ReturnType<typeof createAllToolDefinitions> {\n\tlet definitions = builtInDefinitionsByCwd.get(cwd);\n\tif (!definitions) {\n\t\tdefinitions = createAllToolDefinitions(cwd);\n\t\tbuiltInDefinitionsByCwd.set(cwd, definitions);\n\t}\n\treturn definitions;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate repair: ToolCallRepairInfo | undefined;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\ttoolGroup: string | undefined;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.repair = options.repair;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition<any, any>[\"renderCall\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition<any, any>[\"renderResult\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate resolveToolGroup(): string | undefined {\n\t\tconst configuredGroup = this.toolDefinition?.toolGroup ?? this.builtInToolDefinition?.toolGroup;\n\t\tif (configuredGroup !== undefined) {\n\t\t\tconst trimmed = configuredGroup.trim();\n\t\t\treturn trimmed || undefined;\n\t\t}\n\t\tconst defaultGroup = this.toolName.trim();\n\t\treturn defaultGroup || undefined;\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined, toolGroupSummary = false): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t\trepair: this.repair,\n\t\t\ttoolGroupSummary,\n\t\t};\n\t}\n\n\tprivate humanizeToolName(name: string): string {\n\t\tconst words = name\n\t\t\t.replace(/[_-]+/g, \" \")\n\t\t\t.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean);\n\t\tif (words.length === 0) return name;\n\t\treturn words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(\" \");\n\t}\n\n\tprivate getDisplayLabel(): string {\n\t\tconst label = (this.toolDefinition?.label ?? this.builtInToolDefinition?.label)?.trim();\n\t\tif (this.builtInToolDefinition) return label || this.toolName;\n\t\tif (!label || label === this.toolName) return this.humanizeToolName(this.toolName);\n\t\treturn label;\n\t}\n\n\tresetInvocation(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\ttoolDefinition: ToolDefinition<any, any> | undefined,\n\t\trepair?: ToolCallRepairInfo,\n\t): void {\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.repair = repair;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = getBuiltInToolDefinitions(this.cwd)[toolName as ToolName];\n\t\tthis.toolGroup = this.resolveToolGroup();\n\t\tthis.executionStarted = false;\n\t\tthis.argsComplete = false;\n\t\tthis.isPartial = true;\n\t\tthis.result = undefined;\n\t\tthis.callRendererComponent = undefined;\n\t\tthis.resultRendererComponent = undefined;\n\t\tthis.rendererState = {};\n\t\tthis.convertedImages.clear();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate titleBadgeStatus(): \"pending\" | \"running\" | \"success\" | \"error\" {\n\t\tif (this.result?.isError) return \"error\";\n\t\tif (this.isPartial) return this.executionStarted ? \"running\" : \"pending\";\n\t\treturn \"success\";\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn titleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t}\n\n\tprivate createRepairMarker(): Component | undefined {\n\t\treturn this.repair?.repaired ? new Text(theme.fg(\"dim\", \"[repaired arguments]\"), 0, 0) : undefined;\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// The fallback also serves results whose custom renderer threw; without a\n\t\t// display bound, a renderer bug degrades into dumping the full payload.\n\t\tconst truncation = truncateHead(output);\n\t\tif (!truncation.truncated) {\n\t\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t\t}\n\t\tconst note = theme.fg(\n\t\t\t\"dim\",\n\t\t\t`[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`,\n\t\t);\n\t\treturn new Text(`${theme.fg(\"toolOutput\", truncation.content)}\\n${note}`, 0, 0);\n\t}\n\n\tupdateArgs(args: any, repair?: ToolCallRepairInfo): void {\n\t\tthis.args = args;\n\t\tthis.repair = repair;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(repair?: ToolCallRepairInfo): void {\n\t\tthis.repair = repair;\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\t// Final results live in the chat scrollback for the rest of the process.\n\t\t// Oversized details would pin large payloads per tool call, so retain the\n\t\t// same compacted form a resumed session would see.\n\t\tif (!isPartial) compactRetainedDetails(result, MAX_TUI_RETAINED_DETAILS_BYTES);\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\tgetBackgroundColor(): ThemeBg {\n\t\tif (this.isPartial) return \"toolPendingBg\";\n\t\tif (this.result?.isError) return \"toolErrorBg\";\n\t\treturn \"toolSuccessBg\";\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\trenderCallSummary(width: number): string[] {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tlet component: Component;\n\t\tif (!callRenderer) {\n\t\t\tcomponent = this.createCallFallback();\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tcomponent = callRenderer(this.args, theme, this.getRenderContext(undefined, true));\n\t\t\t} catch {\n\t\t\t\tcomponent = this.createCallFallback();\n\t\t\t}\n\t\t}\n\t\treturn component.render(width);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\t\treturn super.render(width);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst bgFn = (text: string) => theme.bg(this.getBackgroundColor(), text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\thasContent = true;\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst repairMarker = this.createRepairMarker();\n\t\t\tif (repairMarker) {\n\t\t\t\trenderContainer.addChild(repairMarker);\n\t\t\t\thasContent = true;\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = renderTitleBadge(theme, {\n\t\t\tlabel: this.getDisplayLabel(),\n\t\t\tstatus: this.titleBadgeStatus(),\n\t\t});\n\t\tif (this.repair?.repaired) {\n\t\t\ttext += `\\n${theme.fg(\"dim\", \"[repaired arguments]\")}`;\n\t\t}\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\t// Same display bound as createResultFallback: unknown tools must not\n\t\t\t// dump arbitrarily large payloads into the scrollback.\n\t\t\tconst truncation = truncateHead(output);\n\t\t\tif (truncation.truncated) {\n\t\t\t\ttext += `\\n${truncation.content}\\n${theme.fg(\"dim\", `[output truncated for display: showing ${truncation.outputLines} lines; the full result is retained in the conversation]`)}`;\n\t\t\t} else {\n\t\t\t\ttext += `\\n${output}`;\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-editor.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,eAAe,CAAC,CAAC;IAC3D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;
|
|
1
|
+
{"version":3,"file":"external-editor.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,eAAe,CAAC,CAAC;IAC3D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAMD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDhF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiDpG","sourcesContent":["/**\n * External-editor launch flows extracted from interactive-mode.\n *\n * `openExternalEditor` edits the current editor buffer in `$VISUAL`/`$EDITOR`;\n * `openEditorForPath` opens an arbitrary file (falling back to `vi`). Both stop\n * the TUI to release the terminal, spawn the editor, and restart the TUI with a\n * forced full re-render. They operate through a narrow `ExternalEditorHost` seam;\n * interactive-mode keeps thin delegating wrappers.\n */\n\nimport { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { EditorComponent, TUI } from \"@caupulican/pi-tui\";\n\nexport interface ExternalEditorHost {\n\treadonly editor: EditorComponent;\n\treadonly ui: Pick<TUI, \"stop\" | \"start\" | \"requestRender\">;\n\tshowWarning(message: string): void;\n}\n\nfunction resolveEditorCommand(): string | undefined {\n\treturn process.env.VISUAL || process.env.EDITOR;\n}\n\nexport async function openExternalEditor(host: ExternalEditorHost): Promise<void> {\n\tconst editorCmd = resolveEditorCommand();\n\tif (!editorCmd) {\n\t\thost.showWarning(\"No editor configured. Set $VISUAL or $EDITOR environment variable.\");\n\t\treturn;\n\t}\n\n\tconst currentText = host.editor.getExpandedText?.() ?? host.editor.getText();\n\tconst tmpFile = path.join(os.tmpdir(), `pi-editor-${Date.now()}.pi.md`);\n\n\ttry {\n\t\t// Write current content to temp file\n\t\tfs.writeFileSync(tmpFile, currentText, \"utf-8\");\n\n\t\t// Stop TUI to release terminal\n\t\thost.ui.stop();\n\n\t\t// Split by space to support editor arguments (e.g., \"code --wait\")\n\t\tconst [editor, ...editorArgs] = editorCmd.split(\" \");\n\n\t\tprocess.stdout.write(`Launching external editor: ${editorCmd}\\nPi will resume when the editor exits.\\n`);\n\n\t\t// Do not use spawnSync here. On Windows, synchronous child_process calls can keep\n\t\t// Node/libuv's console input read active after ui.stop() pauses stdin, racing\n\t\t// vim/nvim for the console input buffer until Ctrl+C cancels the pending read.\n\t\tconst status = await new Promise<number | null>((resolve) => {\n\t\t\tconst child = spawn(editor, [...editorArgs, tmpFile], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: process.platform === \"win32\",\n\t\t\t});\n\t\t\tchild.on(\"error\", () => resolve(null));\n\t\t\tchild.on(\"close\", (code) => resolve(code));\n\t\t});\n\n\t\t// On successful exit (status 0), replace editor content\n\t\tif (status === 0) {\n\t\t\tconst newContent = fs.readFileSync(tmpFile, \"utf-8\").replace(/\\n$/, \"\");\n\t\t\thost.editor.setText(newContent);\n\t\t}\n\t\t// On non-zero exit, keep original text (no action needed)\n\t} finally {\n\t\t// Clean up temp file\n\t\ttry {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\n\t\t// Restart TUI\n\t\thost.ui.start();\n\t\t// Force full re-render since external editor uses alternate screen\n\t\thost.ui.requestRender(true);\n\t}\n}\n\nexport async function openEditorForPath(host: ExternalEditorHost, filePath: string): Promise<boolean> {\n\tlet editorCmd = resolveEditorCommand();\n\tlet isFallback = false;\n\tif (!editorCmd) {\n\t\teditorCmd = \"vi\";\n\t\tisFallback = true;\n\t}\n\n\ttry {\n\t\t// Stop TUI to release terminal\n\t\thost.ui.stop();\n\n\t\t// Split by space to support editor arguments (e.g., \"code --wait\")\n\t\tconst [editor, ...editorArgs] = editorCmd.split(\" \");\n\n\t\tprocess.stdout.write(\n\t\t\t`Launching external editor: ${editorCmd} ${filePath}\\nPi will resume when the editor exits.\\n`,\n\t\t);\n\n\t\tconst status = await new Promise<number | null>((resolve) => {\n\t\t\tconst child = spawn(editor, [...editorArgs, filePath], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: process.platform === \"win32\",\n\t\t\t});\n\t\t\tchild.on(\"error\", () => resolve(null));\n\t\t\tchild.on(\"close\", (code) => resolve(code));\n\t\t});\n\n\t\tif (status === null) {\n\t\t\tif (isFallback) {\n\t\t\t\tprocess.stdout.write(`\\nError: Failed to launch fallback editor \"vi\".\\n`);\n\t\t\t} else {\n\t\t\t\tprocess.stdout.write(`\\nError: Failed to launch editor \"${editorCmd}\".\\n`);\n\t\t\t}\n\t\t\tprocess.stdout.write(`Please set the $EDITOR or $VISUAL environment variable to edit inline.\\n`);\n\t\t\tprocess.stdout.write(`Absolute file path: ${filePath}\\n\\nPress Enter to return to Pi...`);\n\t\t\t// Wait for enter key\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tprocess.stdin.once(\"data\", () => resolve());\n\t\t\t});\n\t\t}\n\n\t\treturn status === 0;\n\t} finally {\n\t\t// Restart TUI\n\t\thost.ui.start();\n\t\t// Force full re-render since external editor uses alternate screen\n\t\thost.ui.requestRender(true);\n\t}\n}\n"]}
|
|
@@ -11,9 +11,11 @@ import { spawn } from "node:child_process";
|
|
|
11
11
|
import * as fs from "node:fs";
|
|
12
12
|
import * as os from "node:os";
|
|
13
13
|
import * as path from "node:path";
|
|
14
|
+
function resolveEditorCommand() {
|
|
15
|
+
return process.env.VISUAL || process.env.EDITOR;
|
|
16
|
+
}
|
|
14
17
|
export async function openExternalEditor(host) {
|
|
15
|
-
|
|
16
|
-
const editorCmd = process.env.VISUAL || process.env.EDITOR;
|
|
18
|
+
const editorCmd = resolveEditorCommand();
|
|
17
19
|
if (!editorCmd) {
|
|
18
20
|
host.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable.");
|
|
19
21
|
return;
|
|
@@ -61,7 +63,7 @@ export async function openExternalEditor(host) {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
export async function openEditorForPath(host, filePath) {
|
|
64
|
-
let editorCmd =
|
|
66
|
+
let editorCmd = resolveEditorCommand();
|
|
65
67
|
let isFallback = false;
|
|
66
68
|
if (!editorCmd) {
|
|
67
69
|
editorCmd = "vi";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-editor.js","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AASlC,
|
|
1
|
+
{"version":3,"file":"external-editor.js","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * External-editor launch flows extracted from interactive-mode.\n *\n * `openExternalEditor` edits the current editor buffer in `$VISUAL`/`$EDITOR`;\n * `openEditorForPath` opens an arbitrary file (falling back to `vi`). Both stop\n * the TUI to release the terminal, spawn the editor, and restart the TUI with a\n * forced full re-render. They operate through a narrow `ExternalEditorHost` seam;\n * interactive-mode keeps thin delegating wrappers.\n */\n\nimport { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { EditorComponent, TUI } from \"@caupulican/pi-tui\";\n\nexport interface ExternalEditorHost {\n\treadonly editor: EditorComponent;\n\treadonly ui: Pick<TUI, \"stop\" | \"start\" | \"requestRender\">;\n\tshowWarning(message: string): void;\n}\n\nfunction resolveEditorCommand(): string | undefined {\n\treturn process.env.VISUAL || process.env.EDITOR;\n}\n\nexport async function openExternalEditor(host: ExternalEditorHost): Promise<void> {\n\tconst editorCmd = resolveEditorCommand();\n\tif (!editorCmd) {\n\t\thost.showWarning(\"No editor configured. Set $VISUAL or $EDITOR environment variable.\");\n\t\treturn;\n\t}\n\n\tconst currentText = host.editor.getExpandedText?.() ?? host.editor.getText();\n\tconst tmpFile = path.join(os.tmpdir(), `pi-editor-${Date.now()}.pi.md`);\n\n\ttry {\n\t\t// Write current content to temp file\n\t\tfs.writeFileSync(tmpFile, currentText, \"utf-8\");\n\n\t\t// Stop TUI to release terminal\n\t\thost.ui.stop();\n\n\t\t// Split by space to support editor arguments (e.g., \"code --wait\")\n\t\tconst [editor, ...editorArgs] = editorCmd.split(\" \");\n\n\t\tprocess.stdout.write(`Launching external editor: ${editorCmd}\\nPi will resume when the editor exits.\\n`);\n\n\t\t// Do not use spawnSync here. On Windows, synchronous child_process calls can keep\n\t\t// Node/libuv's console input read active after ui.stop() pauses stdin, racing\n\t\t// vim/nvim for the console input buffer until Ctrl+C cancels the pending read.\n\t\tconst status = await new Promise<number | null>((resolve) => {\n\t\t\tconst child = spawn(editor, [...editorArgs, tmpFile], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: process.platform === \"win32\",\n\t\t\t});\n\t\t\tchild.on(\"error\", () => resolve(null));\n\t\t\tchild.on(\"close\", (code) => resolve(code));\n\t\t});\n\n\t\t// On successful exit (status 0), replace editor content\n\t\tif (status === 0) {\n\t\t\tconst newContent = fs.readFileSync(tmpFile, \"utf-8\").replace(/\\n$/, \"\");\n\t\t\thost.editor.setText(newContent);\n\t\t}\n\t\t// On non-zero exit, keep original text (no action needed)\n\t} finally {\n\t\t// Clean up temp file\n\t\ttry {\n\t\t\tfs.unlinkSync(tmpFile);\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\n\t\t// Restart TUI\n\t\thost.ui.start();\n\t\t// Force full re-render since external editor uses alternate screen\n\t\thost.ui.requestRender(true);\n\t}\n}\n\nexport async function openEditorForPath(host: ExternalEditorHost, filePath: string): Promise<boolean> {\n\tlet editorCmd = resolveEditorCommand();\n\tlet isFallback = false;\n\tif (!editorCmd) {\n\t\teditorCmd = \"vi\";\n\t\tisFallback = true;\n\t}\n\n\ttry {\n\t\t// Stop TUI to release terminal\n\t\thost.ui.stop();\n\n\t\t// Split by space to support editor arguments (e.g., \"code --wait\")\n\t\tconst [editor, ...editorArgs] = editorCmd.split(\" \");\n\n\t\tprocess.stdout.write(\n\t\t\t`Launching external editor: ${editorCmd} ${filePath}\\nPi will resume when the editor exits.\\n`,\n\t\t);\n\n\t\tconst status = await new Promise<number | null>((resolve) => {\n\t\t\tconst child = spawn(editor, [...editorArgs, filePath], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: process.platform === \"win32\",\n\t\t\t});\n\t\t\tchild.on(\"error\", () => resolve(null));\n\t\t\tchild.on(\"close\", (code) => resolve(code));\n\t\t});\n\n\t\tif (status === null) {\n\t\t\tif (isFallback) {\n\t\t\t\tprocess.stdout.write(`\\nError: Failed to launch fallback editor \"vi\".\\n`);\n\t\t\t} else {\n\t\t\t\tprocess.stdout.write(`\\nError: Failed to launch editor \"${editorCmd}\".\\n`);\n\t\t\t}\n\t\t\tprocess.stdout.write(`Please set the $EDITOR or $VISUAL environment variable to edit inline.\\n`);\n\t\t\tprocess.stdout.write(`Absolute file path: ${filePath}\\n\\nPress Enter to return to Pi...`);\n\t\t\t// Wait for enter key\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tprocess.stdin.once(\"data\", () => resolve());\n\t\t\t});\n\t\t}\n\n\t\treturn status === 0;\n\t} finally {\n\t\t// Restart TUI\n\t\thost.ui.start();\n\t\t// Force full re-render since external editor uses alternate screen\n\t\thost.ui.requestRender(true);\n\t}\n}\n"]}
|
|
@@ -191,6 +191,7 @@ export declare class InteractiveMode {
|
|
|
191
191
|
private getSessionEntryCount;
|
|
192
192
|
private showDeferredHistoryPlaceholder;
|
|
193
193
|
private loadTuiHistoryOnDemand;
|
|
194
|
+
private getToolCallRepairInfo;
|
|
194
195
|
private attachStreamingToolPanels;
|
|
195
196
|
private applyStreamingMessageUpdate;
|
|
196
197
|
private trimLiveTuiHistory;
|