Files
my-pi/extensions/exa-tool-prefix.ts
T

58 lines
1.6 KiB
TypeScript

const EXA_TOOL_ALIASES: Record<string, string> = {
web_search_exa: "exa_web_search",
web_fetch_exa: "exa_web_fetch",
web_search_advanced_exa: "exa_web_search_advanced",
};
export type ExaToolDefinition = {
name: string;
label: string;
[key: string]: unknown;
};
export function mapExaToolName(name: string): string {
return EXA_TOOL_ALIASES[name] ?? name;
}
export function prefixExaTool<T extends ExaToolDefinition>(definition: T): T {
const name = mapExaToolName(definition.name);
if (name === definition.name) return definition;
const displayName = name
.slice("exa_".length)
.split("_")
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join(" ");
return {
...definition,
name,
label: `Exa ${displayName}`,
} as T;
}
type ToolApi = {
registerTool: (tool: unknown) => unknown;
setActiveTools: (names: string[]) => unknown;
unregisterTool?: (name: string) => boolean;
};
export function createExaToolApiOverride<T extends object>(pi: T): T {
const api = pi as T & ToolApi;
return new Proxy(pi, {
get(target, property) {
if (property === "registerTool") {
return (definition: ExaToolDefinition) => api.registerTool(prefixExaTool(definition));
}
if (property === "setActiveTools") {
return (names: string[]) => api.setActiveTools([...new Set(names.map(mapExaToolName))]);
}
if (property === "unregisterTool") {
return api.unregisterTool ? (name: string) => api.unregisterTool?.(mapExaToolName(name)) : undefined;
}
const value = Reflect.get(target, property, target);
return typeof value === "function" ? value.bind(target) : value;
},
}) as T;
}