@langchain/core
Version:
Core LangChain.js abstractions and schemas
1 lines • 28.9 kB
Source Map (JSON)
{"version":3,"file":"event_stream.cjs","names":["BaseTracer","IterableReadableStream","GenerationChunk","AIMessageChunk"],"sources":["../../src/tracers/event_stream.ts"],"sourcesContent":["import { BaseTracer, type Run } from \"./base.js\";\nimport {\n BaseCallbackHandler,\n BaseCallbackHandlerInput,\n CallbackHandlerPrefersStreaming,\n} from \"../callbacks/base.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { AIMessageChunk } from \"../messages/ai.js\";\nimport { ChatGeneration, Generation, GenerationChunk } from \"../outputs.js\";\nimport { BaseMessage } from \"../messages/base.js\";\n\n/**\n * Data associated with a StreamEvent.\n */\nexport type StreamEventData = {\n /**\n * The input passed to the runnable that generated the event.\n * Inputs will sometimes be available at the *START* of the runnable, and\n * sometimes at the *END* of the runnable.\n * If a runnable is able to stream its inputs, then its input by definition\n * won't be known until the *END* of the runnable when it has finished streaming\n * its inputs.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input?: any;\n\n /**\n * The output of the runnable that generated the event.\n * Outputs will only be available at the *END* of the runnable.\n * For most runnables, this field can be inferred from the `chunk` field,\n * though there might be some exceptions for special cased runnables (e.g., like\n * chat models), which may return more information.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n output?: any;\n\n /**\n * A streaming chunk from the output that generated the event.\n * chunks support addition in general, and adding them up should result\n * in the output of the runnable that generated the event.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n chunk?: any;\n\n /**\n * Error message if the runnable that generated the event failed.\n * This field will only be present if the runnable failed.\n */\n error?: string;\n};\n\n/**\n * A streaming event.\n *\n * Schema of a streaming event which is produced from the streamEvents method.\n */\nexport type StreamEvent = {\n /**\n * Event names are of the format: on_[runnable_type]_(start|stream|end).\n *\n * Runnable types are one of:\n * - llm - used by non chat models\n * - chat_model - used by chat models\n * - prompt -- e.g., ChatPromptTemplate\n * - tool -- LangChain tools\n * - chain - most Runnables are of this type\n *\n * Further, the events are categorized as one of:\n * - start - when the runnable starts\n * - stream - when the runnable is streaming\n * - end - when the runnable ends\n *\n * start, stream and end are associated with slightly different `data` payload.\n *\n * Please see the documentation for `EventData` for more details.\n */\n event: string;\n /** The name of the runnable that generated the event. */\n name: string;\n /**\n * An randomly generated ID to keep track of the execution of the given runnable.\n *\n * Each child runnable that gets invoked as part of the execution of a parent runnable\n * is assigned its own unique ID.\n */\n run_id: string;\n /**\n * Tags associated with the runnable that generated this event.\n * Tags are always inherited from parent runnables.\n */\n tags?: string[];\n /** Metadata associated with the runnable that generated this event. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n metadata: Record<string, any>;\n /**\n * Event data.\n *\n * The contents of the event data depend on the event type.\n */\n data: StreamEventData;\n};\n\ntype RunInfo = {\n name: string;\n tags: string[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n metadata: Record<string, any>;\n runType: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n inputs?: Record<string, any>;\n};\n\nexport interface EventStreamCallbackHandlerInput extends BaseCallbackHandlerInput {\n autoClose?: boolean;\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n}\n\nfunction assignName({\n name,\n serialized,\n}: {\n name?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n serialized?: Record<string, any>;\n}): string {\n if (name !== undefined) {\n return name;\n }\n if (serialized?.name !== undefined) {\n return serialized.name;\n } else if (serialized?.id !== undefined && Array.isArray(serialized?.id)) {\n return serialized.id[serialized.id.length - 1];\n }\n return \"Unnamed\";\n}\n\nexport const isStreamEventsHandler = (\n handler: BaseCallbackHandler\n): handler is EventStreamCallbackHandler =>\n handler.name === \"event_stream_tracer\";\n\n/**\n * Class that extends the `BaseTracer` class from the\n * `langchain.callbacks.tracers.base` module. It represents a callback\n * handler that logs the execution of runs and emits `RunLog` instances to a\n * `RunLogStream`.\n */\nexport class EventStreamCallbackHandler\n extends BaseTracer\n implements CallbackHandlerPrefersStreaming\n{\n protected autoClose = true;\n\n protected includeNames?: string[];\n\n protected includeTypes?: string[];\n\n protected includeTags?: string[];\n\n protected excludeNames?: string[];\n\n protected excludeTypes?: string[];\n\n protected excludeTags?: string[];\n\n private runInfoMap: Map<string, RunInfo> = new Map();\n\n private tappedPromises: Map<string, Promise<void>> = new Map();\n\n protected transformStream: TransformStream;\n\n public writer: WritableStreamDefaultWriter;\n\n public receiveStream: IterableReadableStream<StreamEvent>;\n\n private readableStreamClosed = false;\n\n name = \"event_stream_tracer\";\n\n lc_prefer_streaming = true;\n\n constructor(fields?: EventStreamCallbackHandlerInput) {\n super({ _awaitHandler: true, ...fields });\n this.autoClose = fields?.autoClose ?? true;\n this.includeNames = fields?.includeNames;\n this.includeTypes = fields?.includeTypes;\n this.includeTags = fields?.includeTags;\n this.excludeNames = fields?.excludeNames;\n this.excludeTypes = fields?.excludeTypes;\n this.excludeTags = fields?.excludeTags;\n this.transformStream = new TransformStream({\n flush: () => {\n this.readableStreamClosed = true;\n },\n });\n this.writer = this.transformStream.writable.getWriter();\n this.receiveStream = IterableReadableStream.fromReadableStream(\n this.transformStream.readable\n );\n }\n\n [Symbol.asyncIterator]() {\n return this.receiveStream;\n }\n\n protected async persistRun(_run: Run): Promise<void> {\n // This is a legacy method only called once for an entire run tree\n // and is therefore not useful here\n }\n\n _includeRun(run: RunInfo): boolean {\n const runTags = run.tags ?? [];\n let include =\n this.includeNames === undefined &&\n this.includeTags === undefined &&\n this.includeTypes === undefined;\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(run.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(run.runType);\n }\n if (this.includeTags !== undefined) {\n include =\n include ||\n runTags.find((tag) => this.includeTags?.includes(tag)) !== undefined;\n }\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(run.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(run.runType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && runTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n return include;\n }\n\n async *tapOutputIterable<T>(\n runId: string,\n outputStream: AsyncGenerator<T>\n ): AsyncGenerator<T> {\n const firstChunk = await outputStream.next();\n if (firstChunk.done) {\n return;\n }\n const runInfo = this.runInfoMap.get(runId);\n // Run has finished, don't issue any stream events.\n // An example of this is for runnables that use the default\n // implementation of .stream(), which delegates to .invoke()\n // and calls .onChainEnd() before passing it to the iterator.\n if (runInfo === undefined) {\n yield firstChunk.value;\n return;\n }\n // Match format from handlers below\n function _formatOutputChunk(eventType: string, data: unknown) {\n if (eventType === \"llm\" && typeof data === \"string\") {\n return new GenerationChunk({ text: data });\n }\n return data;\n }\n let tappedPromise = this.tappedPromises.get(runId);\n // if we are the first to tap, issue stream events\n if (tappedPromise === undefined) {\n let tappedPromiseResolver: (() => void) | undefined;\n tappedPromise = new Promise((resolve) => {\n tappedPromiseResolver = resolve;\n });\n this.tappedPromises.set(runId, tappedPromise);\n try {\n const event: StreamEvent = {\n event: `on_${runInfo.runType}_stream`,\n run_id: runId,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n data: {},\n };\n await this.send(\n {\n ...event,\n data: {\n chunk: _formatOutputChunk(runInfo.runType, firstChunk.value),\n },\n },\n runInfo\n );\n yield firstChunk.value;\n for await (const chunk of outputStream) {\n // Don't yield tool and retriever stream events\n if (runInfo.runType !== \"tool\" && runInfo.runType !== \"retriever\") {\n await this.send(\n {\n ...event,\n data: {\n chunk: _formatOutputChunk(runInfo.runType, chunk),\n },\n },\n runInfo\n );\n }\n yield chunk;\n }\n } finally {\n tappedPromiseResolver?.();\n // Don't delete from the promises map to keep track of which runs have been tapped.\n }\n } else {\n // otherwise just pass through\n yield firstChunk.value;\n for await (const chunk of outputStream) {\n yield chunk;\n }\n }\n }\n\n async send(payload: StreamEvent, run: RunInfo) {\n if (this.readableStreamClosed) return;\n if (this._includeRun(run)) {\n await this.writer.write(payload);\n }\n }\n\n async sendEndEvent(payload: StreamEvent, run: RunInfo) {\n const tappedPromise = this.tappedPromises.get(payload.run_id);\n if (tappedPromise !== undefined) {\n // eslint-disable-next-line no-void\n void tappedPromise.then(() => {\n // eslint-disable-next-line no-void\n void this.send(payload, run);\n });\n } else {\n await this.send(payload, run);\n }\n }\n\n async onLLMStart(run: Run): Promise<void> {\n const runName = assignName(run);\n const runType = run.inputs.messages !== undefined ? \"chat_model\" : \"llm\";\n const runInfo = {\n tags: run.tags ?? [],\n metadata: run.extra?.metadata ?? {},\n name: runName,\n runType,\n inputs: run.inputs,\n };\n this.runInfoMap.set(run.id, runInfo);\n const eventName = `on_${runType}_start`;\n await this.send(\n {\n event: eventName,\n data: {\n input: run.inputs,\n },\n name: runName,\n tags: run.tags ?? [],\n run_id: run.id,\n metadata: run.extra?.metadata ?? {},\n },\n runInfo\n );\n }\n\n async onLLMNewToken(\n run: Run,\n token: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n kwargs?: { chunk: any }\n ): Promise<void> {\n const runInfo = this.runInfoMap.get(run.id);\n let chunk;\n let eventName;\n if (runInfo === undefined) {\n throw new Error(`onLLMNewToken: Run ID ${run.id} not found in run map.`);\n }\n // Top-level streaming events are covered by tapOutputIterable\n if (this.runInfoMap.size === 1) {\n return;\n }\n if (runInfo.runType === \"chat_model\") {\n eventName = \"on_chat_model_stream\";\n if (kwargs?.chunk === undefined) {\n chunk = new AIMessageChunk({ content: token, id: `run-${run.id}` });\n } else {\n chunk = kwargs.chunk.message;\n }\n } else if (runInfo.runType === \"llm\") {\n eventName = \"on_llm_stream\";\n if (kwargs?.chunk === undefined) {\n chunk = new GenerationChunk({ text: token });\n } else {\n chunk = kwargs.chunk;\n }\n } else {\n throw new Error(`Unexpected run type ${runInfo.runType}`);\n }\n await this.send(\n {\n event: eventName,\n data: {\n chunk,\n },\n run_id: run.id,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n },\n runInfo\n );\n }\n\n async onLLMEnd(run: Run): Promise<void> {\n const runInfo = this.runInfoMap.get(run.id);\n this.runInfoMap.delete(run.id);\n let eventName: string;\n if (runInfo === undefined) {\n throw new Error(`onLLMEnd: Run ID ${run.id} not found in run map.`);\n }\n const generations: ChatGeneration[][] | Generation[][] | undefined =\n run.outputs?.generations;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let output: BaseMessage | Record<string, any> | undefined;\n if (runInfo.runType === \"chat_model\") {\n for (const generation of generations ?? []) {\n if (output !== undefined) {\n break;\n }\n output = (generation[0] as ChatGeneration | undefined)?.message;\n }\n eventName = \"on_chat_model_end\";\n } else if (runInfo.runType === \"llm\") {\n output = {\n generations: generations?.map((generation) => {\n return generation.map((chunk) => {\n return {\n text: chunk.text,\n generationInfo: chunk.generationInfo,\n };\n });\n }),\n llmOutput: run.outputs?.llmOutput ?? {},\n };\n eventName = \"on_llm_end\";\n } else {\n throw new Error(`onLLMEnd: Unexpected run type: ${runInfo.runType}`);\n }\n await this.sendEndEvent(\n {\n event: eventName,\n data: {\n output,\n input: runInfo.inputs,\n },\n run_id: run.id,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n },\n runInfo\n );\n }\n\n async onChainStart(run: Run): Promise<void> {\n const runName = assignName(run);\n const runType = run.run_type ?? \"chain\";\n const runInfo: RunInfo = {\n tags: run.tags ?? [],\n metadata: run.extra?.metadata ?? {},\n name: runName,\n runType: run.run_type,\n };\n let eventData: StreamEventData = {};\n // Workaround Runnable core code not sending input when transform streaming.\n if (run.inputs.input === \"\" && Object.keys(run.inputs).length === 1) {\n eventData = {};\n runInfo.inputs = {};\n } else if (run.inputs.input !== undefined) {\n eventData.input = run.inputs.input;\n runInfo.inputs = run.inputs.input;\n } else {\n eventData.input = run.inputs;\n runInfo.inputs = run.inputs;\n }\n this.runInfoMap.set(run.id, runInfo);\n await this.send(\n {\n event: `on_${runType}_start`,\n data: eventData,\n name: runName,\n tags: run.tags ?? [],\n run_id: run.id,\n metadata: run.extra?.metadata ?? {},\n },\n runInfo\n );\n }\n\n async onChainEnd(run: Run): Promise<void> {\n const runInfo = this.runInfoMap.get(run.id);\n this.runInfoMap.delete(run.id);\n if (runInfo === undefined) {\n throw new Error(`onChainEnd: Run ID ${run.id} not found in run map.`);\n }\n const eventName = `on_${run.run_type}_end`;\n const inputs = run.inputs ?? runInfo.inputs ?? {};\n const outputs = run.outputs?.output ?? run.outputs;\n const data: StreamEventData = {\n output: outputs,\n input: inputs,\n };\n if (inputs.input && Object.keys(inputs).length === 1) {\n data.input = inputs.input;\n runInfo.inputs = inputs.input;\n }\n await this.sendEndEvent(\n {\n event: eventName,\n data,\n run_id: run.id,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata ?? {},\n },\n runInfo\n );\n }\n\n async onToolStart(run: Run): Promise<void> {\n const runName = assignName(run);\n const runInfo = {\n tags: run.tags ?? [],\n metadata: run.extra?.metadata ?? {},\n name: runName,\n runType: \"tool\",\n inputs: run.inputs ?? {},\n };\n this.runInfoMap.set(run.id, runInfo);\n await this.send(\n {\n event: \"on_tool_start\",\n data: {\n input: run.inputs ?? {},\n },\n name: runName,\n run_id: run.id,\n tags: run.tags ?? [],\n metadata: run.extra?.metadata ?? {},\n },\n runInfo\n );\n }\n\n async onToolEnd(run: Run): Promise<void> {\n const runInfo = this.runInfoMap.get(run.id);\n this.runInfoMap.delete(run.id);\n if (runInfo === undefined) {\n throw new Error(`onToolEnd: Run ID ${run.id} not found in run map.`);\n }\n if (runInfo.inputs === undefined) {\n throw new Error(\n `onToolEnd: Run ID ${run.id} is a tool call, and is expected to have traced inputs.`\n );\n }\n const output =\n run.outputs?.output === undefined ? run.outputs : run.outputs.output;\n await this.sendEndEvent(\n {\n event: \"on_tool_end\",\n data: {\n output,\n input: runInfo.inputs,\n },\n run_id: run.id,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n },\n runInfo\n );\n }\n\n async onToolError(run: Run): Promise<void> {\n const runInfo = this.runInfoMap.get(run.id);\n this.runInfoMap.delete(run.id);\n if (runInfo === undefined) {\n throw new Error(`onToolEnd: Run ID ${run.id} not found in run map.`);\n }\n if (runInfo.inputs === undefined) {\n throw new Error(\n `onToolEnd: Run ID ${run.id} is a tool call, and is expected to have traced inputs.`\n );\n }\n\n await this.sendEndEvent(\n {\n event: \"on_tool_error\",\n data: {\n input: runInfo.inputs,\n error: run.error,\n },\n run_id: run.id,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n },\n runInfo\n );\n }\n\n async onRetrieverStart(run: Run): Promise<void> {\n const runName = assignName(run);\n const runType = \"retriever\";\n const runInfo = {\n tags: run.tags ?? [],\n metadata: run.extra?.metadata ?? {},\n name: runName,\n runType,\n inputs: {\n query: run.inputs.query,\n },\n };\n this.runInfoMap.set(run.id, runInfo);\n await this.send(\n {\n event: \"on_retriever_start\",\n data: {\n input: {\n query: run.inputs.query,\n },\n },\n name: runName,\n tags: run.tags ?? [],\n run_id: run.id,\n metadata: run.extra?.metadata ?? {},\n },\n runInfo\n );\n }\n\n async onRetrieverEnd(run: Run): Promise<void> {\n const runInfo = this.runInfoMap.get(run.id);\n this.runInfoMap.delete(run.id);\n if (runInfo === undefined) {\n throw new Error(`onRetrieverEnd: Run ID ${run.id} not found in run map.`);\n }\n await this.sendEndEvent(\n {\n event: \"on_retriever_end\",\n data: {\n output: run.outputs?.documents ?? run.outputs,\n input: runInfo.inputs,\n },\n run_id: run.id,\n name: runInfo.name,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n },\n runInfo\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async handleCustomEvent(eventName: string, data: any, runId: string) {\n const runInfo = this.runInfoMap.get(runId);\n if (runInfo === undefined) {\n throw new Error(\n `handleCustomEvent: Run ID ${runId} not found in run map.`\n );\n }\n await this.send(\n {\n event: \"on_custom_event\",\n run_id: runId,\n name: eventName,\n tags: runInfo.tags,\n metadata: runInfo.metadata,\n data,\n },\n runInfo\n );\n }\n\n async finish() {\n const pendingPromises = [...this.tappedPromises.values()];\n // eslint-disable-next-line no-void\n void Promise.all(pendingPromises).finally(() => {\n // eslint-disable-next-line no-void\n void this.writer.close();\n });\n }\n}\n"],"mappings":"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"}