fix(coding-agent): honor custom renderers for built-in tool overrides closes #2595
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
### Fixed
|
||||
|
||||
- Fixed auto-compaction overflow recovery for Ollama models when the backend returns explicit `prompt too long; exceeded max context length ...` errors instead of silently truncating input ([#2626](https://github.com/badlogic/pi-mono/issues/2626))
|
||||
- Fixed built-in tool overrides that reuse built-in parameter schemas to still honor custom `renderCall` and `renderResult` renderers in the interactive TUI, restoring the `minimal-mode` example ([#2595](https://github.com/badlogic/pi-mono/issues/2595))
|
||||
|
||||
## [0.63.0] - 2026-03-27
|
||||
|
||||
|
||||
@@ -72,19 +72,11 @@ export class ToolExecutionComponent extends Container {
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
private isBuiltInDefinition(definition: ToolDefinition<any, any> | undefined): boolean {
|
||||
return (
|
||||
definition !== undefined &&
|
||||
this.builtInToolDefinition !== undefined &&
|
||||
definition.parameters === this.builtInToolDefinition.parameters
|
||||
);
|
||||
}
|
||||
|
||||
private getCallRenderer(): ToolDefinition<any, any>["renderCall"] | undefined {
|
||||
if (!this.builtInToolDefinition) {
|
||||
return this.toolDefinition?.renderCall;
|
||||
}
|
||||
if (!this.toolDefinition || this.isBuiltInDefinition(this.toolDefinition)) {
|
||||
if (!this.toolDefinition) {
|
||||
return this.builtInToolDefinition.renderCall;
|
||||
}
|
||||
return this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;
|
||||
@@ -94,7 +86,7 @@ export class ToolExecutionComponent extends Container {
|
||||
if (!this.builtInToolDefinition) {
|
||||
return this.toolDefinition?.renderResult;
|
||||
}
|
||||
if (!this.toolDefinition || this.isBuiltInDefinition(this.toolDefinition)) {
|
||||
if (!this.toolDefinition) {
|
||||
return this.builtInToolDefinition.renderResult;
|
||||
}
|
||||
return this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;
|
||||
|
||||
@@ -4,7 +4,7 @@ import stripAnsi from "strip-ansi";
|
||||
import { beforeAll, describe, expect, test } from "vitest";
|
||||
import type { ToolDefinition } from "../src/core/extensions/types.js";
|
||||
import { type BashOperations, createBashToolDefinition } from "../src/core/tools/bash.js";
|
||||
import { createReadToolDefinition } from "../src/core/tools/read.js";
|
||||
import { createReadTool, createReadToolDefinition } from "../src/core/tools/read.js";
|
||||
import { createWriteToolDefinition } from "../src/core/tools/write.js";
|
||||
import { ToolExecutionComponent } from "../src/modes/interactive/components/tool-execution.js";
|
||||
import { initTheme } from "../src/modes/interactive/theme/theme.js";
|
||||
@@ -166,6 +166,48 @@ describe("ToolExecutionComponent parity", () => {
|
||||
expect(rendered).toContain("override result");
|
||||
});
|
||||
|
||||
test("uses custom renderers for built-in overrides that reuse built-in definition parameters", () => {
|
||||
const builtInDefinition = createReadToolDefinition(process.cwd());
|
||||
const component = new ToolExecutionComponent(
|
||||
"read",
|
||||
"tool-4d",
|
||||
{ path: "README.md" },
|
||||
{},
|
||||
{
|
||||
...builtInDefinition,
|
||||
renderCall: () => new Text("override call", 0, 0),
|
||||
renderResult: () => new Text("override result", 0, 0),
|
||||
},
|
||||
createFakeTui(),
|
||||
);
|
||||
component.updateResult({ content: [{ type: "text", text: "hello" }], details: undefined, isError: false }, false);
|
||||
const rendered = stripAnsi(component.render(120).join("\n"));
|
||||
expect(rendered).toContain("override call");
|
||||
expect(rendered).toContain("override result");
|
||||
expect(rendered).not.toContain("read README.md");
|
||||
});
|
||||
|
||||
test("uses custom renderers for built-in overrides that reuse wrapped built-in tool parameters", () => {
|
||||
const builtInTool = createReadTool(process.cwd());
|
||||
const component = new ToolExecutionComponent(
|
||||
"read",
|
||||
"tool-4e",
|
||||
{ path: "README.md" },
|
||||
{},
|
||||
{
|
||||
...createBaseToolDefinition("read"),
|
||||
parameters: builtInTool.parameters,
|
||||
renderCall: () => new Text("wrapped override call", 0, 0),
|
||||
renderResult: () => new Text("wrapped override result", 0, 0),
|
||||
},
|
||||
createFakeTui(),
|
||||
);
|
||||
component.updateResult({ content: [{ type: "text", text: "hello" }], details: undefined, isError: false }, false);
|
||||
const rendered = stripAnsi(component.render(120).join("\n"));
|
||||
expect(rendered).toContain("wrapped override call");
|
||||
expect(rendered).toContain("wrapped override result");
|
||||
});
|
||||
|
||||
test("shares renderer state across custom call and result slots", () => {
|
||||
type RenderState = { token?: string };
|
||||
const toolDefinition: ToolDefinition<any, unknown, RenderState> = {
|
||||
|
||||
Reference in New Issue
Block a user