import { Type } from "typebox"; import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent"; import { findSharedResult, readResultPage, type ResultStream } from "./results.ts"; function text(text: string) { return { content: [{ type: "text" as const, text }], details: undefined }; } export function registerAxiTools(pi: ExtensionAPI): void { pi.registerTool({ name: "axi_read", label: "AXI read", description: "Read pages from a saved AXI result.", parameters: Type.Object({ result: Type.String(), stream: Type.Optional(Type.Union([Type.Literal("stdout"), Type.Literal("stderr"), Type.Literal("formatted")])), offset: Type.Optional(Type.Integer({ minimum: 0 })), limit: Type.Optional(Type.Integer({ minimum: 4, maximum: 32 * 1024 })) }), async execute(_id: string, params: { result: string; stream?: ResultStream; offset?: number; limit?: number }, _signal: AbortSignal | undefined, _onUpdate: unknown, ctx: ExtensionContext) { const reference = await findSharedResult(ctx.sessionManager.getEntries(), params.result); if (!reference) throw new Error("result is not available in this session"); const stream = params.stream ?? "formatted"; const page = await readResultPage(reference, stream, { offset: params.offset, limit: params.limit }); const pageDetails = Object.fromEntries(Object.entries(page).filter(([key]) => key !== "text")); Object.assign(pageDetails, { format: reference.format, captureComplete: reference.captureComplete }); const marker = `[axi_read result=${reference.id} stream=${stream} format=${reference.format} offset=${page.offset} bytes=${page.bytes} totalBytes=${page.totalBytes} nextOffset=${page.nextOffset ?? "null"} eof=${page.eof} captureComplete=${reference.captureComplete}]`; return { ...text(page.text + marker), details: pageDetails }; }, }); } export { findResult, findSharedResult, readResultPage, saveResult } from "./results.ts";