import { Type, type Static } from "typebox"; import type { AgentToolResult, ExtensionContext, ToolDefinition } from "@earendil-works/pi-coding-agent"; import { normalizeNotification } from "./notify-protocol.ts"; import { sendNotification } from "./send.ts"; export const notifyToolSchema = Type.Object({ title: Type.Optional(Type.String({ maxLength: 256 })), body: Type.Optional(Type.String({ maxLength: 4096 })), urgency: Type.Optional(Type.Union([Type.Literal("low"), Type.Literal("normal"), Type.Literal("critical")])), }); export type NotifyToolParams = Static; export function createNotifyTool( notify: (payload: unknown) => void = sendNotification, ): ToolDefinition { return { name: "notify", label: "notify", description: "Show a best-effort terminal or desktop notification to the user.", promptSnippet: "Show a notification to the user", parameters: notifyToolSchema, async execute( _toolCallId: string, params: NotifyToolParams, _signal: AbortSignal | undefined, _onUpdate: undefined, ctx: ExtensionContext, ): Promise> { if (ctx.mode !== "tui") { return { content: [{ type: "text", text: "Notifications are available only in TUI mode." }], details: undefined }; } const normalized = normalizeNotification(params); if (!normalized) { return { content: [{ type: "text", text: "Notification payload was invalid or exceeded its limits." }], details: undefined }; } notify(normalized); return { content: [{ type: "text", text: "Notification sent on a best-effort basis." }], details: undefined }; }, }; }