import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core"; import * as z from "zod/v4"; import memoryEditDescription from "../prompts/tools/memory-edit.md" with { type: "text" }; import type { ToolSession } from "."; const memoryEditSchema = z.object({ op: z.enum(["update", "forget", "invalidate"]).describe("memory edit operation"), id: z.string().describe("memory id from recall output"), content: z.string().optional().describe("replacement content for update"), importance: z.number().optional().describe("replacement importance for update, clamped to [0, 1]"), replacement_id: z.string().optional().describe("replacement memory id for invalidate"), }); export type MemoryEditParams = z.infer; export class MemoryEditTool implements AgentTool { readonly name = "memory_edit"; readonly approval = "read" as const; readonly label = "Memory Edit"; readonly description = memoryEditDescription; readonly parameters = memoryEditSchema; readonly strict = true; readonly loadMode = "discoverable"; readonly summary = "Update, forget, or invalidate Mnemopi memories"; constructor(private readonly session: ToolSession) {} static createIf(session: ToolSession): MemoryEditTool | null { const backend = session.settings.get("memory.backend"); if (backend !== "mnemopi") return null; return new MemoryEditTool(session); } async execute(_id: string, params: MemoryEditParams): Promise { const state = this.session.getMnemopiSessionState?.(); if (!state) { throw new Error("Mnemopi backend is not initialised for this session."); } if (params.op === "update" && params.content === undefined && params.importance === undefined) { throw new Error("memory_edit update requires content or importance."); } const importance = params.importance === undefined ? undefined : Math.max(0, Math.min(1, params.importance)); const result = state.editScopedMemory(params.op, params.id, { content: params.content, importance, replacementId: params.replacement_id, }); const location = result.bank ? ` in bank ${result.bank}${result.store ? ` (${result.store})` : ""}` : ""; const text = result.status === "not_found" ? `Memory ${params.id} was not found${location}.` : `Memory ${params.id} ${result.status}${location}.`; return { content: [{ type: "text", text }], details: result, }; } }