{"version":3,"sources":["../src/message.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 { extractJson } from './extract';\nimport type {\n  MessageData,\n  Part,\n  ToolRequestPart,\n  ToolResponsePart,\n} from './model';\n\nexport type MessageParser<T = unknown> = (message: Message) => T;\n\n/**\n * Message represents a single role's contribution to a generation. Each message\n * can contain multiple parts (for example text and an image), and each generation\n * can contain multiple messages.\n */\nexport class Message<T = unknown> implements MessageData {\n  role: MessageData['role'];\n  content: Part[];\n  metadata?: Record<string, any>;\n  parser?: MessageParser<T>;\n\n  static parseData(\n    lenientMessage:\n      | string\n      | (MessageData & { content: string | Part | Part[]; role: string })\n      | MessageData,\n    defaultRole: MessageData['role'] = 'user'\n  ): MessageData {\n    if (typeof lenientMessage === 'string') {\n      return { role: defaultRole, content: [{ text: lenientMessage }] };\n    }\n    return {\n      ...lenientMessage,\n      content: Message.parseContent(lenientMessage.content),\n    };\n  }\n\n  static parse(\n    lenientMessage: string | (MessageData & { content: string }) | MessageData\n  ): Message {\n    return new Message(Message.parseData(lenientMessage));\n  }\n\n  static parseContent(lenientPart: string | Part | (string | Part)[]): Part[] {\n    if (typeof lenientPart === 'string') {\n      return [{ text: lenientPart }];\n    } else if (Array.isArray(lenientPart)) {\n      return lenientPart.map((p) => (typeof p === 'string' ? { text: p } : p));\n    } else {\n      return [lenientPart];\n    }\n  }\n\n  constructor(message: MessageData, options?: { parser?: MessageParser<T> }) {\n    this.role = message.role;\n    this.content = message.content;\n    this.metadata = message.metadata;\n    this.parser = options?.parser;\n  }\n\n  /**\n   * Attempts to parse the content of the message according to the supplied\n   * output parser. Without a parser, returns `data` contained in the message or\n   * tries to parse JSON from the text of the message.\n   *\n   * @returns The structured output contained in the message.\n   */\n  get output(): T {\n    return this.parser?.(this) || this.data || extractJson<T>(this.text);\n  }\n\n  toolResponseParts(): ToolResponsePart[] {\n    const res = this.content.filter((part) => !!part.toolResponse);\n    return res as ToolResponsePart[];\n  }\n\n  /**\n   * Concatenates all `text` parts present in the message with no delimiter.\n   * @returns A string of all concatenated text parts.\n   */\n  get text(): string {\n    return this.content.map((part) => part.text || '').join('');\n  }\n\n  /**\n   * Concatenates all `reasoning` parts present in the message with no delimiter.\n   * @returns A string of all concatenated reasoning parts.\n   */\n  get reasoning(): string {\n    return this.content.map((part) => part.reasoning || '').join('');\n  }\n\n  /**\n   * Returns the first media part detected in the message. Useful for extracting\n   * (for example) an image from a generation expected to create one.\n   * @returns The first detected `media` part in the message.\n   */\n  get media(): { url: string; contentType?: string } | null {\n    return this.content.find((part) => part.media)?.media || null;\n  }\n\n  /**\n   * Returns the first detected `data` part of a message.\n   * @returns The first `data` part detected in the message (if any).\n   */\n  get data(): T | null {\n    return this.content.find((part) => part.data)?.data as T | null;\n  }\n\n  /**\n   * Returns all tool request found in this message.\n   * @returns Array of all tool request found in this message.\n   */\n  get toolRequests(): ToolRequestPart[] {\n    return this.content.filter(\n      (part) => !!part.toolRequest\n    ) as ToolRequestPart[];\n  }\n\n  /**\n   * Returns all tool requests annotated with interrupt metadata.\n   * @returns Array of all interrupt tool requests.\n   */\n  get interrupts(): ToolRequestPart[] {\n    return this.toolRequests.filter((t) => !!t.metadata?.interrupt);\n  }\n\n  /**\n   * Converts the Message to a plain JS object.\n   * @returns Plain JS object representing the data contained in the message.\n   */\n  toJSON(): MessageData {\n    const out: MessageData = {\n      role: this.role,\n      content: [...this.content],\n    };\n    if (this.metadata) out.metadata = this.metadata;\n    return out;\n  }\n}\n"],"mappings":"AAgBA,SAAS,mBAAmB;AAerB,MAAM,QAA4C;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,OAAO,UACL,gBAIA,cAAmC,QACtB;AACb,QAAI,OAAO,mBAAmB,UAAU;AACtC,aAAO,EAAE,MAAM,aAAa,SAAS,CAAC,EAAE,MAAM,eAAe,CAAC,EAAE;AAAA,IAClE;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,QAAQ,aAAa,eAAe,OAAO;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,OAAO,MACL,gBACS;AACT,WAAO,IAAI,QAAQ,QAAQ,UAAU,cAAc,CAAC;AAAA,EACtD;AAAA,EAEA,OAAO,aAAa,aAAwD;AAC1E,QAAI,OAAO,gBAAgB,UAAU;AACnC,aAAO,CAAC,EAAE,MAAM,YAAY,CAAC;AAAA,IAC/B,WAAW,MAAM,QAAQ,WAAW,GAAG;AACrC,aAAO,YAAY,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,EAAE,MAAM,EAAE,IAAI,CAAE;AAAA,IACzE,OAAO;AACL,aAAO,CAAC,WAAW;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,YAAY,SAAsB,SAAyC;AACzE,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ;AACvB,SAAK,WAAW,QAAQ;AACxB,SAAK,SAAS,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,SAAY;AACd,WAAO,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,YAAe,KAAK,IAAI;AAAA,EACrE;AAAA,EAEA,oBAAwC;AACtC,UAAM,MAAM,KAAK,QAAQ,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,YAAY;AAC7D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAe;AACjB,WAAO,KAAK,QAAQ,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,EAAE,KAAK,EAAE;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,YAAoB;AACtB,WAAO,KAAK,QAAQ,IAAI,CAAC,SAAS,KAAK,aAAa,EAAE,EAAE,KAAK,EAAE;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,QAAsD;AACxD,WAAO,KAAK,QAAQ,KAAK,CAAC,SAAS,KAAK,KAAK,GAAG,SAAS;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAiB;AACnB,WAAO,KAAK,QAAQ,KAAK,CAAC,SAAS,KAAK,IAAI,GAAG;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,eAAkC;AACpC,WAAO,KAAK,QAAQ;AAAA,MAClB,CAAC,SAAS,CAAC,CAAC,KAAK;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,aAAgC;AAClC,WAAO,KAAK,aAAa,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,SAAS;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAsB;AACpB,UAAM,MAAmB;AAAA,MACvB,MAAM,KAAK;AAAA,MACX,SAAS,CAAC,GAAG,KAAK,OAAO;AAAA,IAC3B;AACA,QAAI,KAAK,SAAU,KAAI,WAAW,KAAK;AACvC,WAAO;AAAA,EACT;AACF;","names":[]}