gadget/docs/archive/tools/memory/pin-remove.ts

129 lines
3.4 KiB
TypeScript

// src/tools/memory/pin-remove.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved
import type { ToolDefinition } from "../../lib/ai-client.js";
import {
DtpTool,
type ToolArguments,
type ToolContext,
} from "../../lib/tool.js";
import { ChatSession, ChatSessionMode } from "../../models/chat-session.js";
export class PinRemoveTool extends DtpTool {
get name(): string {
return "PinRemoveTool";
}
get slug(): string {
return "pin-remove";
}
get metadata() {
return {
name: this.definition.function.name || "pin_remove",
category: "memory",
tags: ["pin", "pinboard", "note", "memory", "context", "remove"],
modes: [
ChatSessionMode.Plan,
ChatSessionMode.Build,
ChatSessionMode.Test,
ChatSessionMode.Ship,
ChatSessionMode.Develop,
],
};
}
public definition: ToolDefinition = {
type: "function",
function: {
name: "pin_remove",
description:
"Remove a pin from the session pinboard by its ID. Use this to free up space on the pinboard or remove information that is no longer relevant.",
parameters: {
type: "object",
properties: {
pin_id: {
type: "string",
description:
"The _id of the pin to remove. This is returned when the pin was added via pin_add, and is also visible in the PINBOARD section of the system prompt.",
},
},
required: ["pin_id"],
},
},
};
public async execute(
context: ToolContext,
args: ToolArguments,
): Promise<string> {
const pinId = args.pin_id as string | undefined;
if (!pinId || pinId.trim().length === 0) {
return this.error("INVALID_PARAMETER", "pin_id must not be empty.", {
parameter: "pin_id",
recoveryHint: "Provide the _id of the pin you want to remove.",
});
}
const sessionId = context.session._id.toHexString();
try {
const session = await ChatSession.findById(sessionId);
if (!session) {
return this.error("NOT_FOUND", `Session not found: ${sessionId}`);
}
const pinIndex = session.pins.findIndex(
(pin) => pin._id?.toString() === pinId,
);
if (pinIndex === -1) {
return this.error(
"NOT_FOUND",
`Pin not found: ${pinId}. Check the pin ID and try again.`,
{
recoveryHint:
"Pin IDs are shown in the PINBOARD section of the system prompt and returned when pins are added.",
},
);
}
const removedContent = session.pins[pinIndex]!.content;
session.pins.splice(pinIndex, 1);
await session.save();
const totalChars = session.pins.reduce(
(sum, pin) => sum + pin.content.length,
0,
);
return this.success(
{
pinId,
content: removedContent,
totalPins: session.pins.length,
totalChars,
maxChars: 8192,
},
`Pin removed from pinboard (${session.pins.length} pins remaining, ${totalChars}/8192 characters used).`,
);
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error);
this.log.error("Failed to remove pin", {
sessionId,
error: errorMessage,
});
return this.error(
"OPERATION_FAILED",
`Failed to remove pin: ${errorMessage}`,
);
}
}
}
export default new PinRemoveTool();