{"version":3,"sources":["../../src/generate/response.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 { Operation } from '@genkit-ai/core';\nimport { parseSchema } from '@genkit-ai/core/schema';\nimport {\n  GenerationBlockedError,\n  GenerationResponseError,\n} from '../generate.js';\nimport { Message, type MessageParser } from '../message.js';\nimport type {\n  GenerateRequest,\n  GenerateResponseData,\n  GenerationUsage,\n  MessageData,\n  ModelResponseData,\n  ToolRequestPart,\n} from '../model.js';\n\n/**\n * GenerateResponse is the result from a `generate()` call and contains one or\n * more generated candidate messages.\n */\nexport class GenerateResponse<O = unknown> implements ModelResponseData {\n  /** The generated message. */\n  message?: Message<O>;\n  /** The reason generation stopped for this request. */\n  finishReason: ModelResponseData['finishReason'];\n  /** Additional information about why the model stopped generating, if any. */\n  finishMessage?: string;\n  /** Usage information. */\n  usage: GenerationUsage;\n  /** Provider-specific response data. */\n  custom: unknown;\n  /** Provider-specific response data. */\n  raw: unknown;\n  /** The request that generated this response. */\n  request?: GenerateRequest;\n  /** Model generation long running operation. */\n  operation?: Operation<GenerateResponseData>;\n  /** Name of the model used. */\n  model?: string;\n  /** The parser for output parsing of this response. */\n  parser?: MessageParser<O>;\n\n  constructor(\n    response: GenerateResponseData,\n    options?: {\n      request?: GenerateRequest;\n      parser?: MessageParser<O>;\n    }\n  ) {\n    // Check for candidates in addition to message for backwards compatibility.\n    const generatedMessage =\n      response.message || response.candidates?.[0]?.message;\n    if (generatedMessage) {\n      if (\n        options?.request?.output?.contentType ||\n        options?.request?.output?.format\n      ) {\n        generatedMessage.metadata = {\n          ...generatedMessage.metadata,\n          generate: {\n            output: {\n              contentType: options?.request?.output?.contentType,\n              format: options?.request?.output?.format,\n            },\n          },\n        };\n      }\n      this.message = new Message<O>(generatedMessage, {\n        parser: options?.parser,\n      });\n    }\n    this.finishReason =\n      response.finishReason || response.candidates?.[0]?.finishReason!;\n    this.finishMessage =\n      response.finishMessage || response.candidates?.[0]?.finishMessage;\n    this.usage = response.usage || {};\n    this.custom = response.custom || {};\n    this.raw = response.raw || this.custom;\n    this.request = options?.request;\n    this.operation = response?.operation;\n  }\n\n  /**\n   * Throws an error if the response does not contain valid output.\n   */\n  assertValid(): void {\n    if (this.finishReason === 'blocked') {\n      throw new GenerationBlockedError(\n        this,\n        `Generation blocked${this.finishMessage ? `: ${this.finishMessage}` : '.'}`\n      );\n    }\n\n    if (!this.message && !this.operation) {\n      throw new GenerationResponseError(\n        this,\n        `Model did not generate a message. Finish reason: '${this.finishReason}': ${this.finishMessage}`\n      );\n    }\n  }\n\n  /**\n   * Throws an error if the response does not conform to expected schema.\n   */\n  assertValidSchema(request?: GenerateRequest): void {\n    if (request?.output?.schema || this.request?.output?.schema) {\n      const o = this.output;\n      parseSchema(o, {\n        jsonSchema: request?.output?.schema || this.request?.output?.schema,\n      });\n    }\n  }\n\n  isValid(request?: GenerateRequest): boolean {\n    try {\n      this.assertValid();\n      this.assertValidSchema(request);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  /**\n   * If the generated message contains a `data` part, it is returned. Otherwise,\n   * the `output()` method extracts the first valid JSON object or array from the text\n   * contained in the selected candidate's message and returns it.\n   *\n   * @returns The structured output contained in the selected candidate.\n   */\n  get output(): O | null {\n    return this.message?.output || null;\n  }\n\n  /**\n   * Concatenates all `text` parts present in the generated message with no delimiter.\n   * @returns A string of all concatenated text parts.\n   */\n  get text(): string {\n    return this.message?.text || '';\n  }\n\n  /**\n   * Concatenates all `reasoning` parts present in the generated message with no delimiter.\n   * @returns A string of all concatenated reasoning parts.\n   */\n  get reasoning(): string {\n    return this.message?.reasoning || '';\n  }\n\n  /**\n   * Returns the first detected media part in the generated message. Useful for\n   * extracting (for example) an image from a generation expected to create one.\n   * @returns The first detected `media` part in the candidate.\n   */\n  get media(): { url: string; contentType?: string } | null {\n    return this.message?.media || null;\n  }\n\n  /**\n   * Returns the first detected `data` part of the generated message.\n   * @returns The first `data` part detected in the candidate (if any).\n   */\n  get data(): O | null {\n    return this.message?.data || null;\n  }\n\n  /**\n   * Returns all tool request found in the generated message.\n   * @returns Array of all tool request found in the candidate.\n   */\n  get toolRequests(): ToolRequestPart[] {\n    return this.message?.toolRequests || [];\n  }\n\n  /**\n   * Returns all tool requests annotated as interrupts found in the generated message.\n   * @returns A list of ToolRequestParts.\n   */\n  get interrupts(): ToolRequestPart[] {\n    return this.message?.interrupts || [];\n  }\n\n  /**\n   * Returns the message history for the request by concatenating the model\n   * response to the list of messages from the request. The result of this\n   * method can be safely serialized to JSON for persistence in a database.\n   * @returns A serializable list of messages compatible with `generate({history})`.\n   */\n  get messages(): MessageData[] {\n    if (!this.request)\n      throw new Error(\n        \"Can't construct history for response without request reference.\"\n      );\n    if (!this.message)\n      throw new Error(\n        \"Can't construct history for response without generated message.\"\n      );\n    return [...this.request?.messages, this.message.toJSON()];\n  }\n\n  toJSON(): ModelResponseData {\n    const out = {\n      message: this.message?.toJSON(),\n      finishReason: this.finishReason,\n      finishMessage: this.finishMessage,\n      usage: this.usage,\n      custom: (this.custom as { toJSON?: () => any }).toJSON?.() || this.custom,\n      request: this.request,\n      operation: this.operation,\n    };\n    if (!out.finishMessage) delete out.finishMessage;\n    if (!out.request) delete out.request;\n    if (!out.operation) delete out.operation;\n    return out;\n  }\n}\n"],"mappings":"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","names":[]}