{"version":3,"sources":["../../src/generate/action.ts"],"sourcesContent":["/**\n * Copyright 2024 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 {\n  Action,\n  defineAction,\n  GenkitError,\n  getStreamingCallback,\n  runWithStreamingCallback,\n  stripUndefinedProps,\n  z,\n} from '@genkit-ai/core';\nimport { logger } from '@genkit-ai/core/logging';\nimport { Registry } from '@genkit-ai/core/registry';\nimport { runInNewSpan, SPAN_TYPE_ATTR } from '@genkit-ai/core/tracing';\nimport {\n  injectInstructions,\n  resolveFormat,\n  resolveInstructions,\n} from '../formats/index.js';\nimport { Formatter } from '../formats/types.js';\nimport {\n  GenerateResponse,\n  GenerateResponseChunk,\n  GenerationResponseError,\n  tagAsPreamble,\n} from '../generate.js';\nimport {\n  GenerateActionOptions,\n  GenerateActionOptionsSchema,\n  GenerateActionOutputConfig,\n  GenerateRequest,\n  GenerateRequestSchema,\n  GenerateResponseChunkData,\n  GenerateResponseChunkSchema,\n  GenerateResponseData,\n  GenerateResponseSchema,\n  ModelAction,\n  ModelInfo,\n  ModelMiddleware,\n  ModelRequest,\n  Part,\n  resolveModel,\n  Role,\n} from '../model.js';\nimport { resolveTools, ToolAction, toToolDefinition } from '../tool.js';\nimport {\n  assertValidToolNames,\n  resolveResumeOption,\n  resolveToolRequests,\n} from './resolve-tool-requests.js';\n\nexport type GenerateAction = Action<\n  typeof GenerateActionOptionsSchema,\n  typeof GenerateResponseSchema,\n  typeof GenerateResponseChunkSchema\n>;\n\n/** Defines (registers) a utilty generate action. */\nexport function defineGenerateAction(registry: Registry): GenerateAction {\n  return defineAction(\n    registry,\n    {\n      actionType: 'util',\n      name: 'generate',\n      inputSchema: GenerateActionOptionsSchema,\n      outputSchema: GenerateResponseSchema,\n      streamSchema: GenerateResponseChunkSchema,\n    },\n    async (request, { sendChunk }) => {\n      const generateFn = () =>\n        generate(registry, {\n          rawRequest: request,\n          currentTurn: 0,\n          messageIndex: 0,\n          // Generate util action does not support middleware. Maybe when we add named/registered middleware....\n          middleware: [],\n        });\n      return sendChunk\n        ? runWithStreamingCallback(\n            registry,\n            (c: GenerateResponseChunk) => sendChunk(c.toJSON ? c.toJSON() : c),\n            generateFn\n          )\n        : generateFn();\n    }\n  );\n}\n\n/**\n * Encapsulates all generate logic. This is similar to `generateAction` except not an action and can take middleware.\n */\nexport async function generateHelper(\n  registry: Registry,\n  options: {\n    rawRequest: GenerateActionOptions;\n    middleware?: ModelMiddleware[];\n    currentTurn?: number;\n    messageIndex?: number;\n  }\n): Promise<GenerateResponseData> {\n  let currentTurn = options.currentTurn ?? 0;\n  let messageIndex = options.messageIndex ?? 0;\n  // do tracing\n  return await runInNewSpan(\n    registry,\n    {\n      metadata: {\n        name: 'generate',\n      },\n      labels: {\n        [SPAN_TYPE_ATTR]: 'util',\n      },\n    },\n    async (metadata) => {\n      metadata.name = 'generate';\n      metadata.input = options.rawRequest;\n      const output = await generate(registry, {\n        rawRequest: options.rawRequest,\n        middleware: options.middleware,\n        currentTurn,\n        messageIndex,\n      });\n      metadata.output = JSON.stringify(output);\n      return output;\n    }\n  );\n}\n\n/** Take the raw request and resolve tools, model, and format into their registry action counterparts. */\nasync function resolveParameters(\n  registry: Registry,\n  request: GenerateActionOptions\n) {\n  const [model, tools, format] = await Promise.all([\n    resolveModel(registry, request.model, { warnDeprecated: true }).then(\n      (r) => r.modelAction\n    ),\n    resolveTools(registry, request.tools),\n    resolveFormat(registry, request.output),\n  ]);\n  return { model, tools, format };\n}\n\n/** Given a raw request and a formatter, apply the formatter's logic and instructions to the request. */\nfunction applyFormat(\n  rawRequest: GenerateActionOptions,\n  resolvedFormat?: Formatter\n) {\n  const outRequest = { ...rawRequest };\n  // If is schema is set but format is not explicitly set, default to `json` format.\n  if (rawRequest.output?.jsonSchema && !rawRequest.output?.format) {\n    outRequest.output = { ...rawRequest.output, format: 'json' };\n  }\n\n  const instructions = resolveInstructions(\n    resolvedFormat,\n    outRequest.output?.jsonSchema,\n    outRequest?.output?.instructions\n  );\n\n  if (resolvedFormat) {\n    if (\n      shouldInjectFormatInstructions(resolvedFormat.config, rawRequest?.output)\n    ) {\n      outRequest.messages = injectInstructions(\n        outRequest.messages,\n        instructions\n      );\n    }\n    outRequest.output = {\n      // use output config from the format\n      ...resolvedFormat.config,\n      // if anything is set explicitly, use that\n      ...outRequest.output,\n    };\n  }\n\n  return outRequest;\n}\n\nexport function shouldInjectFormatInstructions(\n  formatConfig?: Formatter['config'],\n  rawRequestConfig?: z.infer<typeof GenerateActionOutputConfig>\n) {\n  return (\n    formatConfig?.defaultInstructions !== false ||\n    rawRequestConfig?.instructions\n  );\n}\n\nfunction applyTransferPreamble(\n  rawRequest: GenerateActionOptions,\n  transferPreamble?: GenerateActionOptions\n): GenerateActionOptions {\n  if (!transferPreamble) {\n    return rawRequest;\n  }\n\n  return stripUndefinedProps({\n    ...rawRequest,\n    messages: [\n      ...tagAsPreamble(transferPreamble.messages!)!,\n      ...rawRequest.messages.filter((m) => !m.metadata?.preamble),\n    ],\n    toolChoice: transferPreamble.toolChoice || rawRequest.toolChoice,\n    tools: transferPreamble.tools || rawRequest.tools,\n    config: transferPreamble.config || rawRequest.config,\n  });\n}\n\nasync function generate(\n  registry: Registry,\n  {\n    rawRequest,\n    middleware,\n    currentTurn,\n    messageIndex,\n  }: {\n    rawRequest: GenerateActionOptions;\n    middleware: ModelMiddleware[] | undefined;\n    currentTurn: number;\n    messageIndex: number;\n  }\n): Promise<GenerateResponseData> {\n  const { model, tools, format } = await resolveParameters(\n    registry,\n    rawRequest\n  );\n  rawRequest = applyFormat(rawRequest, format);\n\n  // check to make sure we don't have overlapping tool names *before* generation\n  await assertValidToolNames(tools);\n\n  const {\n    revisedRequest,\n    interruptedResponse,\n    toolMessage: resumedToolMessage,\n  } = await resolveResumeOption(registry, rawRequest);\n  // NOTE: in the future we should make it possible to interrupt a restart, but\n  // at the moment it's too complicated because it's not clear how to return a\n  // response that amends history but doesn't generate a new message, so we throw\n  if (interruptedResponse) {\n    throw new GenkitError({\n      status: 'FAILED_PRECONDITION',\n      message:\n        'One or more tools triggered an interrupt during a restarted execution.',\n      detail: { message: interruptedResponse.message },\n    });\n  }\n  rawRequest = revisedRequest!;\n\n  const request = await actionToGenerateRequest(\n    rawRequest,\n    tools,\n    format,\n    model\n  );\n\n  const previousChunks: GenerateResponseChunkData[] = [];\n\n  let chunkRole: Role = 'model';\n  // convenience method to create a full chunk from role and data, append the chunk\n  // to the previousChunks array, and increment the message index as needed\n  const makeChunk = (\n    role: Role,\n    chunk: GenerateResponseChunkData\n  ): GenerateResponseChunk => {\n    if (role !== chunkRole && previousChunks.length) messageIndex++;\n    chunkRole = role;\n\n    const prevToSend = [...previousChunks];\n    previousChunks.push(chunk);\n\n    return new GenerateResponseChunk(chunk, {\n      index: messageIndex,\n      role,\n      previousChunks: prevToSend,\n      parser: format?.handler(request.output?.schema).parseChunk,\n    });\n  };\n\n  const streamingCallback = getStreamingCallback(registry);\n\n  // if resolving the 'resume' option above generated a tool message, stream it.\n  if (resumedToolMessage && streamingCallback) {\n    streamingCallback(makeChunk('tool', resumedToolMessage));\n  }\n\n  const response = await runWithStreamingCallback(\n    registry,\n    streamingCallback &&\n      ((chunk: GenerateResponseChunkData) =>\n        streamingCallback(makeChunk('model', chunk))),\n    async () => {\n      const dispatch = async (\n        index: number,\n        req: z.infer<typeof GenerateRequestSchema>\n      ) => {\n        if (!middleware || index === middleware.length) {\n          // end of the chain, call the original model action\n          return await model(req);\n        }\n\n        const currentMiddleware = middleware[index];\n        return currentMiddleware(req, async (modifiedReq) =>\n          dispatch(index + 1, modifiedReq || req)\n        );\n      };\n\n      return new GenerateResponse(await dispatch(0, request), {\n        request,\n        parser: format?.handler(request.output?.schema).parseMessage,\n      });\n    }\n  );\n\n  // Throw an error if the response is not usable.\n  response.assertValid();\n  const generatedMessage = response.message!; // would have thrown if no message\n\n  const toolRequests = generatedMessage.content.filter(\n    (part) => !!part.toolRequest\n  );\n\n  if (rawRequest.returnToolRequests || toolRequests.length === 0) {\n    if (toolRequests.length === 0) response.assertValidSchema(request);\n    return response.toJSON();\n  }\n\n  const maxIterations = rawRequest.maxTurns ?? 5;\n  if (currentTurn + 1 > maxIterations) {\n    throw new GenerationResponseError(\n      response,\n      `Exceeded maximum tool call iterations (${maxIterations})`,\n      'ABORTED',\n      { request }\n    );\n  }\n\n  const { revisedModelMessage, toolMessage, transferPreamble } =\n    await resolveToolRequests(registry, rawRequest, generatedMessage);\n\n  // if an interrupt message is returned, stop the tool loop and return a response\n  if (revisedModelMessage) {\n    return {\n      ...response.toJSON(),\n      finishReason: 'interrupted',\n      finishMessage: 'One or more tool calls resulted in interrupts.',\n      message: revisedModelMessage,\n    };\n  }\n\n  // if the loop will continue, stream out the tool response message...\n  streamingCallback?.(\n    makeChunk('tool', {\n      content: toolMessage!.content,\n    })\n  );\n\n  let nextRequest = {\n    ...rawRequest,\n    messages: [...rawRequest.messages, generatedMessage.toJSON(), toolMessage!],\n  };\n  nextRequest = applyTransferPreamble(nextRequest, transferPreamble);\n\n  // then recursively call for another loop\n  return await generateHelper(registry, {\n    rawRequest: nextRequest,\n    middleware: middleware,\n    currentTurn: currentTurn + 1,\n    messageIndex: messageIndex + 1,\n  });\n}\n\nasync function actionToGenerateRequest(\n  options: GenerateActionOptions,\n  resolvedTools: ToolAction[] | undefined,\n  resolvedFormat: Formatter | undefined,\n  model: ModelAction\n): Promise<GenerateRequest> {\n  const modelInfo = model.__action.metadata?.model as ModelInfo;\n  if (\n    (options.tools?.length ?? 0) > 0 &&\n    modelInfo?.supports &&\n    !modelInfo?.supports?.tools\n  ) {\n    logger.warn(\n      `The model '${model.__action.name}' does not support tools (you set: ${options.tools?.length} tools). ` +\n        'The model may not behave the way you expect.'\n    );\n  }\n  if (\n    options.toolChoice &&\n    modelInfo?.supports &&\n    !modelInfo?.supports?.toolChoice\n  ) {\n    logger.warn(\n      `The model '${model.__action.name}' does not support the 'toolChoice' option (you set: ${options.toolChoice}). ` +\n        'The model may not behave the way you expect.'\n    );\n  }\n  const out: ModelRequest = {\n    messages: options.messages,\n    config: options.config,\n    docs: options.docs,\n    tools: resolvedTools?.map(toToolDefinition) || [],\n    output: stripUndefinedProps({\n      constrained: options.output?.constrained,\n      contentType: options.output?.contentType,\n      format: options.output?.format,\n      schema: options.output?.jsonSchema,\n    }),\n  };\n  if (options.toolChoice) {\n    out.toolChoice = options.toolChoice;\n  }\n  if (out.output && !out.output.schema) delete out.output.schema;\n  return out;\n}\n\nexport function inferRoleFromParts(parts: Part[]): Role {\n  const uniqueRoles = new Set<Role>();\n  for (const part of parts) {\n    const role = getRoleFromPart(part);\n    uniqueRoles.add(role);\n    if (uniqueRoles.size > 1) {\n      throw new Error('Contents contain mixed roles');\n    }\n  }\n  return Array.from(uniqueRoles)[0];\n}\n\nfunction getRoleFromPart(part: Part): Role {\n  if (part.toolRequest !== undefined) return 'model';\n  if (part.toolResponse !== undefined) return 'tool';\n  if (part.text !== undefined) return 'user';\n  if (part.media !== undefined) return 'user';\n  if (part.data !== undefined) return 'user';\n  throw new Error('No recognized fields in content');\n}\n"],"mappings":"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","names":[]}