+ `;
+ }
+
+ // Success: show expression = result in header
+ return renderHeader(state, Calculator, `${params.expression} = ${output}`);
}
- return html`
-
- ${i18n("Calculating")}
- ${params.expression}
-
- `;
- }
-
- renderResult(_params: CalculateParams, result: ToolResultMessage): TemplateResult {
- // Parse the output to make it look nicer
- const output = result.output || "";
- const isError = result.isError === true;
-
- if (isError) {
- return html`
${output}
`;
+ // Full params, no result: just show header with expression in it
+ if (params?.expression) {
+ return renderHeader(state, Calculator, `${i18n("Calculating")} ${params.expression}`);
}
- // Try to split on = to show expression and result separately
- const parts = output.split(" = ");
- if (parts.length === 2) {
- return html`
-
- ${parts[0]}
- =
- ${parts[1]}
-
- `;
+ // Partial params (empty expression), no result
+ if (params && !params.expression) {
+ return renderHeader(state, Calculator, i18n("Writing expression..."));
}
- // Fallback to showing the whole output
- return html`
${output}
`;
+ // No params, no result
+ return renderHeader(state, Calculator, i18n("Waiting for expression..."));
}
}
diff --git a/packages/web-ui/src/tools/renderers/DefaultRenderer.ts b/packages/web-ui/src/tools/renderers/DefaultRenderer.ts
index dd15e028..8bed4dca 100644
--- a/packages/web-ui/src/tools/renderers/DefaultRenderer.ts
+++ b/packages/web-ui/src/tools/renderers/DefaultRenderer.ts
@@ -4,33 +4,34 @@ import { i18n } from "../../utils/i18n.js";
import type { ToolRenderer } from "../types.js";
export class DefaultRenderer implements ToolRenderer {
- renderParams(params: any, isStreaming?: boolean): TemplateResult {
- let text: string;
- let isJson = false;
+ render(params: any | undefined, result: ToolResultMessage | undefined, isStreaming?: boolean): TemplateResult {
+ // Show result if available
+ if (result) {
+ const text = result.output || i18n("(no output)");
+ return html`
${text}
`;
+ }
- try {
- text = JSON.stringify(JSON.parse(params), null, 2);
- isJson = true;
- } catch {
+ // Show params
+ if (params) {
+ let text: string;
try {
- text = JSON.stringify(params, null, 2);
- isJson = true;
+ text = JSON.stringify(JSON.parse(params), null, 2);
} catch {
- text = String(params);
+ try {
+ text = JSON.stringify(params, null, 2);
+ } catch {
+ text = String(params);
+ }
}
+
+ if (isStreaming && (!text || text === "{}" || text === "null")) {
+ return html`
${i18n("Preparing tool parameters...")}
`;
+ }
+
+ return html``;
}
- if (isStreaming && (!text || text === "{}" || text === "null")) {
- return html`
${i18n("Preparing tool parameters...")}
`;
- }
-
- return html``;
- }
-
- renderResult(_params: any, result: ToolResultMessage): TemplateResult {
- // Just show the output field - that's what was sent to the LLM
- const text = result.output || i18n("(no output)");
-
- return html`
${text}
`;
+ // No params or result yet
+ return html`
${i18n("Preparing tool...")}
`;
}
}
diff --git a/packages/web-ui/src/tools/renderers/GetCurrentTimeRenderer.ts b/packages/web-ui/src/tools/renderers/GetCurrentTimeRenderer.ts
index db2d629b..20fd4bf1 100644
--- a/packages/web-ui/src/tools/renderers/GetCurrentTimeRenderer.ts
+++ b/packages/web-ui/src/tools/renderers/GetCurrentTimeRenderer.ts
@@ -1,6 +1,8 @@
import { html, type TemplateResult } from "@mariozechner/mini-lit";
import type { ToolResultMessage } from "@mariozechner/pi-ai";
+import { Clock } from "lucide";
import { i18n } from "../../utils/i18n.js";
+import { renderHeader } from "../renderer-registry.js";
import type { ToolRenderer } from "../types.js";
interface GetCurrentTimeParams {
@@ -9,31 +11,59 @@ interface GetCurrentTimeParams {
// GetCurrentTime tool has undefined details (only uses output)
export class GetCurrentTimeRenderer implements ToolRenderer {
- renderParams(params: GetCurrentTimeParams, isStreaming?: boolean): TemplateResult {
- if (params.timezone) {
- return html`
-
- ${i18n("Getting current time in")}
- ${params.timezone}
-
- `;
- }
- return html`
-
- ${i18n("Getting current date and time")}${isStreaming ? "..." : ""}
-
- `;
- }
+ render(params: GetCurrentTimeParams | undefined, result: ToolResultMessage | undefined): TemplateResult {
+ const state = result ? (result.isError ? "error" : "complete") : "inprogress";
- renderResult(_params: GetCurrentTimeParams, result: ToolResultMessage): TemplateResult {
- const output = result.output || "";
- const isError = result.isError === true;
+ // Full params + full result
+ if (result && params) {
+ const output = result.output || "";
+ const headerText = params.timezone
+ ? `${i18n("Getting current time in")} ${params.timezone}`
+ : i18n("Getting current date and time");
- if (isError) {
- return html`
${output}
`;
+ // Error: show header, error below
+ if (result.isError) {
+ return html`
+
+ ${renderHeader(state, Clock, headerText)}
+
${output}
+
+ `;
+ }
+
+ // Success: show time in header
+ return renderHeader(state, Clock, `${headerText}: ${output}`);
}
- // Display the date/time result
- return html`
${output}
`;
+ // Full result, no params
+ if (result) {
+ const output = result.output || "";
+
+ // Error: show header, error below
+ if (result.isError) {
+ return html`
+
+ ${renderHeader(state, Clock, i18n("Getting current date and time"))}
+