illuma-agents 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/run.cjs +105 -33
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/esm/run.mjs +106 -34
- package/dist/esm/run.mjs.map +1 -1
- package/dist/types/run.d.ts +4 -3
- package/package.json +1 -1
- package/src/run.ts +120 -36
package/dist/cjs/run.cjs
CHANGED
|
@@ -345,8 +345,8 @@ class Run {
|
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
347
|
* Process stream with browser interrupt support.
|
|
348
|
-
* Uses
|
|
349
|
-
*
|
|
348
|
+
* Uses streamEvents() like processStream to emit SSE events,
|
|
349
|
+
* then checks for interrupts after stream completes.
|
|
350
350
|
*/
|
|
351
351
|
async *processBrowserStream(inputs, config, streamOptions) {
|
|
352
352
|
if (this.graphRunnable == null) {
|
|
@@ -365,28 +365,65 @@ class Run {
|
|
|
365
365
|
run_id: this.id,
|
|
366
366
|
thread_id: this.id, // Use run ID as thread ID for browser sessions
|
|
367
367
|
});
|
|
368
|
-
//
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
368
|
+
// Set up callbacks for SSE event emission (same as processStream)
|
|
369
|
+
const customEventCallback = this.createCustomEventCallback();
|
|
370
|
+
const baseCallbacks = config.callbacks ?? [];
|
|
371
|
+
const streamCallbacks = streamOptions?.callbacks
|
|
372
|
+
? this.getCallbacks(streamOptions.callbacks)
|
|
373
|
+
: [];
|
|
374
|
+
config.callbacks = baseCallbacks.concat(streamCallbacks).concat({
|
|
375
|
+
[_enum.Callback.CUSTOM_EVENT]: customEventCallback,
|
|
376
|
+
});
|
|
377
|
+
// Use streamEvents like processStream to emit proper SSE events
|
|
378
|
+
const stream = this.graphRunnable.streamEvents(inputs, config, {
|
|
379
|
+
raiseError: true,
|
|
380
|
+
ignoreCustomEvent: true,
|
|
372
381
|
});
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
+
try {
|
|
383
|
+
for await (const event of stream) {
|
|
384
|
+
const { data, metadata, ...info } = event;
|
|
385
|
+
const eventName = info.event;
|
|
386
|
+
// Skip custom events as they're handled by our callback
|
|
387
|
+
if (eventName === _enum.GraphEvents.ON_CUSTOM_EVENT) {
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
const handler = this.handlerRegistry?.getHandler(eventName);
|
|
391
|
+
if (handler) {
|
|
392
|
+
await handler.handle(eventName, data, metadata, this.Graph);
|
|
393
|
+
}
|
|
394
|
+
// Also yield the event for the caller to process
|
|
395
|
+
yield { type: 'event', data: event };
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
// streamEvents may throw when interrupt happens
|
|
400
|
+
// Check if this is an interrupt-related termination
|
|
401
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
402
|
+
if (errorMessage.includes('interrupt') || errorMessage.includes('GraphInterrupt')) ;
|
|
403
|
+
else {
|
|
404
|
+
throw error;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// After stream completes, check for pending interrupts using getState
|
|
408
|
+
// The checkpointer stores the interrupt state
|
|
409
|
+
try {
|
|
410
|
+
const state = await this.graphRunnable.getState(config);
|
|
411
|
+
if (state?.tasks) {
|
|
412
|
+
for (const task of state.tasks) {
|
|
413
|
+
if (task.interrupts && task.interrupts.length > 0) {
|
|
414
|
+
for (const interruptInfo of task.interrupts) {
|
|
415
|
+
if (interruptInfo.value?.type === 'browser_interrupt') {
|
|
416
|
+
yield { type: 'interrupt', data: interruptInfo.value };
|
|
417
|
+
return; // Stop after yielding interrupt
|
|
418
|
+
}
|
|
382
419
|
}
|
|
383
420
|
}
|
|
384
|
-
// Stop yielding - graph is paused
|
|
385
|
-
return;
|
|
386
421
|
}
|
|
387
422
|
}
|
|
388
|
-
|
|
389
|
-
|
|
423
|
+
}
|
|
424
|
+
catch (stateError) {
|
|
425
|
+
// getState may fail if no checkpointer - that's ok for non-browser flows
|
|
426
|
+
console.debug('[processBrowserStream] Could not get state:', stateError);
|
|
390
427
|
}
|
|
391
428
|
// Stream completed without interrupt
|
|
392
429
|
if (this.returnContent) {
|
|
@@ -399,8 +436,9 @@ class Run {
|
|
|
399
436
|
/**
|
|
400
437
|
* Resume a browser stream after interrupt.
|
|
401
438
|
* Call this with the result from the browser extension.
|
|
439
|
+
* Uses streamEvents() to emit proper SSE events during resume.
|
|
402
440
|
*/
|
|
403
|
-
async *resumeBrowserStream(result, config) {
|
|
441
|
+
async *resumeBrowserStream(result, config, streamOptions) {
|
|
404
442
|
if (this.graphRunnable == null) {
|
|
405
443
|
throw new Error('Run not initialized. Make sure to use Run.create() to instantiate the Run.');
|
|
406
444
|
}
|
|
@@ -415,26 +453,60 @@ class Run {
|
|
|
415
453
|
run_id: this.id,
|
|
416
454
|
thread_id: this.id,
|
|
417
455
|
});
|
|
456
|
+
// Set up callbacks for SSE event emission (same as processStream)
|
|
457
|
+
const customEventCallback = this.createCustomEventCallback();
|
|
458
|
+
const baseCallbacks = config.callbacks ?? [];
|
|
459
|
+
const streamCallbacks = streamOptions?.callbacks
|
|
460
|
+
? this.getCallbacks(streamOptions.callbacks)
|
|
461
|
+
: [];
|
|
462
|
+
config.callbacks = baseCallbacks.concat(streamCallbacks).concat({
|
|
463
|
+
[_enum.Callback.CUSTOM_EVENT]: customEventCallback,
|
|
464
|
+
});
|
|
418
465
|
// Use Command to resume with the browser result
|
|
419
466
|
const resumeCommand = new langgraph.Command({ resume: result });
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
467
|
+
// Use streamEvents for proper SSE event emission
|
|
468
|
+
const stream = this.graphRunnable.streamEvents(resumeCommand, config, {
|
|
469
|
+
raiseError: true,
|
|
470
|
+
ignoreCustomEvent: true,
|
|
423
471
|
});
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
472
|
+
try {
|
|
473
|
+
for await (const event of stream) {
|
|
474
|
+
const { data, metadata, ...info } = event;
|
|
475
|
+
const eventName = info.event;
|
|
476
|
+
if (eventName === _enum.GraphEvents.ON_CUSTOM_EVENT) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
const handler = this.handlerRegistry?.getHandler(eventName);
|
|
480
|
+
if (handler) {
|
|
481
|
+
await handler.handle(eventName, data, metadata, this.Graph);
|
|
482
|
+
}
|
|
483
|
+
yield { type: 'event', data: event };
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
488
|
+
if (!errorMessage.includes('interrupt') && !errorMessage.includes('GraphInterrupt')) {
|
|
489
|
+
throw error;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// Check for additional interrupts after resume
|
|
493
|
+
try {
|
|
494
|
+
const state = await this.graphRunnable.getState(config);
|
|
495
|
+
if (state?.tasks) {
|
|
496
|
+
for (const task of state.tasks) {
|
|
497
|
+
if (task.interrupts && task.interrupts.length > 0) {
|
|
498
|
+
for (const interruptInfo of task.interrupts) {
|
|
499
|
+
if (interruptInfo.value?.type === 'browser_interrupt') {
|
|
500
|
+
yield { type: 'interrupt', data: interruptInfo.value };
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
432
503
|
}
|
|
433
504
|
}
|
|
434
|
-
return;
|
|
435
505
|
}
|
|
436
506
|
}
|
|
437
|
-
|
|
507
|
+
}
|
|
508
|
+
catch (stateError) {
|
|
509
|
+
console.debug('[resumeBrowserStream] Could not get state:', stateError);
|
|
438
510
|
}
|
|
439
511
|
if (this.returnContent) {
|
|
440
512
|
yield { type: 'done', data: this.Graph.getContentParts() };
|
package/dist/cjs/run.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.cjs","sources":["../../src/run.ts"],"sourcesContent":["// src/run.ts\nimport './instrumentation';\nimport { CallbackHandler } from '@langfuse/langchain';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport { RunnableLambda } from '@langchain/core/runnables';\nimport { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';\nimport { MemorySaver } from '@langchain/langgraph-checkpoint';\nimport { Command, INTERRUPT, isInterrupted } from '@langchain/langgraph';\nimport type {\n MessageContentComplex,\n BaseMessage,\n} from '@langchain/core/messages';\nimport type { StringPromptValue } from '@langchain/core/prompt_values';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from '@/types';\nimport {\n createCompletionTitleRunnable,\n createTitleRunnable,\n} from '@/utils/title';\nimport { GraphEvents, Callback, TitleMethod } from '@/common';\nimport { MultiAgentGraph } from '@/graphs/MultiAgentGraph';\nimport { createTokenCounter } from '@/utils/tokens';\nimport { StandardGraph } from '@/graphs/Graph';\nimport { HandlerRegistry } from '@/events';\nimport { isOpenAILike } from '@/utils/llm';\nimport { isPresent } from '@/utils/misc';\nimport type { BrowserInterrupt, BrowserActionResult } from '@/tools/BrowserInterruptTools';\n\nexport const defaultOmitOptions = new Set([\n 'stream',\n 'thinking',\n 'streaming',\n 'maxTokens',\n 'clientOptions',\n 'thinkingConfig',\n 'thinkingBudget',\n 'includeThoughts',\n 'maxOutputTokens',\n 'additionalModelRequestFields',\n]);\n\n/** Global checkpointer store for browser mode (keyed by runId) */\nconst browserCheckpointers = new Map<string, MemorySaver>();\n\n/**\n * Get or create a checkpointer for browser mode\n */\nexport function getBrowserCheckpointer(runId: string): MemorySaver {\n let checkpointer = browserCheckpointers.get(runId);\n if (!checkpointer) {\n checkpointer = new MemorySaver();\n browserCheckpointers.set(runId, checkpointer);\n }\n return checkpointer;\n}\n\n/**\n * Clean up a browser checkpointer when done\n */\nexport function cleanupBrowserCheckpointer(runId: string): void {\n browserCheckpointers.delete(runId);\n}\n\nexport class Run<_T extends t.BaseGraphState> {\n id: string;\n private tokenCounter?: t.TokenCounter;\n private handlerRegistry?: HandlerRegistry;\n private indexTokenCountMap?: Record<string, number>;\n /** Whether this run is in browser extension mode */\n browserMode: boolean = false;\n graphRunnable?: t.CompiledStateWorkflow;\n Graph: StandardGraph | MultiAgentGraph | undefined;\n returnContent: boolean = false;\n\n private constructor(config: Partial<t.RunConfig>) {\n const runId = config.runId ?? '';\n if (!runId) {\n throw new Error('Run ID not provided');\n }\n\n this.id = runId;\n this.tokenCounter = config.tokenCounter;\n this.indexTokenCountMap = config.indexTokenCountMap;\n this.browserMode = config.browserMode ?? false;\n\n const handlerRegistry = new HandlerRegistry();\n\n if (config.customHandlers) {\n for (const [eventType, handler] of Object.entries(\n config.customHandlers\n )) {\n handlerRegistry.register(eventType, handler);\n }\n }\n\n this.handlerRegistry = handlerRegistry;\n\n if (!config.graphConfig) {\n throw new Error('Graph config not provided');\n }\n\n /** Handle different graph types */\n if (config.graphConfig.type === 'multi-agent') {\n // For multi-agent, browser mode checkpointer support not yet implemented\n this.graphRunnable = this.createMultiAgentGraph(config.graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n } else {\n /** Default to legacy graph for 'standard' or undefined type */\n // In browser mode, inject checkpointer into compileOptions BEFORE creating the graph\n const graphConfig = { ...config.graphConfig };\n if (this.browserMode) {\n const checkpointer = getBrowserCheckpointer(runId);\n graphConfig.compileOptions = {\n ...graphConfig.compileOptions,\n checkpointer,\n };\n }\n this.graphRunnable = this.createLegacyGraph(graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n }\n\n this.returnContent = config.returnContent ?? false;\n }\n\n private createLegacyGraph(\n config: t.LegacyGraphConfig | t.StandardGraphConfig\n ): t.CompiledStateWorkflow {\n let agentConfig: t.AgentInputs;\n let signal: AbortSignal | undefined;\n\n /** Check if this is a multi-agent style config (has agents array) */\n if ('agents' in config && Array.isArray(config.agents)) {\n if (config.agents.length === 0) {\n throw new Error('At least one agent must be provided');\n }\n agentConfig = config.agents[0];\n signal = config.signal;\n } else {\n /** Legacy path: build agent config from llmConfig */\n const {\n type: _type,\n llmConfig,\n signal: legacySignal,\n tools = [],\n ...agentInputs\n } = config as t.LegacyGraphConfig;\n const { provider, ...clientOptions } = llmConfig;\n\n agentConfig = {\n ...agentInputs,\n tools,\n provider,\n clientOptions,\n agentId: 'default',\n };\n signal = legacySignal;\n }\n\n const standardGraph = new StandardGraph({\n signal,\n runId: this.id,\n agents: [agentConfig],\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n /** Propagate compile options from graph config */\n standardGraph.compileOptions = config.compileOptions;\n this.Graph = standardGraph;\n return standardGraph.createWorkflow();\n }\n\n private createMultiAgentGraph(\n config: t.MultiAgentGraphConfig\n ): t.CompiledStateWorkflow {\n const { agents, edges, compileOptions } = config;\n\n const multiAgentGraph = new MultiAgentGraph({\n runId: this.id,\n agents,\n edges,\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n\n if (compileOptions != null) {\n multiAgentGraph.compileOptions = compileOptions;\n }\n\n this.Graph = multiAgentGraph;\n return multiAgentGraph.createWorkflow();\n }\n\n static async create<T extends t.BaseGraphState>(\n config: t.RunConfig\n ): Promise<Run<T>> {\n /** Create tokenCounter if indexTokenCountMap is provided but tokenCounter is not */\n if (config.indexTokenCountMap && !config.tokenCounter) {\n config.tokenCounter = await createTokenCounter();\n }\n return new Run<T>(config);\n }\n\n getRunMessages(): BaseMessage[] | undefined {\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n return this.Graph.getRunMessages();\n }\n\n /**\n * Creates a custom event callback handler that intercepts custom events\n * and processes them through our handler registry instead of EventStreamCallbackHandler\n */\n private createCustomEventCallback() {\n return async (\n eventName: string,\n data: unknown,\n runId: string,\n tags?: string[],\n metadata?: Record<string, unknown>\n ): Promise<void> => {\n if (\n (data as t.StreamEventData)['emitted'] === true &&\n eventName === GraphEvents.CHAT_MODEL_STREAM\n ) {\n return;\n }\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler && this.Graph) {\n return await handler.handle(\n eventName,\n data as\n | t.StreamEventData\n | t.ModelEndData\n | t.RunStep\n | t.RunStepDeltaEvent\n | t.MessageDeltaEvent\n | t.ReasoningDeltaEvent\n | { result: t.ToolEndEvent },\n metadata,\n this.Graph\n );\n }\n };\n }\n\n async processStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): Promise<MessageContentComplex[] | undefined> {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n /** Custom event callback to intercept and handle custom events */\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n if (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = config.configurable?.user_id;\n const sessionId = config.configurable?.thread_id;\n const traceMetadata = {\n messageId: this.id,\n parentMessageId: config.configurable?.requestBody?.parentMessageId,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n config.callbacks = (\n (config.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n });\n\n const stream = this.graphRunnable.streamEvents(inputs, config, {\n raiseError: true,\n /**\n * Prevent EventStreamCallbackHandler from processing custom events.\n * Custom events are already handled via our createCustomEventCallback()\n * which routes them through the handlerRegistry.\n * Without this flag, EventStreamCallbackHandler throws errors when\n * custom events are dispatched for run IDs not in its internal map\n * (due to timing issues in parallel execution or after run cleanup).\n */\n ignoreCustomEvent: true,\n });\n\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n\n const eventName: t.EventName = info.event;\n\n /** Skip custom events as they're handled by our callback */\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n }\n\n if (this.returnContent) {\n return this.Graph.getContentParts();\n }\n }\n\n private createSystemCallback<K extends keyof t.ClientCallbacks>(\n clientCallbacks: t.ClientCallbacks,\n key: K\n ): t.SystemCallbacks[K] {\n return ((...args: unknown[]) => {\n const clientCallback = clientCallbacks[key];\n if (clientCallback && this.Graph) {\n (clientCallback as (...args: unknown[]) => void)(this.Graph, ...args);\n }\n }) as t.SystemCallbacks[K];\n }\n\n getCallbacks(clientCallbacks: t.ClientCallbacks): t.SystemCallbacks {\n return {\n [Callback.TOOL_ERROR]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_ERROR\n ),\n [Callback.TOOL_START]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_START\n ),\n [Callback.TOOL_END]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_END\n ),\n };\n }\n\n async generateTitle({\n provider,\n inputText,\n contentParts,\n titlePrompt,\n clientOptions,\n chainOptions,\n skipLanguage,\n titleMethod = TitleMethod.COMPLETION,\n titlePromptTemplate,\n }: t.RunTitleOptions): Promise<{ language?: string; title?: string }> {\n if (\n chainOptions != null &&\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = chainOptions.configurable?.user_id;\n const sessionId = chainOptions.configurable?.thread_id;\n const traceMetadata = {\n messageId: 'title-' + this.id,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n chainOptions.callbacks = (\n (chainOptions.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n const convoTemplate = PromptTemplate.fromTemplate(\n titlePromptTemplate ?? 'User: {input}\\nAI: {output}'\n );\n\n const response = contentParts\n .map((part) => {\n if (part?.type === 'text') return part.text;\n return '';\n })\n .join('\\n');\n\n const model = this.Graph?.getNewModel({\n provider,\n clientOptions,\n });\n if (!model) {\n return { language: '', title: '' };\n }\n if (\n isOpenAILike(provider) &&\n (model instanceof ChatOpenAI || model instanceof AzureChatOpenAI)\n ) {\n model.temperature = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.temperature as number;\n model.topP = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.topP as number;\n model.frequencyPenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.frequencyPenalty as number;\n model.presencePenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.presencePenalty as number;\n model.n = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.n as number;\n }\n\n const convoToTitleInput = new RunnableLambda({\n func: (\n promptValue: StringPromptValue\n ): { convo: string; inputText: string; skipLanguage?: boolean } => ({\n convo: promptValue.value,\n inputText,\n skipLanguage,\n }),\n }).withConfig({ runName: 'ConvoTransform' });\n\n const titleChain =\n titleMethod === TitleMethod.COMPLETION\n ? await createCompletionTitleRunnable(model, titlePrompt)\n : await createTitleRunnable(model, titlePrompt);\n\n /** Pipes `convoTemplate` -> `transformer` -> `titleChain` */\n const fullChain = convoTemplate\n .withConfig({ runName: 'ConvoTemplate' })\n .pipe(convoToTitleInput)\n .pipe(titleChain)\n .withConfig({ runName: 'TitleChain' });\n\n const invokeConfig = Object.assign({}, chainOptions, {\n run_id: this.id,\n runId: this.id,\n });\n\n try {\n return await fullChain.invoke(\n { input: inputText, output: response },\n invokeConfig\n );\n } catch (_e) {\n // Fallback: strip callbacks to avoid EventStream tracer errors in certain environments\n // But preserve langfuse handler if it exists\n const langfuseHandler = (\n invokeConfig.callbacks as t.ProvidedCallbacks\n )?.find((cb) => cb instanceof CallbackHandler);\n const { callbacks: _cb, ...rest } = invokeConfig;\n const safeConfig = Object.assign({}, rest, {\n callbacks: langfuseHandler ? [langfuseHandler] : [],\n });\n return await fullChain.invoke(\n { input: inputText, output: response },\n safeConfig as Partial<RunnableConfig>\n );\n }\n }\n\n /**\n * Process stream with browser interrupt support.\n * Uses regular stream() instead of streamEvents() to properly detect interrupts.\n * Returns interrupt data when graph is paused waiting for browser action.\n */\n async *processBrowserStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n // Set up thread_id for checkpointing (required for interrupt/resume)\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id, // Use run ID as thread ID for browser sessions\n });\n\n // Use the values stream mode to detect interrupts\n const stream = await this.graphRunnable.stream(inputs, {\n ...config,\n streamMode: ['values', 'updates'],\n });\n\n for await (const chunk of stream) {\n // Check if this chunk contains an interrupt\n if (isInterrupted(chunk)) {\n const interrupts = chunk[INTERRUPT] as Array<{ value: BrowserInterrupt }>;\n if (interrupts.length > 0) {\n // Emit the interrupt data to the client\n for (const interrupt of interrupts) {\n if (interrupt.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interrupt.value };\n }\n }\n // Stop yielding - graph is paused\n return;\n }\n }\n\n // Emit regular events\n yield { type: 'event', data: chunk };\n }\n\n // Stream completed without interrupt\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n\n /**\n * Resume a browser stream after interrupt.\n * Call this with the result from the browser extension.\n */\n async *resumeBrowserStream(\n result: BrowserActionResult,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string }\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id,\n });\n\n // Use Command to resume with the browser result\n const resumeCommand = new Command({ resume: result });\n\n const stream = await this.graphRunnable.stream(resumeCommand, {\n ...config,\n streamMode: ['values', 'updates'],\n });\n\n for await (const chunk of stream) {\n // Check if this chunk contains another interrupt\n if (isInterrupted(chunk)) {\n const interrupts = chunk[INTERRUPT] as Array<{ value: BrowserInterrupt }>;\n if (interrupts.length > 0) {\n for (const interrupt of interrupts) {\n if (interrupt.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interrupt.value };\n }\n }\n return;\n }\n }\n\n yield { type: 'event', data: chunk };\n }\n\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n}\n"],"names":["MemorySaver","HandlerRegistry","StandardGraph","MultiAgentGraph","createTokenCounter","GraphEvents","Callback","isPresent","CallbackHandler","TitleMethod","PromptTemplate","isOpenAILike","ChatOpenAI","AzureChatOpenAI","RunnableLambda","createCompletionTitleRunnable","createTitleRunnable","isInterrupted","INTERRUPT","Command"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run.cjs","sources":["../../src/run.ts"],"sourcesContent":["// src/run.ts\nimport './instrumentation';\nimport { CallbackHandler } from '@langfuse/langchain';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport { RunnableLambda } from '@langchain/core/runnables';\nimport { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';\nimport { MemorySaver } from '@langchain/langgraph-checkpoint';\nimport { Command } from '@langchain/langgraph';\nimport type {\n MessageContentComplex,\n BaseMessage,\n} from '@langchain/core/messages';\nimport type { StringPromptValue } from '@langchain/core/prompt_values';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from '@/types';\nimport {\n createCompletionTitleRunnable,\n createTitleRunnable,\n} from '@/utils/title';\nimport { GraphEvents, Callback, TitleMethod } from '@/common';\nimport { MultiAgentGraph } from '@/graphs/MultiAgentGraph';\nimport { createTokenCounter } from '@/utils/tokens';\nimport { StandardGraph } from '@/graphs/Graph';\nimport { HandlerRegistry } from '@/events';\nimport { isOpenAILike } from '@/utils/llm';\nimport { isPresent } from '@/utils/misc';\nimport type { BrowserInterrupt, BrowserActionResult } from '@/tools/BrowserInterruptTools';\n\nexport const defaultOmitOptions = new Set([\n 'stream',\n 'thinking',\n 'streaming',\n 'maxTokens',\n 'clientOptions',\n 'thinkingConfig',\n 'thinkingBudget',\n 'includeThoughts',\n 'maxOutputTokens',\n 'additionalModelRequestFields',\n]);\n\n/** Global checkpointer store for browser mode (keyed by runId) */\nconst browserCheckpointers = new Map<string, MemorySaver>();\n\n/**\n * Get or create a checkpointer for browser mode\n */\nexport function getBrowserCheckpointer(runId: string): MemorySaver {\n let checkpointer = browserCheckpointers.get(runId);\n if (!checkpointer) {\n checkpointer = new MemorySaver();\n browserCheckpointers.set(runId, checkpointer);\n }\n return checkpointer;\n}\n\n/**\n * Clean up a browser checkpointer when done\n */\nexport function cleanupBrowserCheckpointer(runId: string): void {\n browserCheckpointers.delete(runId);\n}\n\nexport class Run<_T extends t.BaseGraphState> {\n id: string;\n private tokenCounter?: t.TokenCounter;\n private handlerRegistry?: HandlerRegistry;\n private indexTokenCountMap?: Record<string, number>;\n /** Whether this run is in browser extension mode */\n browserMode: boolean = false;\n graphRunnable?: t.CompiledStateWorkflow;\n Graph: StandardGraph | MultiAgentGraph | undefined;\n returnContent: boolean = false;\n\n private constructor(config: Partial<t.RunConfig>) {\n const runId = config.runId ?? '';\n if (!runId) {\n throw new Error('Run ID not provided');\n }\n\n this.id = runId;\n this.tokenCounter = config.tokenCounter;\n this.indexTokenCountMap = config.indexTokenCountMap;\n this.browserMode = config.browserMode ?? false;\n\n const handlerRegistry = new HandlerRegistry();\n\n if (config.customHandlers) {\n for (const [eventType, handler] of Object.entries(\n config.customHandlers\n )) {\n handlerRegistry.register(eventType, handler);\n }\n }\n\n this.handlerRegistry = handlerRegistry;\n\n if (!config.graphConfig) {\n throw new Error('Graph config not provided');\n }\n\n /** Handle different graph types */\n if (config.graphConfig.type === 'multi-agent') {\n // For multi-agent, browser mode checkpointer support not yet implemented\n this.graphRunnable = this.createMultiAgentGraph(config.graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n } else {\n /** Default to legacy graph for 'standard' or undefined type */\n // In browser mode, inject checkpointer into compileOptions BEFORE creating the graph\n const graphConfig = { ...config.graphConfig };\n if (this.browserMode) {\n const checkpointer = getBrowserCheckpointer(runId);\n graphConfig.compileOptions = {\n ...graphConfig.compileOptions,\n checkpointer,\n };\n }\n this.graphRunnable = this.createLegacyGraph(graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n }\n\n this.returnContent = config.returnContent ?? false;\n }\n\n private createLegacyGraph(\n config: t.LegacyGraphConfig | t.StandardGraphConfig\n ): t.CompiledStateWorkflow {\n let agentConfig: t.AgentInputs;\n let signal: AbortSignal | undefined;\n\n /** Check if this is a multi-agent style config (has agents array) */\n if ('agents' in config && Array.isArray(config.agents)) {\n if (config.agents.length === 0) {\n throw new Error('At least one agent must be provided');\n }\n agentConfig = config.agents[0];\n signal = config.signal;\n } else {\n /** Legacy path: build agent config from llmConfig */\n const {\n type: _type,\n llmConfig,\n signal: legacySignal,\n tools = [],\n ...agentInputs\n } = config as t.LegacyGraphConfig;\n const { provider, ...clientOptions } = llmConfig;\n\n agentConfig = {\n ...agentInputs,\n tools,\n provider,\n clientOptions,\n agentId: 'default',\n };\n signal = legacySignal;\n }\n\n const standardGraph = new StandardGraph({\n signal,\n runId: this.id,\n agents: [agentConfig],\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n /** Propagate compile options from graph config */\n standardGraph.compileOptions = config.compileOptions;\n this.Graph = standardGraph;\n return standardGraph.createWorkflow();\n }\n\n private createMultiAgentGraph(\n config: t.MultiAgentGraphConfig\n ): t.CompiledStateWorkflow {\n const { agents, edges, compileOptions } = config;\n\n const multiAgentGraph = new MultiAgentGraph({\n runId: this.id,\n agents,\n edges,\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n\n if (compileOptions != null) {\n multiAgentGraph.compileOptions = compileOptions;\n }\n\n this.Graph = multiAgentGraph;\n return multiAgentGraph.createWorkflow();\n }\n\n static async create<T extends t.BaseGraphState>(\n config: t.RunConfig\n ): Promise<Run<T>> {\n /** Create tokenCounter if indexTokenCountMap is provided but tokenCounter is not */\n if (config.indexTokenCountMap && !config.tokenCounter) {\n config.tokenCounter = await createTokenCounter();\n }\n return new Run<T>(config);\n }\n\n getRunMessages(): BaseMessage[] | undefined {\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n return this.Graph.getRunMessages();\n }\n\n /**\n * Creates a custom event callback handler that intercepts custom events\n * and processes them through our handler registry instead of EventStreamCallbackHandler\n */\n private createCustomEventCallback() {\n return async (\n eventName: string,\n data: unknown,\n runId: string,\n tags?: string[],\n metadata?: Record<string, unknown>\n ): Promise<void> => {\n if (\n (data as t.StreamEventData)['emitted'] === true &&\n eventName === GraphEvents.CHAT_MODEL_STREAM\n ) {\n return;\n }\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler && this.Graph) {\n return await handler.handle(\n eventName,\n data as\n | t.StreamEventData\n | t.ModelEndData\n | t.RunStep\n | t.RunStepDeltaEvent\n | t.MessageDeltaEvent\n | t.ReasoningDeltaEvent\n | { result: t.ToolEndEvent },\n metadata,\n this.Graph\n );\n }\n };\n }\n\n async processStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): Promise<MessageContentComplex[] | undefined> {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n /** Custom event callback to intercept and handle custom events */\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n if (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = config.configurable?.user_id;\n const sessionId = config.configurable?.thread_id;\n const traceMetadata = {\n messageId: this.id,\n parentMessageId: config.configurable?.requestBody?.parentMessageId,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n config.callbacks = (\n (config.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n });\n\n const stream = this.graphRunnable.streamEvents(inputs, config, {\n raiseError: true,\n /**\n * Prevent EventStreamCallbackHandler from processing custom events.\n * Custom events are already handled via our createCustomEventCallback()\n * which routes them through the handlerRegistry.\n * Without this flag, EventStreamCallbackHandler throws errors when\n * custom events are dispatched for run IDs not in its internal map\n * (due to timing issues in parallel execution or after run cleanup).\n */\n ignoreCustomEvent: true,\n });\n\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n\n const eventName: t.EventName = info.event;\n\n /** Skip custom events as they're handled by our callback */\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n }\n\n if (this.returnContent) {\n return this.Graph.getContentParts();\n }\n }\n\n private createSystemCallback<K extends keyof t.ClientCallbacks>(\n clientCallbacks: t.ClientCallbacks,\n key: K\n ): t.SystemCallbacks[K] {\n return ((...args: unknown[]) => {\n const clientCallback = clientCallbacks[key];\n if (clientCallback && this.Graph) {\n (clientCallback as (...args: unknown[]) => void)(this.Graph, ...args);\n }\n }) as t.SystemCallbacks[K];\n }\n\n getCallbacks(clientCallbacks: t.ClientCallbacks): t.SystemCallbacks {\n return {\n [Callback.TOOL_ERROR]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_ERROR\n ),\n [Callback.TOOL_START]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_START\n ),\n [Callback.TOOL_END]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_END\n ),\n };\n }\n\n async generateTitle({\n provider,\n inputText,\n contentParts,\n titlePrompt,\n clientOptions,\n chainOptions,\n skipLanguage,\n titleMethod = TitleMethod.COMPLETION,\n titlePromptTemplate,\n }: t.RunTitleOptions): Promise<{ language?: string; title?: string }> {\n if (\n chainOptions != null &&\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = chainOptions.configurable?.user_id;\n const sessionId = chainOptions.configurable?.thread_id;\n const traceMetadata = {\n messageId: 'title-' + this.id,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n chainOptions.callbacks = (\n (chainOptions.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n const convoTemplate = PromptTemplate.fromTemplate(\n titlePromptTemplate ?? 'User: {input}\\nAI: {output}'\n );\n\n const response = contentParts\n .map((part) => {\n if (part?.type === 'text') return part.text;\n return '';\n })\n .join('\\n');\n\n const model = this.Graph?.getNewModel({\n provider,\n clientOptions,\n });\n if (!model) {\n return { language: '', title: '' };\n }\n if (\n isOpenAILike(provider) &&\n (model instanceof ChatOpenAI || model instanceof AzureChatOpenAI)\n ) {\n model.temperature = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.temperature as number;\n model.topP = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.topP as number;\n model.frequencyPenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.frequencyPenalty as number;\n model.presencePenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.presencePenalty as number;\n model.n = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.n as number;\n }\n\n const convoToTitleInput = new RunnableLambda({\n func: (\n promptValue: StringPromptValue\n ): { convo: string; inputText: string; skipLanguage?: boolean } => ({\n convo: promptValue.value,\n inputText,\n skipLanguage,\n }),\n }).withConfig({ runName: 'ConvoTransform' });\n\n const titleChain =\n titleMethod === TitleMethod.COMPLETION\n ? await createCompletionTitleRunnable(model, titlePrompt)\n : await createTitleRunnable(model, titlePrompt);\n\n /** Pipes `convoTemplate` -> `transformer` -> `titleChain` */\n const fullChain = convoTemplate\n .withConfig({ runName: 'ConvoTemplate' })\n .pipe(convoToTitleInput)\n .pipe(titleChain)\n .withConfig({ runName: 'TitleChain' });\n\n const invokeConfig = Object.assign({}, chainOptions, {\n run_id: this.id,\n runId: this.id,\n });\n\n try {\n return await fullChain.invoke(\n { input: inputText, output: response },\n invokeConfig\n );\n } catch (_e) {\n // Fallback: strip callbacks to avoid EventStream tracer errors in certain environments\n // But preserve langfuse handler if it exists\n const langfuseHandler = (\n invokeConfig.callbacks as t.ProvidedCallbacks\n )?.find((cb) => cb instanceof CallbackHandler);\n const { callbacks: _cb, ...rest } = invokeConfig;\n const safeConfig = Object.assign({}, rest, {\n callbacks: langfuseHandler ? [langfuseHandler] : [],\n });\n return await fullChain.invoke(\n { input: inputText, output: response },\n safeConfig as Partial<RunnableConfig>\n );\n }\n }\n\n /**\n * Process stream with browser interrupt support.\n * Uses streamEvents() like processStream to emit SSE events,\n * then checks for interrupts after stream completes.\n */\n async *processBrowserStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n // Set up thread_id for checkpointing (required for interrupt/resume)\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id, // Use run ID as thread ID for browser sessions\n });\n\n // Set up callbacks for SSE event emission (same as processStream)\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n // Use streamEvents like processStream to emit proper SSE events\n const stream = this.graphRunnable.streamEvents(inputs, config, {\n raiseError: true,\n ignoreCustomEvent: true,\n });\n\n let wasInterrupted = false;\n\n try {\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n const eventName: t.EventName = info.event;\n\n // Skip custom events as they're handled by our callback\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n\n // Also yield the event for the caller to process\n yield { type: 'event', data: event };\n }\n } catch (error) {\n // streamEvents may throw when interrupt happens\n // Check if this is an interrupt-related termination\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes('interrupt') || errorMessage.includes('GraphInterrupt')) {\n wasInterrupted = true;\n } else {\n throw error;\n }\n }\n\n // After stream completes, check for pending interrupts using getState\n // The checkpointer stores the interrupt state\n try {\n const state = await this.graphRunnable.getState(config);\n if (state?.tasks) {\n for (const task of state.tasks) {\n if (task.interrupts && task.interrupts.length > 0) {\n for (const interruptInfo of task.interrupts) {\n if (interruptInfo.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interruptInfo.value as BrowserInterrupt };\n return; // Stop after yielding interrupt\n }\n }\n }\n }\n }\n } catch (stateError) {\n // getState may fail if no checkpointer - that's ok for non-browser flows\n console.debug('[processBrowserStream] Could not get state:', stateError);\n }\n\n // Stream completed without interrupt\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n\n /**\n * Resume a browser stream after interrupt.\n * Call this with the result from the browser extension.\n * Uses streamEvents() to emit proper SSE events during resume.\n */\n async *resumeBrowserStream(\n result: BrowserActionResult,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id,\n });\n\n // Set up callbacks for SSE event emission (same as processStream)\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n // Use Command to resume with the browser result\n const resumeCommand = new Command({ resume: result });\n\n // Use streamEvents for proper SSE event emission\n const stream = this.graphRunnable.streamEvents(resumeCommand, config, {\n raiseError: true,\n ignoreCustomEvent: true,\n });\n\n try {\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n const eventName: t.EventName = info.event;\n\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n\n yield { type: 'event', data: event };\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (!errorMessage.includes('interrupt') && !errorMessage.includes('GraphInterrupt')) {\n throw error;\n }\n }\n\n // Check for additional interrupts after resume\n try {\n const state = await this.graphRunnable.getState(config);\n if (state?.tasks) {\n for (const task of state.tasks) {\n if (task.interrupts && task.interrupts.length > 0) {\n for (const interruptInfo of task.interrupts) {\n if (interruptInfo.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interruptInfo.value as BrowserInterrupt };\n return;\n }\n }\n }\n }\n }\n } catch (stateError) {\n console.debug('[resumeBrowserStream] Could not get state:', stateError);\n }\n\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n}\n"],"names":["MemorySaver","HandlerRegistry","StandardGraph","MultiAgentGraph","createTokenCounter","GraphEvents","Callback","isPresent","CallbackHandler","TitleMethod","PromptTemplate","isOpenAILike","ChatOpenAI","AzureChatOpenAI","RunnableLambda","createCompletionTitleRunnable","createTitleRunnable","Command"],"mappings":"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"}
|
package/dist/esm/run.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { PromptTemplate } from '@langchain/core/prompts';
|
|
|
4
4
|
import { RunnableLambda } from '@langchain/core/runnables';
|
|
5
5
|
import { ChatOpenAI as ChatOpenAI$1, AzureChatOpenAI as AzureChatOpenAI$1 } from '@langchain/openai';
|
|
6
6
|
import { MemorySaver } from '@langchain/langgraph-checkpoint';
|
|
7
|
-
import {
|
|
7
|
+
import { Command } from '@langchain/langgraph';
|
|
8
8
|
import { createCompletionTitleRunnable, createTitleRunnable } from './utils/title.mjs';
|
|
9
9
|
import { GraphEvents, Callback, TitleMethod } from './common/enum.mjs';
|
|
10
10
|
import { MultiAgentGraph } from './graphs/MultiAgentGraph.mjs';
|
|
@@ -343,8 +343,8 @@ class Run {
|
|
|
343
343
|
}
|
|
344
344
|
/**
|
|
345
345
|
* Process stream with browser interrupt support.
|
|
346
|
-
* Uses
|
|
347
|
-
*
|
|
346
|
+
* Uses streamEvents() like processStream to emit SSE events,
|
|
347
|
+
* then checks for interrupts after stream completes.
|
|
348
348
|
*/
|
|
349
349
|
async *processBrowserStream(inputs, config, streamOptions) {
|
|
350
350
|
if (this.graphRunnable == null) {
|
|
@@ -363,28 +363,65 @@ class Run {
|
|
|
363
363
|
run_id: this.id,
|
|
364
364
|
thread_id: this.id, // Use run ID as thread ID for browser sessions
|
|
365
365
|
});
|
|
366
|
-
//
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
366
|
+
// Set up callbacks for SSE event emission (same as processStream)
|
|
367
|
+
const customEventCallback = this.createCustomEventCallback();
|
|
368
|
+
const baseCallbacks = config.callbacks ?? [];
|
|
369
|
+
const streamCallbacks = streamOptions?.callbacks
|
|
370
|
+
? this.getCallbacks(streamOptions.callbacks)
|
|
371
|
+
: [];
|
|
372
|
+
config.callbacks = baseCallbacks.concat(streamCallbacks).concat({
|
|
373
|
+
[Callback.CUSTOM_EVENT]: customEventCallback,
|
|
374
|
+
});
|
|
375
|
+
// Use streamEvents like processStream to emit proper SSE events
|
|
376
|
+
const stream = this.graphRunnable.streamEvents(inputs, config, {
|
|
377
|
+
raiseError: true,
|
|
378
|
+
ignoreCustomEvent: true,
|
|
370
379
|
});
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
+
try {
|
|
381
|
+
for await (const event of stream) {
|
|
382
|
+
const { data, metadata, ...info } = event;
|
|
383
|
+
const eventName = info.event;
|
|
384
|
+
// Skip custom events as they're handled by our callback
|
|
385
|
+
if (eventName === GraphEvents.ON_CUSTOM_EVENT) {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
const handler = this.handlerRegistry?.getHandler(eventName);
|
|
389
|
+
if (handler) {
|
|
390
|
+
await handler.handle(eventName, data, metadata, this.Graph);
|
|
391
|
+
}
|
|
392
|
+
// Also yield the event for the caller to process
|
|
393
|
+
yield { type: 'event', data: event };
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
// streamEvents may throw when interrupt happens
|
|
398
|
+
// Check if this is an interrupt-related termination
|
|
399
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
400
|
+
if (errorMessage.includes('interrupt') || errorMessage.includes('GraphInterrupt')) ;
|
|
401
|
+
else {
|
|
402
|
+
throw error;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// After stream completes, check for pending interrupts using getState
|
|
406
|
+
// The checkpointer stores the interrupt state
|
|
407
|
+
try {
|
|
408
|
+
const state = await this.graphRunnable.getState(config);
|
|
409
|
+
if (state?.tasks) {
|
|
410
|
+
for (const task of state.tasks) {
|
|
411
|
+
if (task.interrupts && task.interrupts.length > 0) {
|
|
412
|
+
for (const interruptInfo of task.interrupts) {
|
|
413
|
+
if (interruptInfo.value?.type === 'browser_interrupt') {
|
|
414
|
+
yield { type: 'interrupt', data: interruptInfo.value };
|
|
415
|
+
return; // Stop after yielding interrupt
|
|
416
|
+
}
|
|
380
417
|
}
|
|
381
418
|
}
|
|
382
|
-
// Stop yielding - graph is paused
|
|
383
|
-
return;
|
|
384
419
|
}
|
|
385
420
|
}
|
|
386
|
-
|
|
387
|
-
|
|
421
|
+
}
|
|
422
|
+
catch (stateError) {
|
|
423
|
+
// getState may fail if no checkpointer - that's ok for non-browser flows
|
|
424
|
+
console.debug('[processBrowserStream] Could not get state:', stateError);
|
|
388
425
|
}
|
|
389
426
|
// Stream completed without interrupt
|
|
390
427
|
if (this.returnContent) {
|
|
@@ -397,8 +434,9 @@ class Run {
|
|
|
397
434
|
/**
|
|
398
435
|
* Resume a browser stream after interrupt.
|
|
399
436
|
* Call this with the result from the browser extension.
|
|
437
|
+
* Uses streamEvents() to emit proper SSE events during resume.
|
|
400
438
|
*/
|
|
401
|
-
async *resumeBrowserStream(result, config) {
|
|
439
|
+
async *resumeBrowserStream(result, config, streamOptions) {
|
|
402
440
|
if (this.graphRunnable == null) {
|
|
403
441
|
throw new Error('Run not initialized. Make sure to use Run.create() to instantiate the Run.');
|
|
404
442
|
}
|
|
@@ -413,26 +451,60 @@ class Run {
|
|
|
413
451
|
run_id: this.id,
|
|
414
452
|
thread_id: this.id,
|
|
415
453
|
});
|
|
454
|
+
// Set up callbacks for SSE event emission (same as processStream)
|
|
455
|
+
const customEventCallback = this.createCustomEventCallback();
|
|
456
|
+
const baseCallbacks = config.callbacks ?? [];
|
|
457
|
+
const streamCallbacks = streamOptions?.callbacks
|
|
458
|
+
? this.getCallbacks(streamOptions.callbacks)
|
|
459
|
+
: [];
|
|
460
|
+
config.callbacks = baseCallbacks.concat(streamCallbacks).concat({
|
|
461
|
+
[Callback.CUSTOM_EVENT]: customEventCallback,
|
|
462
|
+
});
|
|
416
463
|
// Use Command to resume with the browser result
|
|
417
464
|
const resumeCommand = new Command({ resume: result });
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
465
|
+
// Use streamEvents for proper SSE event emission
|
|
466
|
+
const stream = this.graphRunnable.streamEvents(resumeCommand, config, {
|
|
467
|
+
raiseError: true,
|
|
468
|
+
ignoreCustomEvent: true,
|
|
421
469
|
});
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
if (
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
470
|
+
try {
|
|
471
|
+
for await (const event of stream) {
|
|
472
|
+
const { data, metadata, ...info } = event;
|
|
473
|
+
const eventName = info.event;
|
|
474
|
+
if (eventName === GraphEvents.ON_CUSTOM_EVENT) {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
const handler = this.handlerRegistry?.getHandler(eventName);
|
|
478
|
+
if (handler) {
|
|
479
|
+
await handler.handle(eventName, data, metadata, this.Graph);
|
|
480
|
+
}
|
|
481
|
+
yield { type: 'event', data: event };
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
486
|
+
if (!errorMessage.includes('interrupt') && !errorMessage.includes('GraphInterrupt')) {
|
|
487
|
+
throw error;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// Check for additional interrupts after resume
|
|
491
|
+
try {
|
|
492
|
+
const state = await this.graphRunnable.getState(config);
|
|
493
|
+
if (state?.tasks) {
|
|
494
|
+
for (const task of state.tasks) {
|
|
495
|
+
if (task.interrupts && task.interrupts.length > 0) {
|
|
496
|
+
for (const interruptInfo of task.interrupts) {
|
|
497
|
+
if (interruptInfo.value?.type === 'browser_interrupt') {
|
|
498
|
+
yield { type: 'interrupt', data: interruptInfo.value };
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
430
501
|
}
|
|
431
502
|
}
|
|
432
|
-
return;
|
|
433
503
|
}
|
|
434
504
|
}
|
|
435
|
-
|
|
505
|
+
}
|
|
506
|
+
catch (stateError) {
|
|
507
|
+
console.debug('[resumeBrowserStream] Could not get state:', stateError);
|
|
436
508
|
}
|
|
437
509
|
if (this.returnContent) {
|
|
438
510
|
yield { type: 'done', data: this.Graph.getContentParts() };
|
package/dist/esm/run.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.mjs","sources":["../../src/run.ts"],"sourcesContent":["// src/run.ts\nimport './instrumentation';\nimport { CallbackHandler } from '@langfuse/langchain';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport { RunnableLambda } from '@langchain/core/runnables';\nimport { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';\nimport { MemorySaver } from '@langchain/langgraph-checkpoint';\nimport { Command, INTERRUPT, isInterrupted } from '@langchain/langgraph';\nimport type {\n MessageContentComplex,\n BaseMessage,\n} from '@langchain/core/messages';\nimport type { StringPromptValue } from '@langchain/core/prompt_values';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from '@/types';\nimport {\n createCompletionTitleRunnable,\n createTitleRunnable,\n} from '@/utils/title';\nimport { GraphEvents, Callback, TitleMethod } from '@/common';\nimport { MultiAgentGraph } from '@/graphs/MultiAgentGraph';\nimport { createTokenCounter } from '@/utils/tokens';\nimport { StandardGraph } from '@/graphs/Graph';\nimport { HandlerRegistry } from '@/events';\nimport { isOpenAILike } from '@/utils/llm';\nimport { isPresent } from '@/utils/misc';\nimport type { BrowserInterrupt, BrowserActionResult } from '@/tools/BrowserInterruptTools';\n\nexport const defaultOmitOptions = new Set([\n 'stream',\n 'thinking',\n 'streaming',\n 'maxTokens',\n 'clientOptions',\n 'thinkingConfig',\n 'thinkingBudget',\n 'includeThoughts',\n 'maxOutputTokens',\n 'additionalModelRequestFields',\n]);\n\n/** Global checkpointer store for browser mode (keyed by runId) */\nconst browserCheckpointers = new Map<string, MemorySaver>();\n\n/**\n * Get or create a checkpointer for browser mode\n */\nexport function getBrowserCheckpointer(runId: string): MemorySaver {\n let checkpointer = browserCheckpointers.get(runId);\n if (!checkpointer) {\n checkpointer = new MemorySaver();\n browserCheckpointers.set(runId, checkpointer);\n }\n return checkpointer;\n}\n\n/**\n * Clean up a browser checkpointer when done\n */\nexport function cleanupBrowserCheckpointer(runId: string): void {\n browserCheckpointers.delete(runId);\n}\n\nexport class Run<_T extends t.BaseGraphState> {\n id: string;\n private tokenCounter?: t.TokenCounter;\n private handlerRegistry?: HandlerRegistry;\n private indexTokenCountMap?: Record<string, number>;\n /** Whether this run is in browser extension mode */\n browserMode: boolean = false;\n graphRunnable?: t.CompiledStateWorkflow;\n Graph: StandardGraph | MultiAgentGraph | undefined;\n returnContent: boolean = false;\n\n private constructor(config: Partial<t.RunConfig>) {\n const runId = config.runId ?? '';\n if (!runId) {\n throw new Error('Run ID not provided');\n }\n\n this.id = runId;\n this.tokenCounter = config.tokenCounter;\n this.indexTokenCountMap = config.indexTokenCountMap;\n this.browserMode = config.browserMode ?? false;\n\n const handlerRegistry = new HandlerRegistry();\n\n if (config.customHandlers) {\n for (const [eventType, handler] of Object.entries(\n config.customHandlers\n )) {\n handlerRegistry.register(eventType, handler);\n }\n }\n\n this.handlerRegistry = handlerRegistry;\n\n if (!config.graphConfig) {\n throw new Error('Graph config not provided');\n }\n\n /** Handle different graph types */\n if (config.graphConfig.type === 'multi-agent') {\n // For multi-agent, browser mode checkpointer support not yet implemented\n this.graphRunnable = this.createMultiAgentGraph(config.graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n } else {\n /** Default to legacy graph for 'standard' or undefined type */\n // In browser mode, inject checkpointer into compileOptions BEFORE creating the graph\n const graphConfig = { ...config.graphConfig };\n if (this.browserMode) {\n const checkpointer = getBrowserCheckpointer(runId);\n graphConfig.compileOptions = {\n ...graphConfig.compileOptions,\n checkpointer,\n };\n }\n this.graphRunnable = this.createLegacyGraph(graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n }\n\n this.returnContent = config.returnContent ?? false;\n }\n\n private createLegacyGraph(\n config: t.LegacyGraphConfig | t.StandardGraphConfig\n ): t.CompiledStateWorkflow {\n let agentConfig: t.AgentInputs;\n let signal: AbortSignal | undefined;\n\n /** Check if this is a multi-agent style config (has agents array) */\n if ('agents' in config && Array.isArray(config.agents)) {\n if (config.agents.length === 0) {\n throw new Error('At least one agent must be provided');\n }\n agentConfig = config.agents[0];\n signal = config.signal;\n } else {\n /** Legacy path: build agent config from llmConfig */\n const {\n type: _type,\n llmConfig,\n signal: legacySignal,\n tools = [],\n ...agentInputs\n } = config as t.LegacyGraphConfig;\n const { provider, ...clientOptions } = llmConfig;\n\n agentConfig = {\n ...agentInputs,\n tools,\n provider,\n clientOptions,\n agentId: 'default',\n };\n signal = legacySignal;\n }\n\n const standardGraph = new StandardGraph({\n signal,\n runId: this.id,\n agents: [agentConfig],\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n /** Propagate compile options from graph config */\n standardGraph.compileOptions = config.compileOptions;\n this.Graph = standardGraph;\n return standardGraph.createWorkflow();\n }\n\n private createMultiAgentGraph(\n config: t.MultiAgentGraphConfig\n ): t.CompiledStateWorkflow {\n const { agents, edges, compileOptions } = config;\n\n const multiAgentGraph = new MultiAgentGraph({\n runId: this.id,\n agents,\n edges,\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n\n if (compileOptions != null) {\n multiAgentGraph.compileOptions = compileOptions;\n }\n\n this.Graph = multiAgentGraph;\n return multiAgentGraph.createWorkflow();\n }\n\n static async create<T extends t.BaseGraphState>(\n config: t.RunConfig\n ): Promise<Run<T>> {\n /** Create tokenCounter if indexTokenCountMap is provided but tokenCounter is not */\n if (config.indexTokenCountMap && !config.tokenCounter) {\n config.tokenCounter = await createTokenCounter();\n }\n return new Run<T>(config);\n }\n\n getRunMessages(): BaseMessage[] | undefined {\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n return this.Graph.getRunMessages();\n }\n\n /**\n * Creates a custom event callback handler that intercepts custom events\n * and processes them through our handler registry instead of EventStreamCallbackHandler\n */\n private createCustomEventCallback() {\n return async (\n eventName: string,\n data: unknown,\n runId: string,\n tags?: string[],\n metadata?: Record<string, unknown>\n ): Promise<void> => {\n if (\n (data as t.StreamEventData)['emitted'] === true &&\n eventName === GraphEvents.CHAT_MODEL_STREAM\n ) {\n return;\n }\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler && this.Graph) {\n return await handler.handle(\n eventName,\n data as\n | t.StreamEventData\n | t.ModelEndData\n | t.RunStep\n | t.RunStepDeltaEvent\n | t.MessageDeltaEvent\n | t.ReasoningDeltaEvent\n | { result: t.ToolEndEvent },\n metadata,\n this.Graph\n );\n }\n };\n }\n\n async processStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): Promise<MessageContentComplex[] | undefined> {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n /** Custom event callback to intercept and handle custom events */\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n if (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = config.configurable?.user_id;\n const sessionId = config.configurable?.thread_id;\n const traceMetadata = {\n messageId: this.id,\n parentMessageId: config.configurable?.requestBody?.parentMessageId,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n config.callbacks = (\n (config.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n });\n\n const stream = this.graphRunnable.streamEvents(inputs, config, {\n raiseError: true,\n /**\n * Prevent EventStreamCallbackHandler from processing custom events.\n * Custom events are already handled via our createCustomEventCallback()\n * which routes them through the handlerRegistry.\n * Without this flag, EventStreamCallbackHandler throws errors when\n * custom events are dispatched for run IDs not in its internal map\n * (due to timing issues in parallel execution or after run cleanup).\n */\n ignoreCustomEvent: true,\n });\n\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n\n const eventName: t.EventName = info.event;\n\n /** Skip custom events as they're handled by our callback */\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n }\n\n if (this.returnContent) {\n return this.Graph.getContentParts();\n }\n }\n\n private createSystemCallback<K extends keyof t.ClientCallbacks>(\n clientCallbacks: t.ClientCallbacks,\n key: K\n ): t.SystemCallbacks[K] {\n return ((...args: unknown[]) => {\n const clientCallback = clientCallbacks[key];\n if (clientCallback && this.Graph) {\n (clientCallback as (...args: unknown[]) => void)(this.Graph, ...args);\n }\n }) as t.SystemCallbacks[K];\n }\n\n getCallbacks(clientCallbacks: t.ClientCallbacks): t.SystemCallbacks {\n return {\n [Callback.TOOL_ERROR]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_ERROR\n ),\n [Callback.TOOL_START]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_START\n ),\n [Callback.TOOL_END]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_END\n ),\n };\n }\n\n async generateTitle({\n provider,\n inputText,\n contentParts,\n titlePrompt,\n clientOptions,\n chainOptions,\n skipLanguage,\n titleMethod = TitleMethod.COMPLETION,\n titlePromptTemplate,\n }: t.RunTitleOptions): Promise<{ language?: string; title?: string }> {\n if (\n chainOptions != null &&\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = chainOptions.configurable?.user_id;\n const sessionId = chainOptions.configurable?.thread_id;\n const traceMetadata = {\n messageId: 'title-' + this.id,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n chainOptions.callbacks = (\n (chainOptions.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n const convoTemplate = PromptTemplate.fromTemplate(\n titlePromptTemplate ?? 'User: {input}\\nAI: {output}'\n );\n\n const response = contentParts\n .map((part) => {\n if (part?.type === 'text') return part.text;\n return '';\n })\n .join('\\n');\n\n const model = this.Graph?.getNewModel({\n provider,\n clientOptions,\n });\n if (!model) {\n return { language: '', title: '' };\n }\n if (\n isOpenAILike(provider) &&\n (model instanceof ChatOpenAI || model instanceof AzureChatOpenAI)\n ) {\n model.temperature = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.temperature as number;\n model.topP = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.topP as number;\n model.frequencyPenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.frequencyPenalty as number;\n model.presencePenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.presencePenalty as number;\n model.n = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.n as number;\n }\n\n const convoToTitleInput = new RunnableLambda({\n func: (\n promptValue: StringPromptValue\n ): { convo: string; inputText: string; skipLanguage?: boolean } => ({\n convo: promptValue.value,\n inputText,\n skipLanguage,\n }),\n }).withConfig({ runName: 'ConvoTransform' });\n\n const titleChain =\n titleMethod === TitleMethod.COMPLETION\n ? await createCompletionTitleRunnable(model, titlePrompt)\n : await createTitleRunnable(model, titlePrompt);\n\n /** Pipes `convoTemplate` -> `transformer` -> `titleChain` */\n const fullChain = convoTemplate\n .withConfig({ runName: 'ConvoTemplate' })\n .pipe(convoToTitleInput)\n .pipe(titleChain)\n .withConfig({ runName: 'TitleChain' });\n\n const invokeConfig = Object.assign({}, chainOptions, {\n run_id: this.id,\n runId: this.id,\n });\n\n try {\n return await fullChain.invoke(\n { input: inputText, output: response },\n invokeConfig\n );\n } catch (_e) {\n // Fallback: strip callbacks to avoid EventStream tracer errors in certain environments\n // But preserve langfuse handler if it exists\n const langfuseHandler = (\n invokeConfig.callbacks as t.ProvidedCallbacks\n )?.find((cb) => cb instanceof CallbackHandler);\n const { callbacks: _cb, ...rest } = invokeConfig;\n const safeConfig = Object.assign({}, rest, {\n callbacks: langfuseHandler ? [langfuseHandler] : [],\n });\n return await fullChain.invoke(\n { input: inputText, output: response },\n safeConfig as Partial<RunnableConfig>\n );\n }\n }\n\n /**\n * Process stream with browser interrupt support.\n * Uses regular stream() instead of streamEvents() to properly detect interrupts.\n * Returns interrupt data when graph is paused waiting for browser action.\n */\n async *processBrowserStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n // Set up thread_id for checkpointing (required for interrupt/resume)\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id, // Use run ID as thread ID for browser sessions\n });\n\n // Use the values stream mode to detect interrupts\n const stream = await this.graphRunnable.stream(inputs, {\n ...config,\n streamMode: ['values', 'updates'],\n });\n\n for await (const chunk of stream) {\n // Check if this chunk contains an interrupt\n if (isInterrupted(chunk)) {\n const interrupts = chunk[INTERRUPT] as Array<{ value: BrowserInterrupt }>;\n if (interrupts.length > 0) {\n // Emit the interrupt data to the client\n for (const interrupt of interrupts) {\n if (interrupt.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interrupt.value };\n }\n }\n // Stop yielding - graph is paused\n return;\n }\n }\n\n // Emit regular events\n yield { type: 'event', data: chunk };\n }\n\n // Stream completed without interrupt\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n\n /**\n * Resume a browser stream after interrupt.\n * Call this with the result from the browser extension.\n */\n async *resumeBrowserStream(\n result: BrowserActionResult,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string }\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id,\n });\n\n // Use Command to resume with the browser result\n const resumeCommand = new Command({ resume: result });\n\n const stream = await this.graphRunnable.stream(resumeCommand, {\n ...config,\n streamMode: ['values', 'updates'],\n });\n\n for await (const chunk of stream) {\n // Check if this chunk contains another interrupt\n if (isInterrupted(chunk)) {\n const interrupts = chunk[INTERRUPT] as Array<{ value: BrowserInterrupt }>;\n if (interrupts.length > 0) {\n for (const interrupt of interrupts) {\n if (interrupt.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interrupt.value };\n }\n }\n return;\n }\n }\n\n yield { type: 'event', data: chunk };\n }\n\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n}\n"],"names":["ChatOpenAI","AzureChatOpenAI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run.mjs","sources":["../../src/run.ts"],"sourcesContent":["// src/run.ts\nimport './instrumentation';\nimport { CallbackHandler } from '@langfuse/langchain';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport { RunnableLambda } from '@langchain/core/runnables';\nimport { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';\nimport { MemorySaver } from '@langchain/langgraph-checkpoint';\nimport { Command } from '@langchain/langgraph';\nimport type {\n MessageContentComplex,\n BaseMessage,\n} from '@langchain/core/messages';\nimport type { StringPromptValue } from '@langchain/core/prompt_values';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from '@/types';\nimport {\n createCompletionTitleRunnable,\n createTitleRunnable,\n} from '@/utils/title';\nimport { GraphEvents, Callback, TitleMethod } from '@/common';\nimport { MultiAgentGraph } from '@/graphs/MultiAgentGraph';\nimport { createTokenCounter } from '@/utils/tokens';\nimport { StandardGraph } from '@/graphs/Graph';\nimport { HandlerRegistry } from '@/events';\nimport { isOpenAILike } from '@/utils/llm';\nimport { isPresent } from '@/utils/misc';\nimport type { BrowserInterrupt, BrowserActionResult } from '@/tools/BrowserInterruptTools';\n\nexport const defaultOmitOptions = new Set([\n 'stream',\n 'thinking',\n 'streaming',\n 'maxTokens',\n 'clientOptions',\n 'thinkingConfig',\n 'thinkingBudget',\n 'includeThoughts',\n 'maxOutputTokens',\n 'additionalModelRequestFields',\n]);\n\n/** Global checkpointer store for browser mode (keyed by runId) */\nconst browserCheckpointers = new Map<string, MemorySaver>();\n\n/**\n * Get or create a checkpointer for browser mode\n */\nexport function getBrowserCheckpointer(runId: string): MemorySaver {\n let checkpointer = browserCheckpointers.get(runId);\n if (!checkpointer) {\n checkpointer = new MemorySaver();\n browserCheckpointers.set(runId, checkpointer);\n }\n return checkpointer;\n}\n\n/**\n * Clean up a browser checkpointer when done\n */\nexport function cleanupBrowserCheckpointer(runId: string): void {\n browserCheckpointers.delete(runId);\n}\n\nexport class Run<_T extends t.BaseGraphState> {\n id: string;\n private tokenCounter?: t.TokenCounter;\n private handlerRegistry?: HandlerRegistry;\n private indexTokenCountMap?: Record<string, number>;\n /** Whether this run is in browser extension mode */\n browserMode: boolean = false;\n graphRunnable?: t.CompiledStateWorkflow;\n Graph: StandardGraph | MultiAgentGraph | undefined;\n returnContent: boolean = false;\n\n private constructor(config: Partial<t.RunConfig>) {\n const runId = config.runId ?? '';\n if (!runId) {\n throw new Error('Run ID not provided');\n }\n\n this.id = runId;\n this.tokenCounter = config.tokenCounter;\n this.indexTokenCountMap = config.indexTokenCountMap;\n this.browserMode = config.browserMode ?? false;\n\n const handlerRegistry = new HandlerRegistry();\n\n if (config.customHandlers) {\n for (const [eventType, handler] of Object.entries(\n config.customHandlers\n )) {\n handlerRegistry.register(eventType, handler);\n }\n }\n\n this.handlerRegistry = handlerRegistry;\n\n if (!config.graphConfig) {\n throw new Error('Graph config not provided');\n }\n\n /** Handle different graph types */\n if (config.graphConfig.type === 'multi-agent') {\n // For multi-agent, browser mode checkpointer support not yet implemented\n this.graphRunnable = this.createMultiAgentGraph(config.graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n } else {\n /** Default to legacy graph for 'standard' or undefined type */\n // In browser mode, inject checkpointer into compileOptions BEFORE creating the graph\n const graphConfig = { ...config.graphConfig };\n if (this.browserMode) {\n const checkpointer = getBrowserCheckpointer(runId);\n graphConfig.compileOptions = {\n ...graphConfig.compileOptions,\n checkpointer,\n };\n }\n this.graphRunnable = this.createLegacyGraph(graphConfig);\n if (this.Graph) {\n this.Graph.handlerRegistry = handlerRegistry;\n }\n }\n\n this.returnContent = config.returnContent ?? false;\n }\n\n private createLegacyGraph(\n config: t.LegacyGraphConfig | t.StandardGraphConfig\n ): t.CompiledStateWorkflow {\n let agentConfig: t.AgentInputs;\n let signal: AbortSignal | undefined;\n\n /** Check if this is a multi-agent style config (has agents array) */\n if ('agents' in config && Array.isArray(config.agents)) {\n if (config.agents.length === 0) {\n throw new Error('At least one agent must be provided');\n }\n agentConfig = config.agents[0];\n signal = config.signal;\n } else {\n /** Legacy path: build agent config from llmConfig */\n const {\n type: _type,\n llmConfig,\n signal: legacySignal,\n tools = [],\n ...agentInputs\n } = config as t.LegacyGraphConfig;\n const { provider, ...clientOptions } = llmConfig;\n\n agentConfig = {\n ...agentInputs,\n tools,\n provider,\n clientOptions,\n agentId: 'default',\n };\n signal = legacySignal;\n }\n\n const standardGraph = new StandardGraph({\n signal,\n runId: this.id,\n agents: [agentConfig],\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n /** Propagate compile options from graph config */\n standardGraph.compileOptions = config.compileOptions;\n this.Graph = standardGraph;\n return standardGraph.createWorkflow();\n }\n\n private createMultiAgentGraph(\n config: t.MultiAgentGraphConfig\n ): t.CompiledStateWorkflow {\n const { agents, edges, compileOptions } = config;\n\n const multiAgentGraph = new MultiAgentGraph({\n runId: this.id,\n agents,\n edges,\n tokenCounter: this.tokenCounter,\n indexTokenCountMap: this.indexTokenCountMap,\n });\n\n if (compileOptions != null) {\n multiAgentGraph.compileOptions = compileOptions;\n }\n\n this.Graph = multiAgentGraph;\n return multiAgentGraph.createWorkflow();\n }\n\n static async create<T extends t.BaseGraphState>(\n config: t.RunConfig\n ): Promise<Run<T>> {\n /** Create tokenCounter if indexTokenCountMap is provided but tokenCounter is not */\n if (config.indexTokenCountMap && !config.tokenCounter) {\n config.tokenCounter = await createTokenCounter();\n }\n return new Run<T>(config);\n }\n\n getRunMessages(): BaseMessage[] | undefined {\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n return this.Graph.getRunMessages();\n }\n\n /**\n * Creates a custom event callback handler that intercepts custom events\n * and processes them through our handler registry instead of EventStreamCallbackHandler\n */\n private createCustomEventCallback() {\n return async (\n eventName: string,\n data: unknown,\n runId: string,\n tags?: string[],\n metadata?: Record<string, unknown>\n ): Promise<void> => {\n if (\n (data as t.StreamEventData)['emitted'] === true &&\n eventName === GraphEvents.CHAT_MODEL_STREAM\n ) {\n return;\n }\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler && this.Graph) {\n return await handler.handle(\n eventName,\n data as\n | t.StreamEventData\n | t.ModelEndData\n | t.RunStep\n | t.RunStepDeltaEvent\n | t.MessageDeltaEvent\n | t.ReasoningDeltaEvent\n | { result: t.ToolEndEvent },\n metadata,\n this.Graph\n );\n }\n };\n }\n\n async processStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): Promise<MessageContentComplex[] | undefined> {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n /** Custom event callback to intercept and handle custom events */\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n if (\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = config.configurable?.user_id;\n const sessionId = config.configurable?.thread_id;\n const traceMetadata = {\n messageId: this.id,\n parentMessageId: config.configurable?.requestBody?.parentMessageId,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n config.callbacks = (\n (config.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n });\n\n const stream = this.graphRunnable.streamEvents(inputs, config, {\n raiseError: true,\n /**\n * Prevent EventStreamCallbackHandler from processing custom events.\n * Custom events are already handled via our createCustomEventCallback()\n * which routes them through the handlerRegistry.\n * Without this flag, EventStreamCallbackHandler throws errors when\n * custom events are dispatched for run IDs not in its internal map\n * (due to timing issues in parallel execution or after run cleanup).\n */\n ignoreCustomEvent: true,\n });\n\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n\n const eventName: t.EventName = info.event;\n\n /** Skip custom events as they're handled by our callback */\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n }\n\n if (this.returnContent) {\n return this.Graph.getContentParts();\n }\n }\n\n private createSystemCallback<K extends keyof t.ClientCallbacks>(\n clientCallbacks: t.ClientCallbacks,\n key: K\n ): t.SystemCallbacks[K] {\n return ((...args: unknown[]) => {\n const clientCallback = clientCallbacks[key];\n if (clientCallback && this.Graph) {\n (clientCallback as (...args: unknown[]) => void)(this.Graph, ...args);\n }\n }) as t.SystemCallbacks[K];\n }\n\n getCallbacks(clientCallbacks: t.ClientCallbacks): t.SystemCallbacks {\n return {\n [Callback.TOOL_ERROR]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_ERROR\n ),\n [Callback.TOOL_START]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_START\n ),\n [Callback.TOOL_END]: this.createSystemCallback(\n clientCallbacks,\n Callback.TOOL_END\n ),\n };\n }\n\n async generateTitle({\n provider,\n inputText,\n contentParts,\n titlePrompt,\n clientOptions,\n chainOptions,\n skipLanguage,\n titleMethod = TitleMethod.COMPLETION,\n titlePromptTemplate,\n }: t.RunTitleOptions): Promise<{ language?: string; title?: string }> {\n if (\n chainOptions != null &&\n isPresent(process.env.LANGFUSE_SECRET_KEY) &&\n isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&\n isPresent(process.env.LANGFUSE_BASE_URL)\n ) {\n const userId = chainOptions.configurable?.user_id;\n const sessionId = chainOptions.configurable?.thread_id;\n const traceMetadata = {\n messageId: 'title-' + this.id,\n };\n const handler = new CallbackHandler({\n userId,\n sessionId,\n traceMetadata,\n });\n chainOptions.callbacks = (\n (chainOptions.callbacks as t.ProvidedCallbacks) ?? []\n ).concat([handler]);\n }\n\n const convoTemplate = PromptTemplate.fromTemplate(\n titlePromptTemplate ?? 'User: {input}\\nAI: {output}'\n );\n\n const response = contentParts\n .map((part) => {\n if (part?.type === 'text') return part.text;\n return '';\n })\n .join('\\n');\n\n const model = this.Graph?.getNewModel({\n provider,\n clientOptions,\n });\n if (!model) {\n return { language: '', title: '' };\n }\n if (\n isOpenAILike(provider) &&\n (model instanceof ChatOpenAI || model instanceof AzureChatOpenAI)\n ) {\n model.temperature = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.temperature as number;\n model.topP = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.topP as number;\n model.frequencyPenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.frequencyPenalty as number;\n model.presencePenalty = (\n clientOptions as t.OpenAIClientOptions | undefined\n )?.presencePenalty as number;\n model.n = (clientOptions as t.OpenAIClientOptions | undefined)\n ?.n as number;\n }\n\n const convoToTitleInput = new RunnableLambda({\n func: (\n promptValue: StringPromptValue\n ): { convo: string; inputText: string; skipLanguage?: boolean } => ({\n convo: promptValue.value,\n inputText,\n skipLanguage,\n }),\n }).withConfig({ runName: 'ConvoTransform' });\n\n const titleChain =\n titleMethod === TitleMethod.COMPLETION\n ? await createCompletionTitleRunnable(model, titlePrompt)\n : await createTitleRunnable(model, titlePrompt);\n\n /** Pipes `convoTemplate` -> `transformer` -> `titleChain` */\n const fullChain = convoTemplate\n .withConfig({ runName: 'ConvoTemplate' })\n .pipe(convoToTitleInput)\n .pipe(titleChain)\n .withConfig({ runName: 'TitleChain' });\n\n const invokeConfig = Object.assign({}, chainOptions, {\n run_id: this.id,\n runId: this.id,\n });\n\n try {\n return await fullChain.invoke(\n { input: inputText, output: response },\n invokeConfig\n );\n } catch (_e) {\n // Fallback: strip callbacks to avoid EventStream tracer errors in certain environments\n // But preserve langfuse handler if it exists\n const langfuseHandler = (\n invokeConfig.callbacks as t.ProvidedCallbacks\n )?.find((cb) => cb instanceof CallbackHandler);\n const { callbacks: _cb, ...rest } = invokeConfig;\n const safeConfig = Object.assign({}, rest, {\n callbacks: langfuseHandler ? [langfuseHandler] : [],\n });\n return await fullChain.invoke(\n { input: inputText, output: response },\n safeConfig as Partial<RunnableConfig>\n );\n }\n }\n\n /**\n * Process stream with browser interrupt support.\n * Uses streamEvents() like processStream to emit SSE events,\n * then checks for interrupts after stream completes.\n */\n async *processBrowserStream(\n inputs: t.IState,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n this.Graph.resetValues(streamOptions?.keepContent);\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n // Set up thread_id for checkpointing (required for interrupt/resume)\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id, // Use run ID as thread ID for browser sessions\n });\n\n // Set up callbacks for SSE event emission (same as processStream)\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n // Use streamEvents like processStream to emit proper SSE events\n const stream = this.graphRunnable.streamEvents(inputs, config, {\n raiseError: true,\n ignoreCustomEvent: true,\n });\n\n let wasInterrupted = false;\n\n try {\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n const eventName: t.EventName = info.event;\n\n // Skip custom events as they're handled by our callback\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n\n // Also yield the event for the caller to process\n yield { type: 'event', data: event };\n }\n } catch (error) {\n // streamEvents may throw when interrupt happens\n // Check if this is an interrupt-related termination\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes('interrupt') || errorMessage.includes('GraphInterrupt')) {\n wasInterrupted = true;\n } else {\n throw error;\n }\n }\n\n // After stream completes, check for pending interrupts using getState\n // The checkpointer stores the interrupt state\n try {\n const state = await this.graphRunnable.getState(config);\n if (state?.tasks) {\n for (const task of state.tasks) {\n if (task.interrupts && task.interrupts.length > 0) {\n for (const interruptInfo of task.interrupts) {\n if (interruptInfo.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interruptInfo.value as BrowserInterrupt };\n return; // Stop after yielding interrupt\n }\n }\n }\n }\n }\n } catch (stateError) {\n // getState may fail if no checkpointer - that's ok for non-browser flows\n console.debug('[processBrowserStream] Could not get state:', stateError);\n }\n\n // Stream completed without interrupt\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n\n /**\n * Resume a browser stream after interrupt.\n * Call this with the result from the browser extension.\n * Uses streamEvents() to emit proper SSE events during resume.\n */\n async *resumeBrowserStream(\n result: BrowserActionResult,\n config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },\n streamOptions?: t.EventStreamOptions\n ): AsyncGenerator<\n | { type: 'event'; data: unknown }\n | { type: 'interrupt'; data: BrowserInterrupt }\n | { type: 'done'; data?: MessageContentComplex[] }\n > {\n if (this.graphRunnable == null) {\n throw new Error(\n 'Run not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n if (!this.Graph) {\n throw new Error(\n 'Graph not initialized. Make sure to use Run.create() to instantiate the Run.'\n );\n }\n\n if (!this.id) {\n throw new Error('Run ID not provided');\n }\n\n config.run_id = this.id;\n config.configurable = Object.assign(config.configurable ?? {}, {\n run_id: this.id,\n thread_id: this.id,\n });\n\n // Set up callbacks for SSE event emission (same as processStream)\n const customEventCallback = this.createCustomEventCallback();\n\n const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];\n const streamCallbacks = streamOptions?.callbacks\n ? this.getCallbacks(streamOptions.callbacks)\n : [];\n\n config.callbacks = baseCallbacks.concat(streamCallbacks).concat({\n [Callback.CUSTOM_EVENT]: customEventCallback,\n });\n\n // Use Command to resume with the browser result\n const resumeCommand = new Command({ resume: result });\n\n // Use streamEvents for proper SSE event emission\n const stream = this.graphRunnable.streamEvents(resumeCommand, config, {\n raiseError: true,\n ignoreCustomEvent: true,\n });\n\n try {\n for await (const event of stream) {\n const { data, metadata, ...info } = event;\n const eventName: t.EventName = info.event;\n\n if (eventName === GraphEvents.ON_CUSTOM_EVENT) {\n continue;\n }\n\n const handler = this.handlerRegistry?.getHandler(eventName);\n if (handler) {\n await handler.handle(eventName, data, metadata, this.Graph);\n }\n\n yield { type: 'event', data: event };\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (!errorMessage.includes('interrupt') && !errorMessage.includes('GraphInterrupt')) {\n throw error;\n }\n }\n\n // Check for additional interrupts after resume\n try {\n const state = await this.graphRunnable.getState(config);\n if (state?.tasks) {\n for (const task of state.tasks) {\n if (task.interrupts && task.interrupts.length > 0) {\n for (const interruptInfo of task.interrupts) {\n if (interruptInfo.value?.type === 'browser_interrupt') {\n yield { type: 'interrupt', data: interruptInfo.value as BrowserInterrupt };\n return;\n }\n }\n }\n }\n }\n } catch (stateError) {\n console.debug('[resumeBrowserStream] Could not get state:', stateError);\n }\n\n if (this.returnContent) {\n yield { type: 'done', data: this.Graph.getContentParts() };\n } else {\n yield { type: 'done' };\n }\n }\n}\n"],"names":["ChatOpenAI","AzureChatOpenAI"],"mappings":";;;;;;;;;;;;;;;;AAAA;AA4Ba,MAAA,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACxC,QAAQ;IACR,UAAU;IACV,WAAW;IACX,WAAW;IACX,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,8BAA8B;AAC/B,CAAA;AAED;AACA,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAuB;AAE3D;;AAEG;AACG,SAAU,sBAAsB,CAAC,KAAa,EAAA;IAClD,IAAI,YAAY,GAAG,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC;IAClD,IAAI,CAAC,YAAY,EAAE;AACjB,QAAA,YAAY,GAAG,IAAI,WAAW,EAAE;AAChC,QAAA,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC;;AAE/C,IAAA,OAAO,YAAY;AACrB;AAEA;;AAEG;AACG,SAAU,0BAA0B,CAAC,KAAa,EAAA;AACtD,IAAA,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC;AACpC;MAEa,GAAG,CAAA;AACd,IAAA,EAAE;AACM,IAAA,YAAY;AACZ,IAAA,eAAe;AACf,IAAA,kBAAkB;;IAE1B,WAAW,GAAY,KAAK;AAC5B,IAAA,aAAa;AACb,IAAA,KAAK;IACL,aAAa,GAAY,KAAK;AAE9B,IAAA,WAAA,CAAoB,MAA4B,EAAA;AAC9C,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE;QAChC,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC;;AAGxC,QAAA,IAAI,CAAC,EAAE,GAAG,KAAK;AACf,QAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;AACvC,QAAA,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,kBAAkB;QACnD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,KAAK;AAE9C,QAAA,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE;AAE7C,QAAA,IAAI,MAAM,CAAC,cAAc,EAAE;AACzB,YAAA,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAC/C,MAAM,CAAC,cAAc,CACtB,EAAE;AACD,gBAAA,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;;;AAIhD,QAAA,IAAI,CAAC,eAAe,GAAG,eAAe;AAEtC,QAAA,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE;AACvB,YAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC;;;QAI9C,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,aAAa,EAAE;;YAE7C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,WAAW,CAAC;AACnE,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,gBAAA,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,eAAe;;;aAEzC;;;YAGL,MAAM,WAAW,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE;AAC7C,YAAA,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,gBAAA,MAAM,YAAY,GAAG,sBAAsB,CAAC,KAAK,CAAC;gBAClD,WAAW,CAAC,cAAc,GAAG;oBAC3B,GAAG,WAAW,CAAC,cAAc;oBAC7B,YAAY;iBACb;;YAEH,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC;AACxD,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,gBAAA,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,eAAe;;;QAIhD,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,KAAK;;AAG5C,IAAA,iBAAiB,CACvB,MAAmD,EAAA;AAEnD,QAAA,IAAI,WAA0B;AAC9B,QAAA,IAAI,MAA+B;;AAGnC,QAAA,IAAI,QAAQ,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACtD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;AAC9B,gBAAA,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC;;AAExD,YAAA,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,YAAA,MAAM,GAAG,MAAM,CAAC,MAAM;;aACjB;;YAEL,MAAM,EACJ,IAAI,EAAE,KAAK,EACX,SAAS,EACT,MAAM,EAAE,YAAY,EACpB,KAAK,GAAG,EAAE,EACV,GAAG,WAAW,EACf,GAAG,MAA6B;YACjC,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,GAAG,SAAS;AAEhD,YAAA,WAAW,GAAG;AACZ,gBAAA,GAAG,WAAW;gBACd,KAAK;gBACL,QAAQ;gBACR,aAAa;AACb,gBAAA,OAAO,EAAE,SAAS;aACnB;YACD,MAAM,GAAG,YAAY;;AAGvB,QAAA,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;YACtC,MAAM;YACN,KAAK,EAAE,IAAI,CAAC,EAAE;YACd,MAAM,EAAE,CAAC,WAAW,CAAC;YACrB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;AAC5C,SAAA,CAAC;;AAEF,QAAA,aAAa,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc;AACpD,QAAA,IAAI,CAAC,KAAK,GAAG,aAAa;AAC1B,QAAA,OAAO,aAAa,CAAC,cAAc,EAAE;;AAG/B,IAAA,qBAAqB,CAC3B,MAA+B,EAAA;QAE/B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM;AAEhD,QAAA,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE;YACd,MAAM;YACN,KAAK;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;AAC5C,SAAA,CAAC;AAEF,QAAA,IAAI,cAAc,IAAI,IAAI,EAAE;AAC1B,YAAA,eAAe,CAAC,cAAc,GAAG,cAAc;;AAGjD,QAAA,IAAI,CAAC,KAAK,GAAG,eAAe;AAC5B,QAAA,OAAO,eAAe,CAAC,cAAc,EAAE;;AAGzC,IAAA,aAAa,MAAM,CACjB,MAAmB,EAAA;;QAGnB,IAAI,MAAM,CAAC,kBAAkB,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;AACrD,YAAA,MAAM,CAAC,YAAY,GAAG,MAAM,kBAAkB,EAAE;;AAElD,QAAA,OAAO,IAAI,GAAG,CAAI,MAAM,CAAC;;IAG3B,cAAc,GAAA;AACZ,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E;;AAEH,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;;AAGpC;;;AAGG;IACK,yBAAyB,GAAA;AAC/B,QAAA,OAAO,OACL,SAAiB,EACjB,IAAa,EACb,KAAa,EACb,IAAe,EACf,QAAkC,KACjB;AACjB,YAAA,IACG,IAA0B,CAAC,SAAS,CAAC,KAAK,IAAI;AAC/C,gBAAA,SAAS,KAAK,WAAW,CAAC,iBAAiB,EAC3C;gBACA;;YAEF,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,SAAS,CAAC;AAC3D,YAAA,IAAI,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE;AACzB,gBAAA,OAAO,MAAM,OAAO,CAAC,MAAM,CACzB,SAAS,EACT,IAO8B,EAC9B,QAAQ,EACR,IAAI,CAAC,KAAK,CACX;;AAEL,SAAC;;AAGH,IAAA,MAAM,aAAa,CACjB,MAAgB,EAChB,MAA2E,EAC3E,aAAoC,EAAA;AAEpC,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE;AAC9B,YAAA,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E;;AAEH,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E;;QAGH,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,WAAW,CAAC;;AAGlD,QAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,yBAAyB,EAAE;AAE5D,QAAA,MAAM,aAAa,GAAI,MAAM,CAAC,SAAiC,IAAI,EAAE;AACrE,QAAA,MAAM,eAAe,GAAG,aAAa,EAAE;cACnC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS;cACzC,EAAE;QAEN,MAAM,CAAC,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;AAC9D,YAAA,CAAC,QAAQ,CAAC,YAAY,GAAG,mBAAmB;AAC7C,SAAA,CAAC;AAEF,QAAA,IACE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,YAAA,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC1C,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EACxC;AACA,YAAA,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,OAAO;AAC3C,YAAA,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,SAAS;AAChD,YAAA,MAAM,aAAa,GAAG;gBACpB,SAAS,EAAE,IAAI,CAAC,EAAE;AAClB,gBAAA,eAAe,EAAE,MAAM,CAAC,YAAY,EAAE,WAAW,EAAE,eAAe;aACnE;AACD,YAAA,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC;gBAClC,MAAM;gBACN,SAAS;gBACT,aAAa;AACd,aAAA,CAAC;AACF,YAAA,MAAM,CAAC,SAAS,GAAG,CAChB,MAAM,CAAC,SAAiC,IAAI,EAAE,EAC/C,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;;AAGrB,QAAA,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;AACZ,YAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC;;AAGxC,QAAA,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;AACvB,QAAA,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE;YAC7D,MAAM,EAAE,IAAI,CAAC,EAAE;AAChB,SAAA,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE;AAC7D,YAAA,UAAU,EAAE,IAAI;AAChB;;;;;;;AAOG;AACH,YAAA,iBAAiB,EAAE,IAAI;AACxB,SAAA,CAAC;AAEF,QAAA,WAAW,MAAM,KAAK,IAAI,MAAM,EAAE;YAChC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK;AAEzC,YAAA,MAAM,SAAS,GAAgB,IAAI,CAAC,KAAK;;AAGzC,YAAA,IAAI,SAAS,KAAK,WAAW,CAAC,eAAe,EAAE;gBAC7C;;YAGF,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,SAAS,CAAC;YAC3D,IAAI,OAAO,EAAE;AACX,gBAAA,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC;;;AAI/D,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;;;IAI/B,oBAAoB,CAC1B,eAAkC,EAClC,GAAM,EAAA;AAEN,QAAA,QAAQ,CAAC,GAAG,IAAe,KAAI;AAC7B,YAAA,MAAM,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC;AAC3C,YAAA,IAAI,cAAc,IAAI,IAAI,CAAC,KAAK,EAAE;gBAC/B,cAA+C,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC;;AAEzE,SAAC;;AAGH,IAAA,YAAY,CAAC,eAAkC,EAAA;QAC7C,OAAO;AACL,YAAA,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAC9C,eAAe,EACf,QAAQ,CAAC,UAAU,CACpB;AACD,YAAA,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAC9C,eAAe,EACf,QAAQ,CAAC,UAAU,CACpB;AACD,YAAA,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAC5C,eAAe,EACf,QAAQ,CAAC,QAAQ,CAClB;SACF;;IAGH,MAAM,aAAa,CAAC,EAClB,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,GAAG,WAAW,CAAC,UAAU,EACpC,mBAAmB,GACD,EAAA;QAClB,IACE,YAAY,IAAI,IAAI;AACpB,YAAA,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,YAAA,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC1C,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EACxC;AACA,YAAA,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO;AACjD,YAAA,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,EAAE,SAAS;AACtD,YAAA,MAAM,aAAa,GAAG;AACpB,gBAAA,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC,EAAE;aAC9B;AACD,YAAA,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC;gBAClC,MAAM;gBACN,SAAS;gBACT,aAAa;AACd,aAAA,CAAC;AACF,YAAA,YAAY,CAAC,SAAS,GAAG,CACtB,YAAY,CAAC,SAAiC,IAAI,EAAE,EACrD,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;;QAGrB,MAAM,aAAa,GAAG,cAAc,CAAC,YAAY,CAC/C,mBAAmB,IAAI,6BAA6B,CACrD;QAED,MAAM,QAAQ,GAAG;AACd,aAAA,GAAG,CAAC,CAAC,IAAI,KAAI;AACZ,YAAA,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC,IAAI;AAC3C,YAAA,OAAO,EAAE;AACX,SAAC;aACA,IAAI,CAAC,IAAI,CAAC;AAEb,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC;YACpC,QAAQ;YACR,aAAa;AACd,SAAA,CAAC;QACF,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;;QAEpC,IACE,YAAY,CAAC,QAAQ,CAAC;aACrB,KAAK,YAAYA,YAAU,IAAI,KAAK,YAAYC,iBAAe,CAAC,EACjE;YACA,KAAK,CAAC,WAAW,GAAI;AACnB,kBAAE,WAAqB;YACzB,KAAK,CAAC,IAAI,GAAI;AACZ,kBAAE,IAAc;AAClB,YAAA,KAAK,CAAC,gBAAgB,GACpB,aACD,EAAE,gBAA0B;AAC7B,YAAA,KAAK,CAAC,eAAe,GACnB,aACD,EAAE,eAAyB;YAC5B,KAAK,CAAC,CAAC,GAAI;AACT,kBAAE,CAAW;;AAGjB,QAAA,MAAM,iBAAiB,GAAG,IAAI,cAAc,CAAC;AAC3C,YAAA,IAAI,EAAE,CACJ,WAA8B,MACoC;gBAClE,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,SAAS;gBACT,YAAY;aACb,CAAC;SACH,CAAC,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5C,QAAA,MAAM,UAAU,GACd,WAAW,KAAK,WAAW,CAAC;AAC1B,cAAE,MAAM,6BAA6B,CAAC,KAAK,EAAE,WAAW;cACtD,MAAM,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC;;QAGnD,MAAM,SAAS,GAAG;AACf,aAAA,UAAU,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE;aACvC,IAAI,CAAC,iBAAiB;aACtB,IAAI,CAAC,UAAU;AACf,aAAA,UAAU,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAExC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,YAAY,EAAE;YACnD,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,KAAK,EAAE,IAAI,CAAC,EAAE;AACf,SAAA,CAAC;AAEF,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,SAAS,CAAC,MAAM,CAC3B,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EACtC,YAAY,CACb;;QACD,OAAO,EAAE,EAAE;;;AAGX,YAAA,MAAM,eAAe,GACnB,YAAY,CAAC,SACd,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,eAAe,CAAC;YAC9C,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,YAAY;YAChD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE;gBACzC,SAAS,EAAE,eAAe,GAAG,CAAC,eAAe,CAAC,GAAG,EAAE;AACpD,aAAA,CAAC;AACF,YAAA,OAAO,MAAM,SAAS,CAAC,MAAM,CAC3B,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EACtC,UAAqC,CACtC;;;AAIL;;;;AAIG;IACH,OAAO,oBAAoB,CACzB,MAAgB,EAChB,MAA2E,EAC3E,aAAoC,EAAA;AAMpC,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE;AAC9B,YAAA,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E;;AAEH,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E;;QAGH,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,WAAW,CAAC;AAElD,QAAA,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;AACZ,YAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC;;AAGxC,QAAA,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;;AAEvB,QAAA,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE;YAC7D,MAAM,EAAE,IAAI,CAAC,EAAE;AACf,YAAA,SAAS,EAAE,IAAI,CAAC,EAAE;AACnB,SAAA,CAAC;;AAGF,QAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,yBAAyB,EAAE;AAE5D,QAAA,MAAM,aAAa,GAAI,MAAM,CAAC,SAAiC,IAAI,EAAE;AACrE,QAAA,MAAM,eAAe,GAAG,aAAa,EAAE;cACnC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS;cACzC,EAAE;QAEN,MAAM,CAAC,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;AAC9D,YAAA,CAAC,QAAQ,CAAC,YAAY,GAAG,mBAAmB;AAC7C,SAAA,CAAC;;QAGF,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE;AAC7D,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,iBAAiB,EAAE,IAAI;AACxB,SAAA,CAAC;AAIF,QAAA,IAAI;AACF,YAAA,WAAW,MAAM,KAAK,IAAI,MAAM,EAAE;gBAChC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK;AACzC,gBAAA,MAAM,SAAS,GAAgB,IAAI,CAAC,KAAK;;AAGzC,gBAAA,IAAI,SAAS,KAAK,WAAW,CAAC,eAAe,EAAE;oBAC7C;;gBAGF,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,SAAS,CAAC;gBAC3D,IAAI,OAAO,EAAE;AACX,oBAAA,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC;;;gBAI7D,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;;;QAEtC,OAAO,KAAK,EAAE;;;AAGd,YAAA,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;AAC3E,YAAA,IAAI,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;iBAE5E;AACL,gBAAA,MAAM,KAAK;;;;;AAMf,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC;AACvD,YAAA,IAAI,KAAK,EAAE,KAAK,EAAE;AAChB,gBAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;AAC9B,oBAAA,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;AACjD,wBAAA,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,UAAU,EAAE;4BAC3C,IAAI,aAAa,CAAC,KAAK,EAAE,IAAI,KAAK,mBAAmB,EAAE;gCACrD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,CAAC,KAAyB,EAAE;AAC1E,gCAAA,OAAO;;;;;;;QAMjB,OAAO,UAAU,EAAE;;AAEnB,YAAA,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,UAAU,CAAC;;;AAI1E,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE;;aACrD;AACL,YAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;;;AAI1B;;;;AAIG;IACH,OAAO,mBAAmB,CACxB,MAA2B,EAC3B,MAA2E,EAC3E,aAAoC,EAAA;AAMpC,QAAA,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE;AAC9B,YAAA,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E;;AAEH,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E;;AAGH,QAAA,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;AACZ,YAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC;;AAGxC,QAAA,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;AACvB,QAAA,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE;YAC7D,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,SAAS,EAAE,IAAI,CAAC,EAAE;AACnB,SAAA,CAAC;;AAGF,QAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,yBAAyB,EAAE;AAE5D,QAAA,MAAM,aAAa,GAAI,MAAM,CAAC,SAAiC,IAAI,EAAE;AACrE,QAAA,MAAM,eAAe,GAAG,aAAa,EAAE;cACnC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS;cACzC,EAAE;QAEN,MAAM,CAAC,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;AAC9D,YAAA,CAAC,QAAQ,CAAC,YAAY,GAAG,mBAAmB;AAC7C,SAAA,CAAC;;QAGF,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;;QAGrD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE;AACpE,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,iBAAiB,EAAE,IAAI;AACxB,SAAA,CAAC;AAEF,QAAA,IAAI;AACF,YAAA,WAAW,MAAM,KAAK,IAAI,MAAM,EAAE;gBAChC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK;AACzC,gBAAA,MAAM,SAAS,GAAgB,IAAI,CAAC,KAAK;AAEzC,gBAAA,IAAI,SAAS,KAAK,WAAW,CAAC,eAAe,EAAE;oBAC7C;;gBAGF,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,SAAS,CAAC;gBAC3D,IAAI,OAAO,EAAE;AACX,oBAAA,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC;;gBAG7D,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;;;QAEtC,OAAO,KAAK,EAAE;AACd,YAAA,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;AAC3E,YAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;AACnF,gBAAA,MAAM,KAAK;;;;AAKf,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC;AACvD,YAAA,IAAI,KAAK,EAAE,KAAK,EAAE;AAChB,gBAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;AAC9B,oBAAA,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;AACjD,wBAAA,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,UAAU,EAAE;4BAC3C,IAAI,aAAa,CAAC,KAAK,EAAE,IAAI,KAAK,mBAAmB,EAAE;gCACrD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,CAAC,KAAyB,EAAE;gCAC1E;;;;;;;QAMV,OAAO,UAAU,EAAE;AACnB,YAAA,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,UAAU,CAAC;;AAGzE,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE;;aACrD;AACL,YAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;;;AAG3B;;;;"}
|
package/dist/types/run.d.ts
CHANGED
|
@@ -47,8 +47,8 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
47
47
|
}>;
|
|
48
48
|
/**
|
|
49
49
|
* Process stream with browser interrupt support.
|
|
50
|
-
* Uses
|
|
51
|
-
*
|
|
50
|
+
* Uses streamEvents() like processStream to emit SSE events,
|
|
51
|
+
* then checks for interrupts after stream completes.
|
|
52
52
|
*/
|
|
53
53
|
processBrowserStream(inputs: t.IState, config: Partial<RunnableConfig> & {
|
|
54
54
|
version: 'v1' | 'v2';
|
|
@@ -66,11 +66,12 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
66
66
|
/**
|
|
67
67
|
* Resume a browser stream after interrupt.
|
|
68
68
|
* Call this with the result from the browser extension.
|
|
69
|
+
* Uses streamEvents() to emit proper SSE events during resume.
|
|
69
70
|
*/
|
|
70
71
|
resumeBrowserStream(result: BrowserActionResult, config: Partial<RunnableConfig> & {
|
|
71
72
|
version: 'v1' | 'v2';
|
|
72
73
|
run_id?: string;
|
|
73
|
-
}): AsyncGenerator<{
|
|
74
|
+
}, streamOptions?: t.EventStreamOptions): AsyncGenerator<{
|
|
74
75
|
type: 'event';
|
|
75
76
|
data: unknown;
|
|
76
77
|
} | {
|
package/package.json
CHANGED
package/src/run.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { PromptTemplate } from '@langchain/core/prompts';
|
|
|
5
5
|
import { RunnableLambda } from '@langchain/core/runnables';
|
|
6
6
|
import { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';
|
|
7
7
|
import { MemorySaver } from '@langchain/langgraph-checkpoint';
|
|
8
|
-
import { Command
|
|
8
|
+
import { Command } from '@langchain/langgraph';
|
|
9
9
|
import type {
|
|
10
10
|
MessageContentComplex,
|
|
11
11
|
BaseMessage,
|
|
@@ -492,8 +492,8 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
492
492
|
|
|
493
493
|
/**
|
|
494
494
|
* Process stream with browser interrupt support.
|
|
495
|
-
* Uses
|
|
496
|
-
*
|
|
495
|
+
* Uses streamEvents() like processStream to emit SSE events,
|
|
496
|
+
* then checks for interrupts after stream completes.
|
|
497
497
|
*/
|
|
498
498
|
async *processBrowserStream(
|
|
499
499
|
inputs: t.IState,
|
|
@@ -528,30 +528,74 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
528
528
|
thread_id: this.id, // Use run ID as thread ID for browser sessions
|
|
529
529
|
});
|
|
530
530
|
|
|
531
|
-
//
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
531
|
+
// Set up callbacks for SSE event emission (same as processStream)
|
|
532
|
+
const customEventCallback = this.createCustomEventCallback();
|
|
533
|
+
|
|
534
|
+
const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];
|
|
535
|
+
const streamCallbacks = streamOptions?.callbacks
|
|
536
|
+
? this.getCallbacks(streamOptions.callbacks)
|
|
537
|
+
: [];
|
|
538
|
+
|
|
539
|
+
config.callbacks = baseCallbacks.concat(streamCallbacks).concat({
|
|
540
|
+
[Callback.CUSTOM_EVENT]: customEventCallback,
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
// Use streamEvents like processStream to emit proper SSE events
|
|
544
|
+
const stream = this.graphRunnable.streamEvents(inputs, config, {
|
|
545
|
+
raiseError: true,
|
|
546
|
+
ignoreCustomEvent: true,
|
|
535
547
|
});
|
|
536
548
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
549
|
+
let wasInterrupted = false;
|
|
550
|
+
|
|
551
|
+
try {
|
|
552
|
+
for await (const event of stream) {
|
|
553
|
+
const { data, metadata, ...info } = event;
|
|
554
|
+
const eventName: t.EventName = info.event;
|
|
555
|
+
|
|
556
|
+
// Skip custom events as they're handled by our callback
|
|
557
|
+
if (eventName === GraphEvents.ON_CUSTOM_EVENT) {
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const handler = this.handlerRegistry?.getHandler(eventName);
|
|
562
|
+
if (handler) {
|
|
563
|
+
await handler.handle(eventName, data, metadata, this.Graph);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// Also yield the event for the caller to process
|
|
567
|
+
yield { type: 'event', data: event };
|
|
568
|
+
}
|
|
569
|
+
} catch (error) {
|
|
570
|
+
// streamEvents may throw when interrupt happens
|
|
571
|
+
// Check if this is an interrupt-related termination
|
|
572
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
573
|
+
if (errorMessage.includes('interrupt') || errorMessage.includes('GraphInterrupt')) {
|
|
574
|
+
wasInterrupted = true;
|
|
575
|
+
} else {
|
|
576
|
+
throw error;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// After stream completes, check for pending interrupts using getState
|
|
581
|
+
// The checkpointer stores the interrupt state
|
|
582
|
+
try {
|
|
583
|
+
const state = await this.graphRunnable.getState(config);
|
|
584
|
+
if (state?.tasks) {
|
|
585
|
+
for (const task of state.tasks) {
|
|
586
|
+
if (task.interrupts && task.interrupts.length > 0) {
|
|
587
|
+
for (const interruptInfo of task.interrupts) {
|
|
588
|
+
if (interruptInfo.value?.type === 'browser_interrupt') {
|
|
589
|
+
yield { type: 'interrupt', data: interruptInfo.value as BrowserInterrupt };
|
|
590
|
+
return; // Stop after yielding interrupt
|
|
591
|
+
}
|
|
546
592
|
}
|
|
547
593
|
}
|
|
548
|
-
// Stop yielding - graph is paused
|
|
549
|
-
return;
|
|
550
594
|
}
|
|
551
595
|
}
|
|
552
|
-
|
|
553
|
-
//
|
|
554
|
-
|
|
596
|
+
} catch (stateError) {
|
|
597
|
+
// getState may fail if no checkpointer - that's ok for non-browser flows
|
|
598
|
+
console.debug('[processBrowserStream] Could not get state:', stateError);
|
|
555
599
|
}
|
|
556
600
|
|
|
557
601
|
// Stream completed without interrupt
|
|
@@ -565,10 +609,12 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
565
609
|
/**
|
|
566
610
|
* Resume a browser stream after interrupt.
|
|
567
611
|
* Call this with the result from the browser extension.
|
|
612
|
+
* Uses streamEvents() to emit proper SSE events during resume.
|
|
568
613
|
*/
|
|
569
614
|
async *resumeBrowserStream(
|
|
570
615
|
result: BrowserActionResult,
|
|
571
|
-
config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string }
|
|
616
|
+
config: Partial<RunnableConfig> & { version: 'v1' | 'v2'; run_id?: string },
|
|
617
|
+
streamOptions?: t.EventStreamOptions
|
|
572
618
|
): AsyncGenerator<
|
|
573
619
|
| { type: 'event'; data: unknown }
|
|
574
620
|
| { type: 'interrupt'; data: BrowserInterrupt }
|
|
@@ -595,29 +641,67 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
595
641
|
thread_id: this.id,
|
|
596
642
|
});
|
|
597
643
|
|
|
644
|
+
// Set up callbacks for SSE event emission (same as processStream)
|
|
645
|
+
const customEventCallback = this.createCustomEventCallback();
|
|
646
|
+
|
|
647
|
+
const baseCallbacks = (config.callbacks as t.ProvidedCallbacks) ?? [];
|
|
648
|
+
const streamCallbacks = streamOptions?.callbacks
|
|
649
|
+
? this.getCallbacks(streamOptions.callbacks)
|
|
650
|
+
: [];
|
|
651
|
+
|
|
652
|
+
config.callbacks = baseCallbacks.concat(streamCallbacks).concat({
|
|
653
|
+
[Callback.CUSTOM_EVENT]: customEventCallback,
|
|
654
|
+
});
|
|
655
|
+
|
|
598
656
|
// Use Command to resume with the browser result
|
|
599
657
|
const resumeCommand = new Command({ resume: result });
|
|
600
658
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
659
|
+
// Use streamEvents for proper SSE event emission
|
|
660
|
+
const stream = this.graphRunnable.streamEvents(resumeCommand, config, {
|
|
661
|
+
raiseError: true,
|
|
662
|
+
ignoreCustomEvent: true,
|
|
604
663
|
});
|
|
605
664
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
665
|
+
try {
|
|
666
|
+
for await (const event of stream) {
|
|
667
|
+
const { data, metadata, ...info } = event;
|
|
668
|
+
const eventName: t.EventName = info.event;
|
|
669
|
+
|
|
670
|
+
if (eventName === GraphEvents.ON_CUSTOM_EVENT) {
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
const handler = this.handlerRegistry?.getHandler(eventName);
|
|
675
|
+
if (handler) {
|
|
676
|
+
await handler.handle(eventName, data, metadata, this.Graph);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
yield { type: 'event', data: event };
|
|
680
|
+
}
|
|
681
|
+
} catch (error) {
|
|
682
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
683
|
+
if (!errorMessage.includes('interrupt') && !errorMessage.includes('GraphInterrupt')) {
|
|
684
|
+
throw error;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Check for additional interrupts after resume
|
|
689
|
+
try {
|
|
690
|
+
const state = await this.graphRunnable.getState(config);
|
|
691
|
+
if (state?.tasks) {
|
|
692
|
+
for (const task of state.tasks) {
|
|
693
|
+
if (task.interrupts && task.interrupts.length > 0) {
|
|
694
|
+
for (const interruptInfo of task.interrupts) {
|
|
695
|
+
if (interruptInfo.value?.type === 'browser_interrupt') {
|
|
696
|
+
yield { type: 'interrupt', data: interruptInfo.value as BrowserInterrupt };
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
614
699
|
}
|
|
615
700
|
}
|
|
616
|
-
return;
|
|
617
701
|
}
|
|
618
702
|
}
|
|
619
|
-
|
|
620
|
-
|
|
703
|
+
} catch (stateError) {
|
|
704
|
+
console.debug('[resumeBrowserStream] Could not get state:', stateError);
|
|
621
705
|
}
|
|
622
706
|
|
|
623
707
|
if (this.returnContent) {
|