{"version":3,"sources":["../src/model.ts"],"sourcesContent":["/**\n * Copyright 2024 The Fire Company\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 type {\n  GenerateRequest,\n  GenerateResponseChunkData,\n  GenerateResponseData,\n  Genkit,\n  MessageData,\n  ModelReference,\n  Part,\n  Role,\n  StreamingCallback,\n  ToolRequestPart,\n} from 'genkit';\nimport { GenerationCommonConfigSchema, Message, modelRef, z } from 'genkit';\nimport type { ModelAction, ModelInfo, ToolDefinition } from 'genkit/model';\nimport type OpenAI from 'openai';\nimport type {\n  ChatCompletion,\n  ChatCompletionChunk,\n  ChatCompletionContentPart,\n  ChatCompletionCreateParams,\n  ChatCompletionCreateParamsNonStreaming,\n  ChatCompletionMessageParam,\n  ChatCompletionMessageToolCall,\n  ChatCompletionRole,\n  ChatCompletionTool,\n  CompletionChoice,\n} from 'openai/resources/index.mjs';\n\nconst VisualDetailLevelSchema = z.enum(['auto', 'low', 'high']).optional();\n\ntype VisualDetailLevel = z.infer<typeof VisualDetailLevelSchema>;\n\nexport type ModelRequestBuilder = (\n  req: GenerateRequest,\n  params: ChatCompletionCreateParams\n) => void;\n\nexport const ChatCompletionCommonConfigSchema =\n  GenerationCommonConfigSchema.extend({\n    temperature: z.number().min(0).max(2).optional(),\n    frequencyPenalty: z.number().min(-2).max(2).optional(),\n    logProbs: z.boolean().optional(),\n    presencePenalty: z.number().min(-2).max(2).optional(),\n    topLogProbs: z.number().int().min(0).max(20).optional(),\n  });\n\nexport function toOpenAIRole(role: Role): ChatCompletionRole {\n  switch (role) {\n    case 'user':\n      return 'user';\n    case 'model':\n      return 'assistant';\n    case 'system':\n      return 'system';\n    case 'tool':\n      return 'tool';\n    default:\n      throw new Error(`role ${role} doesn't map to an OpenAI role.`);\n  }\n}\n\n/**\n * Converts a Genkit ToolDefinition to an OpenAI ChatCompletionTool object.\n * @param tool The Genkit ToolDefinition to convert.\n * @returns The converted OpenAI ChatCompletionTool object.\n */\nexport function toOpenAITool(tool: ToolDefinition): ChatCompletionTool {\n  return {\n    type: 'function',\n    function: {\n      name: tool.name,\n      parameters: tool.inputSchema !== null ? tool.inputSchema : undefined,\n    },\n  };\n}\n\n/**\n * Converts a Genkit Part to the corresponding OpenAI ChatCompletionContentPart.\n * @param part The Genkit Part to convert.\n * @param visualDetailLevel The visual detail level to use for media parts.\n * @returns The corresponding OpenAI ChatCompletionContentPart.\n * @throws Error if the part contains unsupported fields for the current message role.\n */\nexport function toOpenAITextAndMedia(\n  part: Part,\n  visualDetailLevel: VisualDetailLevel\n): ChatCompletionContentPart {\n  if (part.text) {\n    return {\n      type: 'text',\n      text: part.text,\n    };\n  } else if (part.media) {\n    return {\n      type: 'image_url',\n      image_url: {\n        url: part.media.url,\n        detail: visualDetailLevel,\n      },\n    };\n  }\n  throw Error(\n    `Unsupported genkit part fields encountered for current message role: ${JSON.stringify(part)}.`\n  );\n}\n\n/**\n * Converts a Genkit MessageData array to an OpenAI ChatCompletionMessageParam array.\n * @param messages The Genkit MessageData array to convert.\n * @param visualDetailLevel The visual detail level to use for media parts.\n * @returns The converted OpenAI ChatCompletionMessageParam array.\n */\nexport function toOpenAIMessages(\n  messages: MessageData[],\n  visualDetailLevel: VisualDetailLevel = 'auto'\n): ChatCompletionMessageParam[] {\n  const apiMessages: ChatCompletionMessageParam[] = [];\n  for (const message of messages) {\n    const msg = new Message(message);\n    const role = toOpenAIRole(message.role);\n    switch (role) {\n      case 'user':\n        const content = msg.content.map((part) =>\n          toOpenAITextAndMedia(part, visualDetailLevel)\n        );\n        // Check if we have only text content\n        const onlyTextContent = content.some((item) => item.type !== 'text');\n\n        // If all items are strings, just add them as text\n        if (!onlyTextContent) {\n          content.forEach((item) => {\n            if (item.type === 'text') {\n              apiMessages.push({\n                role: role,\n                content: item.text,\n              });\n            }\n          });\n        } else {\n          apiMessages.push({\n            role: role,\n            content: content,\n          });\n        }\n        break;\n      case 'system':\n        apiMessages.push({\n          role: role,\n          content: msg.text,\n        });\n        break;\n      case 'assistant': {\n        const toolCalls: ChatCompletionMessageToolCall[] = msg.content\n          .filter(\n            (\n              part\n            ): part is Part & {\n              toolRequest: NonNullable<Part['toolRequest']>;\n            } => Boolean(part.toolRequest)\n          )\n          .map((part) => ({\n            id: part.toolRequest.ref ?? '',\n            type: 'function',\n            function: {\n              name: part.toolRequest.name,\n              arguments: JSON.stringify(part.toolRequest.input),\n            },\n          }));\n        if (toolCalls.length > 0) {\n          apiMessages.push({\n            role: role,\n            tool_calls: toolCalls,\n          });\n        } else {\n          apiMessages.push({\n            role: role,\n            content: msg.text,\n          });\n        }\n        break;\n      }\n      case 'tool': {\n        const toolResponseParts = msg.toolResponseParts();\n        toolResponseParts.map((part) => {\n          apiMessages.push({\n            role: role,\n            tool_call_id: part.toolResponse.ref ?? '',\n            content:\n              typeof part.toolResponse.output === 'string'\n                ? part.toolResponse.output\n                : JSON.stringify(part.toolResponse.output),\n          });\n        });\n        break;\n      }\n    }\n  }\n  return apiMessages;\n}\n\nconst finishReasonMap: Record<\n  // OpenAI Node SDK doesn't support tool_call in the enum, but it is returned from the API\n  CompletionChoice['finish_reason'] | 'tool_calls',\n  GenerateResponseData['finishReason']\n> = {\n  length: 'length',\n  stop: 'stop',\n  tool_calls: 'stop',\n  content_filter: 'blocked',\n};\n\n/**\n * Converts an OpenAI tool call to a Genkit ToolRequestPart.\n * @param toolCall The OpenAI tool call to convert.\n * @returns The converted Genkit ToolRequestPart.\n */\nexport function fromOpenAIToolCall(\n  toolCall:\n    | ChatCompletionMessageToolCall\n    | ChatCompletionChunk.Choice.Delta.ToolCall,\n  choice: ChatCompletion.Choice | ChatCompletionChunk.Choice\n): ToolRequestPart {\n  if (!toolCall.function) {\n    throw Error(\n      `Unexpected openAI chunk choice. tool_calls was provided but one or more tool_calls is missing.`\n    );\n  }\n  const f = toolCall.function;\n\n  // Only parse arugments when it is a JSON object and the finish reason is tool_calls to avoid parsing errors\n  if (choice.finish_reason === 'tool_calls') {\n    return {\n      toolRequest: {\n        name: f.name!,\n        ref: toolCall.id,\n        input: f.arguments ? JSON.parse(f.arguments) : f.arguments,\n      },\n    };\n  } else {\n    return {\n      toolRequest: {\n        name: f.name!,\n        ref: toolCall.id,\n        input: '',\n      },\n    };\n  }\n}\n\n/**\n * Converts an OpenAI message event to a Genkit GenerateResponseData object.\n * @param choice The OpenAI message event to convert.\n * @param jsonMode Whether the event is a JSON response.\n * @returns The converted Genkit GenerateResponseData object.\n */\nexport function fromOpenAIChoice(\n  choice: ChatCompletion.Choice,\n  jsonMode = false\n): GenerateResponseData {\n  const toolRequestParts = choice.message.tool_calls?.map((toolCall) =>\n    fromOpenAIToolCall(toolCall, choice)\n  );\n  return {\n    finishReason: finishReasonMap[choice.finish_reason] || 'other',\n    message: {\n      role: 'model',\n      content: toolRequestParts\n        ? // Note: Not sure why I have to cast here exactly.\n          // Otherwise it thinks toolRequest must be 'undefined' if provided\n          (toolRequestParts as ToolRequestPart[])\n        : [\n            jsonMode\n              ? { data: JSON.parse(choice.message.content!) }\n              : { text: choice.message.content! },\n          ],\n    },\n  };\n}\n\n/**\n * Converts an OpenAI message stream event to a Genkit GenerateResponseData\n * object.\n * @param choice The OpenAI message stream event to convert.\n * @param jsonMode Whether the event is a JSON response.\n * @returns The converted Genkit GenerateResponseData object.\n */\nexport function fromOpenAIChunkChoice(\n  choice: ChatCompletionChunk.Choice,\n  jsonMode = false\n): GenerateResponseData {\n  const toolRequestParts = choice.delta.tool_calls?.map((toolCall) =>\n    fromOpenAIToolCall(toolCall, choice)\n  );\n  return {\n    finishReason: choice.finish_reason\n      ? finishReasonMap[choice.finish_reason] || 'other'\n      : 'unknown',\n    message: {\n      role: 'model',\n      content: toolRequestParts\n        ? // Note: Not sure why I have to cast here exactly.\n          // Otherwise it thinks toolRequest must be 'undefined' if provided\n          (toolRequestParts as ToolRequestPart[])\n        : [\n            jsonMode\n              ? { data: JSON.parse(choice.delta.content!) }\n              : { text: choice.delta.content! },\n          ],\n    },\n  };\n}\n\n/**\n * Converts an OpenAI request to an OpenAI API request body.\n * @param modelName The name of the OpenAI model to use.\n * @param request The Genkit GenerateRequest to convert.\n * @returns The converted OpenAI API request body.\n * @throws An error if the specified model is not supported or if an unsupported output format is requested.\n */\nexport function toOpenAIRequestBody(\n  modelName: string,\n  request: GenerateRequest,\n  requestBuilder?: ModelRequestBuilder\n) {\n  const messages = toOpenAIMessages(\n    request.messages,\n    request.config?.visualDetailLevel\n  );\n  const {\n    temperature,\n    maxOutputTokens, // unused\n    topK, // unused\n    topP: top_p,\n    frequencyPenalty: frequency_penalty,\n    logProbs: logprobs,\n    presencePenalty: presence_penalty,\n    topLogProbs: top_logprobs,\n    stopSequences: stop,\n    version: modelVersion,\n    tools: toolsFromConfig,\n    ...restOfConfig\n  } = request.config ?? {};\n\n  const tools: ChatCompletionTool[] = request.tools?.map(toOpenAITool) ?? [];\n  if (toolsFromConfig) {\n    tools.push(...(toolsFromConfig as any[]));\n  }\n  let body = {\n    model: modelVersion ?? modelName,\n    messages,\n    tools: tools.length > 0 ? tools : undefined,\n    temperature,\n    top_p,\n    stop,\n    frequency_penalty,\n    presence_penalty,\n    top_logprobs,\n    logprobs,\n  } as ChatCompletionCreateParamsNonStreaming;\n  if (requestBuilder) {\n    // If override provided, apply the override to the OpenAI request.\n    // User must control passthrough config too.\n    requestBuilder(request, body);\n  } else {\n    body = { ...body, ...restOfConfig }; // passthrough for other config\n  }\n  const response_format = request.output?.format;\n  if (response_format === 'json') {\n    body.response_format = {\n      type: 'json_object',\n    };\n  } else if (response_format === 'text') {\n    body.response_format = {\n      type: 'text',\n    };\n  }\n  for (const key in body) {\n    if (!body[key] || (Array.isArray(body[key]) && !body[key].length))\n      delete body[key];\n  }\n  return body;\n}\n\n/**\n * Creates the runner used by Genkit to interact with an OpenAI compatible\n * model.\n * @param name The name of the GPT model.\n * @param client The OpenAI client instance.\n * @returns The runner that Genkit will call when the model is invoked.\n */\nexport function openAIModelRunner(\n  name: string,\n  client: OpenAI,\n  requestBuilder?: ModelRequestBuilder\n) {\n  return async (\n    request: GenerateRequest,\n    options?: {\n      streamingRequested?: boolean;\n      sendChunk?: StreamingCallback<GenerateResponseChunkData>;\n      abortSignal?: AbortSignal;\n    }\n  ): Promise<GenerateResponseData> => {\n    let response: ChatCompletion;\n    const body = toOpenAIRequestBody(name, request, requestBuilder);\n    if (options?.streamingRequested) {\n      const stream = client.beta.chat.completions.stream(\n        {\n          ...body,\n          stream: true,\n          stream_options: {\n            include_usage: true,\n          },\n        },\n        { signal: options?.abortSignal }\n      );\n      for await (const chunk of stream) {\n        chunk.choices?.forEach((chunk) => {\n          const c = fromOpenAIChunkChoice(chunk);\n          options?.sendChunk!({\n            index: chunk.index,\n            content: c.message?.content ?? [],\n          });\n        });\n      }\n      response = await stream.finalChatCompletion();\n    } else {\n      response = await client.chat.completions.create(body, {\n        signal: options?.abortSignal,\n      });\n    }\n    const standardResponse: GenerateResponseData = {\n      usage: {\n        inputTokens: response.usage?.prompt_tokens,\n        outputTokens: response.usage?.completion_tokens,\n        totalTokens: response.usage?.total_tokens,\n      },\n      raw: response,\n    };\n    if (response.choices.length === 0) {\n      return standardResponse;\n    } else {\n      const choice = response.choices[0];\n      return {\n        ...fromOpenAIChoice(choice, request.output?.format === 'json'),\n        ...standardResponse,\n      };\n    }\n  };\n}\n\n/**\n * Method to define a new Genkit Model that is compatible with Open AI\n * Chat Completions API. \n *\n * These models are to be used to chat with a large language model.\n *\n * @param params An object containing parameters for defining the OpenAI\n * Chat model.\n * @param params.ai The Genkit AI instance.\n * @param params.name The name of the model.\n * @param params.client The OpenAI client instance.\n * @param params.modelRef Optional reference to the model's configuration and\n * custom options.\n\n * @returns the created {@link ModelAction}\n */\nexport function defineCompatOpenAIModel<\n  CustomOptions extends z.ZodTypeAny = z.ZodTypeAny,\n>(params: {\n  ai: Genkit;\n  name: string;\n  client: OpenAI;\n  modelRef?: ModelReference<CustomOptions>;\n  requestBuilder?: ModelRequestBuilder;\n}): ModelAction {\n  const { ai, name, client, modelRef, requestBuilder } = params;\n  const modelName = name.substring(name.indexOf('/') + 1);\n\n  return ai.defineModel(\n    {\n      name,\n      apiVersion: 'v2',\n      ...modelRef?.info,\n      configSchema: modelRef?.configSchema,\n    },\n    openAIModelRunner(modelName!, client, requestBuilder)\n  );\n}\n\nconst GENERIC_MODEL_INFO: ModelInfo = {\n  supports: {\n    multiturn: true,\n    media: true,\n    tools: true,\n    toolChoice: true,\n    systemRole: true,\n  },\n};\n\n/** ModelRef helper, with reasonable defaults for OpenAI-compatible providers */\nexport function compatOaiModelRef<\n  CustomOptions extends z.ZodTypeAny = z.ZodTypeAny,\n>(params: {\n  name: string;\n  info?: ModelInfo;\n  configSchema?: CustomOptions;\n  config?: any;\n}): ModelReference<CustomOptions> {\n  const {\n    name,\n    info = GENERIC_MODEL_INFO,\n    configSchema,\n    config = undefined,\n  } = params;\n  return modelRef({\n    name,\n    configSchema: configSchema || (ChatCompletionCommonConfigSchema as any),\n    info: info,\n    config,\n  });\n}\n"],"mappings":"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","names":["chunk","modelRef"]}