- inputSchema → parameters
- { result: text } → { content: [{ type: "text", text }] }
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
101 lines
4.0 KiB
TypeScript
101 lines
4.0 KiB
TypeScript
import { addRule, removeRule, listRules } from "../core/rule-store.js";
|
|
import { loadRouters, getRouterNames } from "../core/router-loader.js";
|
|
import { resolveInjection } from "../core/prompt-injector.js";
|
|
|
|
export function registerPromptRulesTool(
|
|
api: {
|
|
registerTool(def: any): void;
|
|
logger: { info(msg: string): void; warn(msg: string): void };
|
|
},
|
|
routersDir: string
|
|
): void {
|
|
api.registerTool({
|
|
name: "prompt_rules",
|
|
description:
|
|
"Manage PrismFacet prompt injection rules. " +
|
|
"Actions: add (register a rule mapping router:key to a prompt file), " +
|
|
"remove (delete a rule), list (show all rules), " +
|
|
"test (preview which prompts would be injected for an agent), " +
|
|
"reload-routers (hot-reload all router functions), " +
|
|
"list-routers (show loaded routers).",
|
|
parameters: {
|
|
type: "object",
|
|
properties: {
|
|
action: {
|
|
type: "string",
|
|
enum: ["add", "remove", "list", "test", "reload-routers", "list-routers"],
|
|
description: "The action to perform",
|
|
},
|
|
router: {
|
|
type: "string",
|
|
description: "Router name (for add/remove)",
|
|
},
|
|
key: {
|
|
type: "string",
|
|
description: "Rule key (for add/remove)",
|
|
},
|
|
file: {
|
|
type: "string",
|
|
description: "Absolute path to prompt file (for add)",
|
|
},
|
|
agent: {
|
|
type: "string",
|
|
description: "Agent ID to test (for test)",
|
|
},
|
|
},
|
|
required: ["action"],
|
|
},
|
|
execute: async (_toolCallId: string, params: Record<string, unknown>) => {
|
|
const action = params.action as string;
|
|
const router = params.router as string | undefined;
|
|
const key = params.key as string | undefined;
|
|
const file = params.file as string | undefined;
|
|
const agent = params.agent as string | undefined;
|
|
|
|
switch (action) {
|
|
case "add": {
|
|
if (!router || !key || !file) {
|
|
return { content: [{ type: "text", text: "Error: add requires router, key, and file" }] };
|
|
}
|
|
addRule(router, key, file);
|
|
return { content: [{ type: "text", text: `Rule added: ${router}:${key} → ${file}` }] };
|
|
}
|
|
case "remove": {
|
|
if (!router || !key) {
|
|
return { content: [{ type: "text", text: "Error: remove requires router and key" }] };
|
|
}
|
|
const removed = removeRule(router, key);
|
|
const msg = removed ? `Rule removed: ${router}:${key}` : `Rule not found: ${router}:${key}`;
|
|
return { content: [{ type: "text", text: msg }] };
|
|
}
|
|
case "list": {
|
|
const rules = listRules();
|
|
const entries = Object.entries(rules);
|
|
if (entries.length === 0) return { content: [{ type: "text", text: "No rules registered." }] };
|
|
return { content: [{ type: "text", text: entries.map(([k, v]) => `${k} → ${v}`).join("\n") }] };
|
|
}
|
|
case "test": {
|
|
if (!agent) return { content: [{ type: "text", text: "Error: test requires agent" }] };
|
|
const result = await resolveInjection({ agentId: agent }, api.logger);
|
|
if (!result.appendSystemContext) {
|
|
return { content: [{ type: "text", text: `No prompts matched for agent: ${agent}` }] };
|
|
}
|
|
return { content: [{ type: "text", text: `Matched prompts for ${agent}:\n\n${result.appendSystemContext}` }] };
|
|
}
|
|
case "reload-routers": {
|
|
await loadRouters(routersDir, api.logger);
|
|
const names = getRouterNames();
|
|
return { content: [{ type: "text", text: `Routers reloaded: ${names.join(", ") || "(none)"}` }] };
|
|
}
|
|
case "list-routers": {
|
|
const names = getRouterNames();
|
|
const msg = names.length > 0 ? `Loaded routers: ${names.join(", ")}` : "No routers loaded.";
|
|
return { content: [{ type: "text", text: msg }] };
|
|
}
|
|
default:
|
|
return { content: [{ type: "text", text: `Unknown action: ${action}` }] };
|
|
}
|
|
},
|
|
});
|
|
}
|