import z from "zod" import { Tool } from "./tool" import { RLMArtifacts } from "@/session/rlm/artifacts" function result(title: string, output: string, metadata: Record = {}) { return { title, output, metadata } } export const ArtifactTool = Tool.define("artifact", { description: [ "Store and retrieve large data artifacts by reference.", "Use this to keep large outputs (DataFrames, analysis results, raw data) out of context.", "Actions:", " - register: Store content on disk, returns a reference ID + summary", " - resolve: Retrieve full content by artifact ID", " - list: Show all artifacts in this session", ].join(" "), parameters: z.object({ action: z.enum(["register", "resolve", "list"]).describe("The action to perform"), type: z.string().optional().describe('For register: artifact type (e.g. "dataframe", "analysis", "raw_output")'), content: z.string().optional().describe("For register: the large content to store"), summary: z.string().optional().describe("For register: brief summary for context window"), artifact_id: z.string().optional().describe("For resolve: the artifact ID to retrieve"), }), async execute(params, ctx) { if (params.action === "register") { if (!params.type || !params.content) { return result("Error", "register requires `type` and `content` parameters") } const ref = await RLMArtifacts.register(ctx.sessionID, params.type, params.content, params.summary) return result( `Registered artifact: ${ref.id}`, [ `Artifact stored successfully.`, ` ID: ${ref.id}`, ` Type: ${ref.type}`, ` Summary: ${ref.summary}`, ` Size: ${params.content.length} bytes`, "", "Use artifact_id in resolve to retrieve full content later.", ].join("\n"), { id: ref.id, type: ref.type }, ) } if (params.action === "resolve") { if (!params.artifact_id) { return result("Error", "resolve requires `artifact_id` parameter") } const content = await RLMArtifacts.resolve(ctx.sessionID, params.artifact_id) if (!content) { return result("Not found", `Artifact "${params.artifact_id}" not found in this session.`) } return result(`Resolved artifact: ${params.artifact_id}`, content, { id: params.artifact_id }) } // list const artifacts = await RLMArtifacts.list(ctx.sessionID) if (artifacts.length === 0) { return result("No artifacts", "No artifacts registered in this session.") } const lines = artifacts.map((a) => `- ${a.id}: ${a.summary} (${a.type})`) return result(`${artifacts.length} artifact(s)`, lines.join("\n"), { count: artifacts.length }) }, })