@genkit-ai/ai
Version:
Genkit AI framework generative AI APIs.
1 lines • 6 kB
Source Map (JSON)
{"version":3,"sources":["../../src/generate/chunk.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 { GenkitError } from '@genkit-ai/core';\nimport { extractJson } from '../extract.js';\nimport {\n GenerateResponseChunkData,\n Part,\n Role,\n ToolRequestPart,\n} from '../model.js';\n\nexport interface ChunkParser<T = unknown> {\n (chunk: GenerateResponseChunk<T>): T;\n}\n\nexport class GenerateResponseChunk<T = unknown>\n implements GenerateResponseChunkData\n{\n /** The index of the message this chunk corresponds to, starting with `0` for the first model response of the generation. */\n index: number;\n /** The role of the message this chunk corresponds to. Will always be `model` or `tool`. */\n role: Role;\n /** The content generated in this chunk. */\n content: Part[];\n /** Custom model-specific data for this chunk. */\n custom?: unknown;\n /** Accumulated chunks for partial output extraction. */\n previousChunks?: GenerateResponseChunkData[];\n /** The parser to be used to parse `output` from this chunk. */\n parser?: ChunkParser<T>;\n\n constructor(\n data: GenerateResponseChunkData,\n options: {\n previousChunks?: GenerateResponseChunkData[];\n role: Role;\n index: number;\n parser?: ChunkParser<T>;\n }\n ) {\n this.content = data.content || [];\n this.custom = data.custom;\n this.previousChunks = options.previousChunks\n ? [...options.previousChunks]\n : undefined;\n this.index = options.index;\n this.role = options.role;\n this.parser = options.parser;\n }\n\n /**\n * Concatenates all `text` parts present in the chunk 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 `text` parts of all chunks from the response thus far.\n * @returns A string of all concatenated chunk text content.\n */\n get accumulatedText(): string {\n return this.previousText + this.text;\n }\n\n /**\n * Concatenates all `text` parts of all preceding chunks.\n */\n get previousText(): string {\n if (!this.previousChunks)\n throw new GenkitError({\n status: 'FAILED_PRECONDITION',\n message: 'Cannot compose accumulated text without previous chunks.',\n });\n\n return this.previousChunks\n ?.map((c) => c.content.map((p) => p.text || '').join(''))\n .join('');\n }\n\n /**\n * Returns the first media part detected in the chunk. Useful for extracting\n * (for example) an image from a generation expected to create one.\n * @returns The first detected `media` part in the chunk.\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 chunk.\n * @returns The first `data` part detected in the chunk (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 chunk.\n * @returns Array of all tool request found in this chunk.\n */\n get toolRequests(): ToolRequestPart[] {\n return this.content.filter(\n (part) => !!part.toolRequest\n ) as ToolRequestPart[];\n }\n\n /**\n * Parses the chunk into the desired output format using the parser associated\n * with the generate request, or falls back to naive JSON parsing otherwise.\n */\n get output(): T | null {\n if (this.parser) return this.parser(this);\n return this.data || extractJson(this.accumulatedText);\n }\n\n toJSON(): GenerateResponseChunkData {\n const data = {\n role: this.role,\n index: this.index,\n content: this.content,\n } as GenerateResponseChunkData;\n if (this.custom) {\n data.custom = this.custom;\n }\n return data;\n }\n}\n"],"mappings":"AAgBA,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAYrB,MAAM,sBAEb;AAAA;AAAA,EAEE;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAEA,YACE,MACA,SAMA;AACA,SAAK,UAAU,KAAK,WAAW,CAAC;AAChC,SAAK,SAAS,KAAK;AACnB,SAAK,iBAAiB,QAAQ,iBAC1B,CAAC,GAAG,QAAQ,cAAc,IAC1B;AACJ,SAAK,QAAQ,QAAQ;AACrB,SAAK,OAAO,QAAQ;AACpB,SAAK,SAAS,QAAQ;AAAA,EACxB;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,kBAA0B;AAC5B,WAAO,KAAK,eAAe,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,eAAuB;AACzB,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,YAAY;AAAA,QACpB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAEH,WAAO,KAAK,gBACR,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EACvD,KAAK,EAAE;AAAA,EACZ;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,SAAmB;AACrB,QAAI,KAAK,OAAQ,QAAO,KAAK,OAAO,IAAI;AACxC,WAAO,KAAK,QAAQ,YAAY,KAAK,eAAe;AAAA,EACtD;AAAA,EAEA,SAAoC;AAClC,UAAM,OAAO;AAAA,MACX,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,IAChB;AACA,QAAI,KAAK,QAAQ;AACf,WAAK,SAAS,KAAK;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AACF;","names":[]}