UNPKG

@genkit-ai/ai

Version:

Genkit AI framework generative AI APIs.

184 lines 5.12 kB
import { assertUnstable, defineAction, stripUndefinedProps, z } from "@genkit-ai/core"; import { parseSchema, toJsonSchema } from "@genkit-ai/core/schema"; import { setCustomMetadataAttributes } from "@genkit-ai/core/tracing"; function asTool(registry, action) { if (action.__action?.metadata?.type === "tool") { return action; } const fn = (input) => { setCustomMetadataAttributes(registry, { subtype: "tool" }); return action(input); }; fn.__action = { ...action.__action, metadata: { ...action.__action.metadata, type: "tool" } }; return fn; } async function resolveTools(registry, tools) { if (!tools || tools.length === 0) { return []; } return await Promise.all( tools.map(async (ref) => { if (typeof ref === "string") { return await lookupToolByName(registry, ref); } else if (ref.__action) { return asTool(registry, ref); } else if (typeof ref.asTool === "function") { return await ref.asTool(); } else if (ref.name) { return await lookupToolByName( registry, ref.metadata?.originalName || ref.name ); } throw new Error("Tools must be strings, tool definitions, or actions."); }) ); } async function lookupToolByName(registry, name) { let tool = await registry.lookupAction(name) || await registry.lookupAction(`/tool/${name}`) || await registry.lookupAction(`/prompt/${name}`); if (!tool) { throw new Error(`Tool ${name} not found`); } return tool; } function toToolDefinition(tool) { const originalName = tool.__action.name; let name = originalName; if (originalName.includes("/")) { name = originalName.substring(originalName.lastIndexOf("/") + 1); } const out = { name, description: tool.__action.description || "", outputSchema: toJsonSchema({ schema: tool.__action.outputSchema ?? z.void(), jsonSchema: tool.__action.outputJsonSchema }), inputSchema: toJsonSchema({ schema: tool.__action.inputSchema ?? z.void(), jsonSchema: tool.__action.inputJsonSchema }) }; if (originalName !== name) { out.metadata = { originalName }; } return out; } function defineTool(registry, config, fn) { const a = defineAction( registry, { ...config, actionType: "tool", metadata: { ...config.metadata || {}, type: "tool" } }, (i, runOptions) => { return fn(i, { ...runOptions, context: { ...runOptions.context }, interrupt: interruptTool(registry) }); } ); a.respond = (interrupt, responseData, options) => { assertUnstable( registry, "beta", "The 'tool.reply' method is part of the 'interrupts' beta feature." ); parseSchema(responseData, { jsonSchema: config.outputJsonSchema, schema: config.outputSchema }); return { toolResponse: stripUndefinedProps({ name: interrupt.toolRequest.name, ref: interrupt.toolRequest.ref, output: responseData }), metadata: { interruptResponse: options?.metadata || true } }; }; a.restart = (interrupt, resumedMetadata, options) => { assertUnstable( registry, "beta", "The 'tool.restart' method is part of the 'interrupts' beta feature." ); let replaceInput = options?.replaceInput; if (replaceInput) { replaceInput = parseSchema(replaceInput, { schema: config.inputSchema, jsonSchema: config.inputJsonSchema }); } return { toolRequest: stripUndefinedProps({ name: interrupt.toolRequest.name, ref: interrupt.toolRequest.ref, input: replaceInput || interrupt.toolRequest.input }), metadata: stripUndefinedProps({ ...interrupt.metadata, resumed: resumedMetadata || true, // annotate the original input if replacing it replacedInput: replaceInput ? interrupt.toolRequest.input : void 0 }) }; }; return a; } function isToolRequest(part) { return !!part.toolRequest; } function isToolResponse(part) { return !!part.toolResponse; } function defineInterrupt(registry, config) { const { requestMetadata, ...toolConfig } = config; return defineTool( registry, toolConfig, async (input, { interrupt }) => { if (!config.requestMetadata) interrupt(); else if (typeof config.requestMetadata === "object") interrupt(config.requestMetadata); else interrupt(await Promise.resolve(config.requestMetadata(input))); } ); } class ToolInterruptError extends Error { constructor(metadata) { super(); this.metadata = metadata; this.name = "ToolInterruptError"; } } function interruptTool(registry) { return (metadata) => { assertUnstable(registry, "beta", "Tool interrupts are a beta feature."); throw new ToolInterruptError(metadata); }; } export { ToolInterruptError, asTool, defineInterrupt, defineTool, isToolRequest, isToolResponse, lookupToolByName, resolveTools, toToolDefinition }; //# sourceMappingURL=tool.mjs.map