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