Files
pi_harness/packages/mom/src/tools/attach.ts
T
Armin Ronacher 35ff2689ee fix(typebox): migrate to v1 with extension compat (#3474)
* fix(typebox): migrate to v1 with extension compat

Replace AJV-based validation with TypeBox-native validation, keep legacy extension imports working (including @sinclair/typebox/compiler), and restore coercion for serialized/plain JSON schemas.

This change closes #3112.

* fix(typebox): use canonical imports and harden coercion

Switch first-party code to canonical typebox imports while retaining legacy extension aliases in the loader.

Remove obsolete runtime codegen guards, expand serialized JSON-schema coercion coverage, and update related tests and fixtures.

Fixes #3112.

---------

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
2026-04-22 19:59:33 +02:00

48 lines
1.5 KiB
TypeScript

import type { AgentTool } from "@mariozechner/pi-agent-core";
import { basename, resolve as resolvePath } from "path";
import { Type } from "typebox";
// This will be set by the agent before running
let uploadFn: ((filePath: string, title?: string) => Promise<void>) | null = null;
export function setUploadFunction(fn: (filePath: string, title?: string) => Promise<void>): void {
uploadFn = fn;
}
const attachSchema = Type.Object({
label: Type.String({ description: "Brief description of what you're sharing (shown to user)" }),
path: Type.String({ description: "Path to the file to attach" }),
title: Type.Optional(Type.String({ description: "Title for the file (defaults to filename)" })),
});
export const attachTool: AgentTool<typeof attachSchema> = {
name: "attach",
label: "attach",
description:
"Attach a file to your response. Use this to share files, images, or documents with the user. Only files from /workspace/ can be attached.",
parameters: attachSchema,
execute: async (
_toolCallId: string,
{ path, title }: { label: string; path: string; title?: string },
signal?: AbortSignal,
) => {
if (!uploadFn) {
throw new Error("Upload function not configured");
}
if (signal?.aborted) {
throw new Error("Operation aborted");
}
const absolutePath = resolvePath(path);
const fileName = title || basename(absolutePath);
await uploadFn(absolutePath, fileName);
return {
content: [{ type: "text" as const, text: `Attached file: ${fileName}` }],
details: undefined,
};
},
};