@genkit-ai/ai
Version:
Genkit AI framework generative AI APIs.
1 lines • 19.5 kB
Source Map (JSON)
{"version":3,"sources":["../../src/generate/resolve-tool-requests.ts"],"sourcesContent":["/**\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenkitError, stripUndefinedProps } from '@genkit-ai/core';\nimport { logger } from '@genkit-ai/core/logging';\nimport { Registry } from '@genkit-ai/core/registry';\nimport {\n GenerateActionOptions,\n GenerateResponseData,\n MessageData,\n Part,\n ToolRequestPart,\n ToolResponsePart,\n} from '../model.js';\nimport { isPromptAction } from '../prompt.js';\nimport {\n ToolAction,\n ToolInterruptError,\n ToolRunOptions,\n isToolRequest,\n resolveTools,\n} from '../tool.js';\n\nexport function toToolMap(tools: ToolAction[]): Record<string, ToolAction> {\n assertValidToolNames(tools);\n const out: Record<string, ToolAction> = {};\n for (const tool of tools) {\n const name = tool.__action.name;\n const shortName = name.substring(name.lastIndexOf('/') + 1);\n out[shortName] = tool;\n }\n return out;\n}\n\n/** Ensures that each tool has a unique name. */\nexport function assertValidToolNames(tools: ToolAction[]) {\n const nameMap: Record<string, string> = {};\n for (const tool of tools) {\n const name = tool.__action.name;\n const shortName = name.substring(name.lastIndexOf('/') + 1);\n if (nameMap[shortName]) {\n throw new GenkitError({\n status: 'INVALID_ARGUMENT',\n message: `Cannot provide two tools with the same name: '${name}' and '${nameMap[shortName]}'`,\n });\n }\n nameMap[shortName] = name;\n }\n}\n\nfunction toRunOptions(part: ToolRequestPart): ToolRunOptions {\n const out: ToolRunOptions = { metadata: part.metadata };\n if (part.metadata?.resumed) out.resumed = part.metadata.resumed;\n return out;\n}\n\nexport function toPendingOutput(\n part: ToolRequestPart,\n response: ToolResponsePart\n): ToolRequestPart {\n return {\n ...part,\n metadata: {\n ...part.metadata,\n pendingOutput: response.toolResponse.output,\n },\n };\n}\n\nexport async function resolveToolRequest(\n rawRequest: GenerateActionOptions,\n part: ToolRequestPart,\n toolMap: Record<string, ToolAction>,\n runOptions?: ToolRunOptions\n): Promise<{\n response?: ToolResponsePart;\n interrupt?: ToolRequestPart;\n preamble?: GenerateActionOptions;\n}> {\n const tool = toolMap[part.toolRequest.name];\n if (!tool) {\n throw new GenkitError({\n status: 'NOT_FOUND',\n message: `Tool ${part.toolRequest.name} not found`,\n detail: { request: rawRequest },\n });\n }\n\n // if it's a prompt action, go ahead and render the preamble\n if (isPromptAction(tool)) {\n const preamble = await tool(part.toolRequest.input);\n const response = {\n toolResponse: {\n name: part.toolRequest.name,\n ref: part.toolRequest.ref,\n output: `transferred to ${part.toolRequest.name}`,\n },\n };\n\n return { preamble, response };\n }\n\n // otherwise, execute the tool and catch interrupts\n try {\n const output = await tool(part.toolRequest.input, toRunOptions(part));\n const response = stripUndefinedProps({\n toolResponse: {\n name: part.toolRequest.name,\n ref: part.toolRequest.ref,\n output,\n },\n });\n\n return { response };\n } catch (e) {\n if (e instanceof ToolInterruptError) {\n logger.debug(\n `tool '${toolMap[part.toolRequest?.name].__action.name}' triggered an interrupt${e.metadata ? `: ${JSON.stringify(e.metadata)}` : ''}`\n );\n const interrupt = {\n toolRequest: part.toolRequest,\n metadata: { ...part.metadata, interrupt: e.metadata || true },\n };\n\n return { interrupt };\n }\n\n throw e;\n }\n}\n\n/**\n * resolveToolRequests is responsible for executing the tools requested by the model for a single turn. it\n * returns either a toolMessage to append or a revisedModelMessage when an interrupt occurs, and a transferPreamble\n * if a prompt tool is called\n */\nexport async function resolveToolRequests(\n registry: Registry,\n rawRequest: GenerateActionOptions,\n generatedMessage: MessageData\n): Promise<{\n revisedModelMessage?: MessageData;\n toolMessage?: MessageData;\n transferPreamble?: GenerateActionOptions;\n}> {\n const toolMap = toToolMap(await resolveTools(registry, rawRequest.tools));\n\n const responseParts: ToolResponsePart[] = [];\n let hasInterrupts: boolean = false;\n let transferPreamble: GenerateActionOptions | undefined;\n\n const revisedModelMessage = {\n ...generatedMessage,\n content: [...generatedMessage.content],\n };\n\n await Promise.all(\n revisedModelMessage.content.map(async (part, i) => {\n if (!part.toolRequest) return; // skip non-tool-request parts\n\n const { preamble, response, interrupt } = await resolveToolRequest(\n rawRequest,\n part as ToolRequestPart,\n toolMap\n );\n\n if (preamble) {\n if (transferPreamble) {\n throw new GenkitError({\n status: 'INVALID_ARGUMENT',\n message: `Model attempted to transfer to multiple prompt tools.`,\n });\n }\n\n transferPreamble = preamble;\n }\n\n // this happens for preamble or normal tools\n if (response) {\n responseParts.push(response!);\n revisedModelMessage.content.splice(\n i,\n 1,\n toPendingOutput(part, response)\n );\n }\n\n if (interrupt) {\n revisedModelMessage.content.splice(i, 1, interrupt);\n hasInterrupts = true;\n }\n })\n );\n\n if (hasInterrupts) {\n return { revisedModelMessage };\n }\n\n return {\n toolMessage: { role: 'tool', content: responseParts },\n transferPreamble,\n };\n}\n\nfunction findCorrespondingToolRequest(\n parts: Part[],\n part: ToolRequestPart | ToolResponsePart\n): ToolRequestPart | undefined {\n const name = part.toolRequest?.name || part.toolResponse?.name;\n const ref = part.toolRequest?.ref || part.toolResponse?.ref;\n\n return parts.find(\n (p) => p.toolRequest?.name === name && p.toolRequest?.ref === ref\n ) as ToolRequestPart | undefined;\n}\n\nfunction findCorrespondingToolResponse(\n parts: Part[],\n part: ToolRequestPart | ToolResponsePart\n): ToolResponsePart | undefined {\n const name = part.toolRequest?.name || part.toolResponse?.name;\n const ref = part.toolRequest?.ref || part.toolResponse?.ref;\n\n return parts.find(\n (p) => p.toolResponse?.name === name && p.toolResponse?.ref === ref\n ) as ToolResponsePart | undefined;\n}\n\nasync function resolveResumedToolRequest(\n rawRequest: GenerateActionOptions,\n part: ToolRequestPart,\n toolMap: Record<string, ToolAction>\n): Promise<{\n toolRequest?: ToolRequestPart;\n toolResponse?: ToolResponsePart;\n interrupt?: ToolRequestPart;\n}> {\n if (part.metadata?.pendingOutput) {\n const { pendingOutput, ...metadata } = part.metadata;\n const toolResponse = {\n toolResponse: {\n name: part.toolRequest.name,\n ref: part.toolRequest.ref,\n output: pendingOutput,\n },\n metadata: { ...metadata, source: 'pending' },\n };\n\n // strip pendingOutput from metadata when returning\n return stripUndefinedProps({\n toolResponse,\n toolRequest: { ...part, metadata },\n });\n }\n\n // if there's a corresponding reply, append it to toolResponses\n const providedResponse = findCorrespondingToolResponse(\n rawRequest.resume?.respond || [],\n part\n );\n if (providedResponse) {\n const toolResponse = providedResponse;\n\n // remove the 'interrupt' but leave a 'resolvedInterrupt'\n const { interrupt, ...metadata } = part.metadata || {};\n return stripUndefinedProps({\n toolResponse,\n toolRequest: {\n ...part,\n metadata: { ...metadata, resolvedInterrupt: interrupt },\n },\n });\n }\n\n // if there's a corresponding restart, execute then add to toolResponses\n const restartRequest = findCorrespondingToolRequest(\n rawRequest.resume?.restart || [],\n part\n );\n if (restartRequest) {\n const { response, interrupt, preamble } = await resolveToolRequest(\n rawRequest,\n restartRequest,\n toolMap\n );\n\n if (preamble) {\n throw new GenkitError({\n status: 'INTERNAL',\n message: `Prompt tool '${restartRequest.toolRequest.name}' executed inside 'restart' resolution. This should never happen.`,\n });\n }\n\n // if there's a new interrupt, return it\n if (interrupt) return { interrupt };\n\n if (response) {\n const toolResponse = response;\n\n // remove the 'interrupt' but leave a 'resolvedInterrupt'\n const { interrupt, ...metadata } = part.metadata || {};\n return stripUndefinedProps({\n toolResponse,\n toolRequest: {\n ...part,\n metadata: { ...metadata, resolvedInterrupt: interrupt },\n },\n });\n }\n }\n\n throw new GenkitError({\n status: 'INVALID_ARGUMENT',\n message: `Unresolved tool request '${part.toolRequest.name}${part.toolRequest.ref ? `#${part.toolRequest.ref}` : ''}' was not handled by the 'resume' argument. You must supply replies or restarts for all interrupted tool requests.'`,\n });\n}\n\n/** Amends message history to handle `resume` arguments. Returns the amended history. */\nexport async function resolveResumeOption(\n registry: Registry,\n rawRequest: GenerateActionOptions\n): Promise<{\n revisedRequest?: GenerateActionOptions;\n interruptedResponse?: GenerateResponseData;\n toolMessage?: MessageData;\n}> {\n if (!rawRequest.resume) return { revisedRequest: rawRequest }; // no-op if no resume option\n const toolMap = toToolMap(await resolveTools(registry, rawRequest.tools));\n\n const messages = rawRequest.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !lastMessage ||\n lastMessage.role !== 'model' ||\n !lastMessage.content.find((p) => p.toolRequest)\n ) {\n throw new GenkitError({\n status: 'FAILED_PRECONDITION',\n message: `Cannot 'resume' generation unless the previous message is a model message with at least one tool request.`,\n });\n }\n\n const toolResponses: ToolResponsePart[] = [];\n let interrupted = false;\n\n lastMessage.content = await Promise.all(\n lastMessage.content.map(async (part) => {\n if (!isToolRequest(part)) return part;\n const resolved = await resolveResumedToolRequest(\n rawRequest,\n part,\n toolMap\n );\n if (resolved.interrupt) {\n interrupted = true;\n return resolved.interrupt;\n }\n\n toolResponses.push(resolved.toolResponse!);\n return resolved.toolRequest!;\n })\n );\n\n if (interrupted) {\n // TODO: figure out how to make this trigger an interrupt response.\n return {\n interruptedResponse: {\n finishReason: 'interrupted',\n finishMessage:\n 'One or more tools triggered interrupts while resuming generation. The model was not called.',\n message: lastMessage,\n },\n };\n }\n\n const numToolRequests = lastMessage.content.filter(\n (p) => !!p.toolRequest\n ).length;\n if (toolResponses.length !== numToolRequests) {\n throw new GenkitError({\n status: 'FAILED_PRECONDITION',\n message: `Expected ${numToolRequests} tool responses but resolved to ${toolResponses.length}.`,\n detail: { toolResponses, message: lastMessage },\n });\n }\n\n const toolMessage: MessageData = {\n role: 'tool',\n content: toolResponses,\n metadata: {\n resumed: rawRequest.resume.metadata || true,\n },\n };\n\n return stripUndefinedProps({\n revisedRequest: {\n ...rawRequest,\n resume: undefined,\n messages: [...messages, toolMessage],\n },\n toolMessage,\n });\n}\n\nexport async function resolveRestartedTools(\n registry: Registry,\n rawRequest: GenerateActionOptions\n): Promise<ToolRequestPart[]> {\n const toolMap = toToolMap(await resolveTools(registry, rawRequest.tools));\n const lastMessage = rawRequest.messages.at(-1);\n if (!lastMessage || lastMessage.role !== 'model') return [];\n\n const restarts = lastMessage.content.filter(\n (p) => p.toolRequest && p.metadata?.resumed\n ) as ToolRequestPart[];\n\n return await Promise.all(\n restarts.map(async (p) => {\n const { response, interrupt } = await resolveToolRequest(\n rawRequest,\n p,\n toolMap\n );\n\n // this means that it interrupted *again* after the restart\n if (interrupt) return interrupt;\n return toPendingOutput(p, response!);\n })\n );\n}\n"],"mappings":"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","names":["interrupt"]}