Files
oh-my-pi/packages/coding-agent/src/tools/render-mermaid.ts
T
can1357 a21a542afd refactor(prompt-templates): migrated prompt utilities to pi-utils package
- Extracted prompt rendering and formatting utilities from coding-agent to centralized pi-utils package with new API surface (prompt.render, prompt.format, prompt.registerHelper).
- Migrated parseFrontmatter utility from coding-agent to pi-utils package; updated 8 files to import from @oh-my-pi/pi-utils.
- Removed 170-line prompt-format.ts module and consolidated 192 lines of Handlebars helper registrations into pi-utils prompt module.
- Updated 60+ files across coding-agent and typescript-edit-benchmark to use new prompt.render() and prompt.format() API from pi-utils.
- Simplified prompt-templates.ts by delegating core functionality to pi-utils while retaining custom helper registrations (jtdToTypeScript, jsonStringify, etc.).
2026-04-08 05:47:35 +02:00

67 lines
2.5 KiB
TypeScript

import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
import { type MermaidAsciiRenderOptions, prompt, renderMermaidAscii } from "@oh-my-pi/pi-utils";
import { type Static, Type } from "@sinclair/typebox";
import renderMermaidDescription from "../prompts/tools/render-mermaid.md" with { type: "text" };
import type { ToolSession } from "./index";
const renderMermaidSchema = Type.Object({
mermaid: Type.String({ description: "Mermaid graph source text" }),
config: Type.Optional(
Type.Object({
useAscii: Type.Optional(Type.Boolean()),
paddingX: Type.Optional(Type.Number()),
paddingY: Type.Optional(Type.Number()),
boxBorderPadding: Type.Optional(Type.Number()),
}),
),
});
type RenderMermaidParams = Static<typeof renderMermaidSchema>;
function sanitizeRenderConfig(config: MermaidAsciiRenderOptions | undefined): MermaidAsciiRenderOptions | undefined {
if (!config) return undefined;
return {
useAscii: config.useAscii,
boxBorderPadding:
config.boxBorderPadding === undefined ? undefined : Math.max(0, Math.floor(config.boxBorderPadding)),
paddingX: config.paddingX === undefined ? undefined : Math.max(0, Math.floor(config.paddingX)),
paddingY: config.paddingY === undefined ? undefined : Math.max(0, Math.floor(config.paddingY)),
};
}
export interface RenderMermaidToolDetails {
artifactId?: string;
}
export class RenderMermaidTool implements AgentTool<typeof renderMermaidSchema, RenderMermaidToolDetails> {
readonly name = "render_mermaid";
readonly label = "RenderMermaid";
readonly description: string;
readonly parameters = renderMermaidSchema;
readonly strict = true;
constructor(private readonly session: ToolSession) {
this.description = prompt.render(renderMermaidDescription);
}
async execute(
_toolCallId: string,
params: RenderMermaidParams,
_signal?: AbortSignal,
_onUpdate?: AgentToolUpdateCallback<RenderMermaidToolDetails>,
_context?: AgentToolContext,
): Promise<AgentToolResult<RenderMermaidToolDetails>> {
const ascii = renderMermaidAscii(params.mermaid, sanitizeRenderConfig(params.config));
const { path: artifactPath, id: artifactId } =
(await this.session.allocateOutputArtifact?.("render_mermaid")) ?? {};
if (artifactPath) {
await Bun.write(artifactPath, ascii);
}
const artifactLine = artifactId ? `\n\nSaved artifact: artifact://${artifactId}` : "";
return {
content: [{ type: "text", text: `${ascii}${artifactLine}` }],
details: { artifactId },
};
}
}