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 CHANGED
@@ -345,8 +345,8 @@ class Run {
345
345
  }
346
346
  /**
347
347
  * Process stream with browser interrupt support.
348
- * Uses regular stream() instead of streamEvents() to properly detect interrupts.
349
- * Returns interrupt data when graph is paused waiting for browser action.
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
- // Use the values stream mode to detect interrupts
369
- const stream = await this.graphRunnable.stream(inputs, {
370
- ...config,
371
- streamMode: ['values', 'updates'],
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
- for await (const chunk of stream) {
374
- // Check if this chunk contains an interrupt
375
- if (langgraph.isInterrupted(chunk)) {
376
- const interrupts = chunk[langgraph.INTERRUPT];
377
- if (interrupts.length > 0) {
378
- // Emit the interrupt data to the client
379
- for (const interrupt of interrupts) {
380
- if (interrupt.value?.type === 'browser_interrupt') {
381
- yield { type: 'interrupt', data: interrupt.value };
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
- // Emit regular events
389
- yield { type: 'event', data: chunk };
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
- const stream = await this.graphRunnable.stream(resumeCommand, {
421
- ...config,
422
- streamMode: ['values', 'updates'],
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
- for await (const chunk of stream) {
425
- // Check if this chunk contains another interrupt
426
- if (langgraph.isInterrupted(chunk)) {
427
- const interrupts = chunk[langgraph.INTERRUPT];
428
- if (interrupts.length > 0) {
429
- for (const interrupt of interrupts) {
430
- if (interrupt.value?.type === 'browser_interrupt') {
431
- yield { type: 'interrupt', data: interrupt.value };
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
- yield { type: 'event', data: chunk };
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() };
@@ -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":";;;;;;;;;;;;;;;;;;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,IAAIA,+BAAW,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,IAAIC,sBAAe,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,IAAIC,mBAAa,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,IAAIC,+BAAe,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,MAAMC,yBAAkB,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,KAAKC,iBAAW,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,CAACC,cAAQ,CAAC,YAAY,GAAG,mBAAmB;AAC7C,SAAA,CAAC;AAEF,QAAA,IACEC,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,YAAAA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC1CA,cAAS,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,IAAIC,yBAAe,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,KAAKH,iBAAW,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,CAACC,cAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAC9C,eAAe,EACfA,cAAQ,CAAC,UAAU,CACpB;AACD,YAAA,CAACA,cAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAC9C,eAAe,EACfA,cAAQ,CAAC,UAAU,CACpB;AACD,YAAA,CAACA,cAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAC5C,eAAe,EACfA,cAAQ,CAAC,QAAQ,CAClB;SACF;;IAGH,MAAM,aAAa,CAAC,EAClB,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,GAAGG,iBAAW,CAAC,UAAU,EACpC,mBAAmB,GACD,EAAA;QAClB,IACE,YAAY,IAAI,IAAI;AACpB,YAAAF,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC1C,YAAAA,cAAS,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC1CA,cAAS,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,IAAIC,yBAAe,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,GAAGE,sBAAc,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,IACEC,gBAAY,CAAC,QAAQ,CAAC;aACrB,KAAK,YAAYC,iBAAU,IAAI,KAAK,YAAYC,sBAAe,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,IAAIC,wBAAc,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,KAAKL,iBAAW,CAAC;AAC1B,cAAE,MAAMM,mCAA6B,CAAC,KAAK,EAAE,WAAW;cACtD,MAAMC,yBAAmB,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,YAAYR,yBAAe,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;;QAGF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;AACrD,YAAA,GAAG,MAAM;AACT,YAAA,UAAU,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;AAClC,SAAA,CAAC;AAEF,QAAA,WAAW,MAAM,KAAK,IAAI,MAAM,EAAE;;AAEhC,YAAA,IAAIS,uBAAa,CAAC,KAAK,CAAC,EAAE;AACxB,gBAAA,MAAM,UAAU,GAAG,KAAK,CAACC,mBAAS,CAAuC;AACzE,gBAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;;AAEzB,oBAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;wBAClC,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,KAAK,mBAAmB,EAAE;4BACjD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE;;;;oBAItD;;;;YAKJ,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;;;AAItC,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;;;AAGG;AACH,IAAA,OAAO,mBAAmB,CACxB,MAA2B,EAC3B,MAA2E,EAAA;AAM3E,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;;QAGF,MAAM,aAAa,GAAG,IAAIC,iBAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,aAAa,EAAE;AAC5D,YAAA,GAAG,MAAM;AACT,YAAA,UAAU,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;AAClC,SAAA,CAAC;AAEF,QAAA,WAAW,MAAM,KAAK,IAAI,MAAM,EAAE;;AAEhC,YAAA,IAAIF,uBAAa,CAAC,KAAK,CAAC,EAAE;AACxB,gBAAA,MAAM,UAAU,GAAG,KAAK,CAACC,mBAAS,CAAuC;AACzE,gBAAA,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;AACzB,oBAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;wBAClC,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,KAAK,mBAAmB,EAAE;4BACjD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE;;;oBAGtD;;;YAIJ,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;;AAGtC,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;;;;;;;"}
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 { isInterrupted, INTERRUPT, Command } from '@langchain/langgraph';
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 regular stream() instead of streamEvents() to properly detect interrupts.
347
- * Returns interrupt data when graph is paused waiting for browser action.
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
- // Use the values stream mode to detect interrupts
367
- const stream = await this.graphRunnable.stream(inputs, {
368
- ...config,
369
- streamMode: ['values', 'updates'],
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
- for await (const chunk of stream) {
372
- // Check if this chunk contains an interrupt
373
- if (isInterrupted(chunk)) {
374
- const interrupts = chunk[INTERRUPT];
375
- if (interrupts.length > 0) {
376
- // Emit the interrupt data to the client
377
- for (const interrupt of interrupts) {
378
- if (interrupt.value?.type === 'browser_interrupt') {
379
- yield { type: 'interrupt', data: interrupt.value };
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
- // Emit regular events
387
- yield { type: 'event', data: chunk };
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
- const stream = await this.graphRunnable.stream(resumeCommand, {
419
- ...config,
420
- streamMode: ['values', 'updates'],
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
- for await (const chunk of stream) {
423
- // Check if this chunk contains another interrupt
424
- if (isInterrupted(chunk)) {
425
- const interrupts = chunk[INTERRUPT];
426
- if (interrupts.length > 0) {
427
- for (const interrupt of interrupts) {
428
- if (interrupt.value?.type === 'browser_interrupt') {
429
- yield { type: 'interrupt', data: interrupt.value };
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
- yield { type: 'event', data: chunk };
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() };
@@ -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;;;;"}
@@ -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 regular stream() instead of streamEvents() to properly detect interrupts.
51
- * Returns interrupt data when graph is paused waiting for browser action.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "illuma-agents",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
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, INTERRUPT, isInterrupted } from '@langchain/langgraph';
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 regular stream() instead of streamEvents() to properly detect interrupts.
496
- * Returns interrupt data when graph is paused waiting for browser action.
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
- // Use the values stream mode to detect interrupts
532
- const stream = await this.graphRunnable.stream(inputs, {
533
- ...config,
534
- streamMode: ['values', 'updates'],
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
- for await (const chunk of stream) {
538
- // Check if this chunk contains an interrupt
539
- if (isInterrupted(chunk)) {
540
- const interrupts = chunk[INTERRUPT] as Array<{ value: BrowserInterrupt }>;
541
- if (interrupts.length > 0) {
542
- // Emit the interrupt data to the client
543
- for (const interrupt of interrupts) {
544
- if (interrupt.value?.type === 'browser_interrupt') {
545
- yield { type: 'interrupt', data: interrupt.value };
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
- // Emit regular events
554
- yield { type: 'event', data: chunk };
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
- const stream = await this.graphRunnable.stream(resumeCommand, {
602
- ...config,
603
- streamMode: ['values', 'updates'],
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
- for await (const chunk of stream) {
607
- // Check if this chunk contains another interrupt
608
- if (isInterrupted(chunk)) {
609
- const interrupts = chunk[INTERRUPT] as Array<{ value: BrowserInterrupt }>;
610
- if (interrupts.length > 0) {
611
- for (const interrupt of interrupts) {
612
- if (interrupt.value?.type === 'browser_interrupt') {
613
- yield { type: 'interrupt', data: interrupt.value };
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
- yield { type: 'event', data: chunk };
703
+ } catch (stateError) {
704
+ console.debug('[resumeBrowserStream] Could not get state:', stateError);
621
705
  }
622
706
 
623
707
  if (this.returnContent) {