@dvina/agents 0.8.0 → 0.9.2

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/index.js CHANGED
@@ -181,14 +181,19 @@ var LangchainAgent = class {
181
181
  output_tokens: 0,
182
182
  total_tokens: 0,
183
183
  cache_read: 0,
184
- reasoning_tokens: 0
184
+ reasoning_tokens: 0,
185
+ cache_creation: 0
185
186
  };
186
187
  messagesWithUsage.forEach((m) => {
187
- usage.input_tokens += m.usage_metadata.input_tokens || 0;
188
+ const cacheRead = m.usage_metadata.input_token_details?.cache_read || 0;
189
+ const provider = m.response_metadata?.model_provider;
190
+ const inputTokens = provider === "anthropic" ? m.usage_metadata.input_tokens || 0 : (m.usage_metadata.input_tokens || 0) - cacheRead;
191
+ usage.input_tokens += inputTokens;
188
192
  usage.output_tokens += m.usage_metadata.output_tokens || 0;
189
- usage.total_tokens += m.usage_metadata.total_tokens || 0;
190
- usage.cache_read += m.usage_metadata.input_token_details?.cache_read || 0;
193
+ usage.total_tokens += inputTokens + (m.usage_metadata.output_tokens || 0);
194
+ usage.cache_read += cacheRead;
191
195
  usage.reasoning_tokens += m.usage_metadata.output_token_details?.reasoning || 0;
196
+ usage.cache_creation += m.usage_metadata.input_token_details?.cache_creation || 0;
192
197
  });
193
198
  const contentBlocks = [];
194
199
  const toolCallInputs = {};
@@ -229,7 +234,8 @@ var LangchainAgent = class {
229
234
  completionTokens: usage.output_tokens,
230
235
  totalTokens: usage.total_tokens,
231
236
  cachedPromptTokens: usage.cache_read,
232
- reasoningTokens: usage.reasoning_tokens
237
+ reasoningTokens: usage.reasoning_tokens,
238
+ cacheCreationTokens: usage.cache_creation
233
239
  }
234
240
  };
235
241
  }
@@ -242,7 +248,8 @@ var LangchainAgent = class {
242
248
  completionTokens: 0,
243
249
  totalTokens: 0,
244
250
  cachedPromptTokens: 0,
245
- reasoningTokens: 0
251
+ reasoningTokens: 0,
252
+ cacheCreationTokens: 0
246
253
  };
247
254
  const messages = convertToLangchainMessages(input.messages);
248
255
  debugLogStream("message_start", "");
@@ -304,11 +311,12 @@ var LangchainAgent = class {
304
311
  } else if (this.isReasoningMessage(message)) {
305
312
  const contentArray = message.content;
306
313
  for (const block of contentArray) {
307
- if (block.type === "reasoning" && block.reasoning) {
308
- debugLogStream("reasoning_delta", block.reasoning);
314
+ const delta = block.type === "reasoning" && block.reasoning || block.type === "thinking" && block.thinking;
315
+ if (delta) {
316
+ debugLogStream("reasoning_delta", delta);
309
317
  yield {
310
318
  type: "reasoning_delta",
311
- delta: block.reasoning
319
+ delta
312
320
  };
313
321
  }
314
322
  }
@@ -365,11 +373,15 @@ var LangchainAgent = class {
365
373
  for (let aiChunk of aiMessageChunks) {
366
374
  const um = aiChunk.usage_metadata;
367
375
  if (um) {
368
- usageMetadata.promptTokens += um.input_tokens || 0;
376
+ const cacheRead = um.input_token_details?.cache_read || 0;
377
+ const provider = aiChunk.response_metadata?.model_provider;
378
+ const inputTokens = provider === "anthropic" ? um.input_tokens || 0 : (um.input_tokens || 0) - cacheRead;
379
+ usageMetadata.promptTokens += inputTokens;
369
380
  usageMetadata.completionTokens += um.output_tokens || 0;
370
- usageMetadata.totalTokens += um.total_tokens || 0;
371
- usageMetadata.cachedPromptTokens += um.input_token_details?.cache_read || 0;
381
+ usageMetadata.totalTokens += inputTokens + (um.output_tokens || 0);
382
+ usageMetadata.cachedPromptTokens += cacheRead;
372
383
  usageMetadata.reasoningTokens = (usageMetadata.reasoningTokens || 0) + (um.output_token_details?.reasoning || 0);
384
+ usageMetadata.cacheCreationTokens += um.input_token_details?.cache_creation || 0;
373
385
  }
374
386
  if (aiChunk.tool_calls && aiChunk.tool_calls.length > 0) {
375
387
  for (let tc of aiChunk.tool_calls)
@@ -459,11 +471,11 @@ var LangchainAgent = class {
459
471
  }
460
472
  isReasoningMessage(message) {
461
473
  if (!Array.isArray(message.content)) return false;
462
- return message.content.some((block) => block.type === "reasoning" && block.reasoning);
474
+ return message.content.some((block) => block.type === "reasoning" || block.type === "thinking");
463
475
  }
464
476
  isArrayTextMessage(message) {
465
477
  if (!Array.isArray(message.content)) return false;
466
- return message.content.some((block) => block.type === "text" && block.text);
478
+ return message.content.some((block) => block.type === "text");
467
479
  }
468
480
  /**
469
481
  * Extracts text from message content that may be a string
@@ -479,25 +491,48 @@ var LangchainAgent = class {
479
491
  };
480
492
 
481
493
  // src/runtime/langchain/model-resolver.ts
494
+ var import_anthropic = require("@langchain/anthropic");
482
495
  var import_openai = require("@langchain/openai");
483
- var LangchainModelResolver = class {
496
+ var LangchainModelResolver = class _LangchainModelResolver {
484
497
  constructor(config) {
485
498
  this.config = config;
486
499
  }
487
500
  resolve(modelString, tags, reasoningEffort) {
488
501
  const parts = modelString.split(":");
502
+ if (parts.length === 1) {
503
+ const fullModelString = this.resolveFullModelString(modelString);
504
+ return this.resolve(fullModelString, tags, reasoningEffort);
505
+ }
489
506
  if (parts.length === 2) {
490
507
  const [provider, modelName] = parts;
491
- return this.resolveByProvider(provider, "default", modelName, tags, reasoningEffort);
508
+ return this.resolveByProvider(provider, modelName, modelName, tags, reasoningEffort);
492
509
  }
493
510
  if (parts.length === 3) {
494
511
  const [provider, configName, modelName] = parts;
495
512
  return this.resolveByProvider(provider, configName, modelName, tags, reasoningEffort);
496
513
  }
497
514
  throw new Error(
498
- 'Model string must follow format "provider:modelName" (uses "default" config) or "provider:configName:modelName"'
515
+ 'Model string must follow format "modelName", "provider:modelName", or "provider:configName:modelName"'
499
516
  );
500
517
  }
518
+ resolveFullModelString(modelName) {
519
+ for (const [provider, resources] of Object.entries(this.config)) {
520
+ if (provider === "openai") {
521
+ if (modelName in resources) {
522
+ return `openai:${modelName}`;
523
+ }
524
+ } else if (provider === "azure") {
525
+ for (const [resource, config] of Object.entries(
526
+ resources
527
+ )) {
528
+ if (config.models.some((m) => m.model === modelName)) {
529
+ return `azure:${resource}:${modelName}`;
530
+ }
531
+ }
532
+ }
533
+ }
534
+ throw new Error(`Model "${modelName}" not found in model config`);
535
+ }
501
536
  resolveByProvider(provider, configName, modelName, tags, reasoningEffort) {
502
537
  switch (provider) {
503
538
  case "openai":
@@ -535,39 +570,52 @@ var LangchainModelResolver = class {
535
570
  if (!modelEntry) {
536
571
  throw new Error(`Model "${modelName}" not found in Azure resource "${resourceName}"`);
537
572
  }
538
- if (reasoningEffort) {
539
- const responsesBaseURL = `${resource.endpoint.replace(/\/$/, "")}/openai/responses?api-version=${modelEntry.apiVersion}`;
540
- return new import_openai.AzureChatOpenAI({
541
- model: modelEntry.model,
542
- azureOpenAIApiKey: resource.apiKey,
543
- azureOpenAIEndpoint: responsesBaseURL,
544
- azureOpenAIApiDeploymentName: modelEntry.deploymentName,
545
- azureOpenAIApiVersion: modelEntry.apiVersion,
546
- tags,
547
- ...reasoningEffort && {
548
- reasoning: {
549
- effort: reasoningEffort,
550
- summary: "auto"
551
- }
552
- }
553
- });
573
+ switch (modelEntry.provider) {
574
+ case "anthropic":
575
+ return this.resolveAzureAnthropic(resource, modelEntry, tags, reasoningEffort);
576
+ case "openai":
577
+ return this.resolveAzureOpenAI(resource, modelEntry, tags, reasoningEffort);
554
578
  }
579
+ }
580
+ resolveAzureOpenAI(resource, modelEntry, tags, reasoningEffort) {
581
+ const endpoint = reasoningEffort ? `${modelEntry.endpoint.replace(/\/$/, "")}/openai/responses?api-version=${modelEntry.apiVersion}` : modelEntry.endpoint;
555
582
  return new import_openai.AzureChatOpenAI({
556
583
  model: modelEntry.model,
557
584
  azureOpenAIApiKey: resource.apiKey,
558
- azureOpenAIEndpoint: resource.endpoint,
585
+ azureOpenAIEndpoint: endpoint,
559
586
  azureOpenAIApiDeploymentName: modelEntry.deploymentName,
560
587
  azureOpenAIApiVersion: modelEntry.apiVersion,
561
- tags
588
+ tags,
589
+ ...reasoningEffort && {
590
+ reasoning: {
591
+ effort: reasoningEffort,
592
+ summary: "auto"
593
+ }
594
+ }
562
595
  });
563
596
  }
564
- extractInstanceName(endpoint) {
565
- try {
566
- const url = new URL(endpoint);
567
- return url.hostname.split(".")[0];
568
- } catch (e) {
569
- return endpoint;
570
- }
597
+ static THINKING_BUDGET = {
598
+ minimal: 1024,
599
+ low: 4096,
600
+ medium: 1e4,
601
+ high: 16e3,
602
+ xhigh: 32e3
603
+ };
604
+ resolveAzureAnthropic(resource, modelEntry, tags, reasoningEffort) {
605
+ const budgetTokens = reasoningEffort ? _LangchainModelResolver.THINKING_BUDGET[reasoningEffort] : void 0;
606
+ return new import_anthropic.ChatAnthropic({
607
+ model: modelEntry.model,
608
+ apiKey: resource.apiKey,
609
+ clientOptions: { baseURL: modelEntry.endpoint },
610
+ tags,
611
+ ...budgetTokens && {
612
+ maxTokens: budgetTokens * 2,
613
+ thinking: {
614
+ type: "enabled",
615
+ budget_tokens: budgetTokens
616
+ }
617
+ }
618
+ });
571
619
  }
572
620
  };
573
621
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/runtime/langchain/factory.ts","../src/runtime/langchain/agent.ts","../src/runtime/langchain/utils.ts","../src/runtime/langchain/model-resolver.ts","../src/core/tools/tool-registry.ts","../src/core/tools/tool-cache.ts"],"sourcesContent":["// Core Interfaces & Factory\nexport { AgentFactory, CreateAgentOptions, AgentHandoff } from './core/agent.factory';\nexport {\n\tAgent,\n\tAgentRunInput,\n\tAgentResult,\n\tMessage,\n\tHumanMessage,\n\tAiMessage,\n\tToolMessage,\n\tContentBlock,\n\tUsageMeta,\n\tToolSpec,\n\tToolDefinition,\n\tToolCall,\n\tStreamEvent,\n} from './core/agent.interface';\nexport { LangchainAgentFactory } from './runtime/langchain/factory';\nexport { type LangchainModelConfig } from './runtime/langchain/model-resolver';\n\n// Tools\nexport { ToolRegistry } from './core/tools/tool-registry';\nexport { ToolProvider } from './core/tools/tool-provider';\nexport { ToolCache, RedisToolCache, InMemoryToolCache } from './core/tools/tool-cache';\n","import { AgentFactory, CreateAgentOptions } from '@core/agent.factory';\nimport { Agent } from '@core/agent.interface';\nimport { PostgresSaver } from '@langchain/langgraph-checkpoint-postgres';\n// @ts-ignore -_-\nimport { PostgresStore } from '@langchain/langgraph-checkpoint-postgres/store';\nimport { CompositeBackend, StateBackend, StoreBackend } from 'deepagents';\nimport { AgentMiddleware, llmToolSelectorMiddleware, summarizationMiddleware, tool } from 'langchain';\nimport { CreateOptions, LangchainAgent } from './agent';\nimport { LangchainModelConfig, LangchainModelResolver } from './model-resolver';\n\nexport interface PostgresSaverConfig {\n\tconnString: string;\n\tschema: string;\n}\n\nexport interface PostgresStoreConfig {\n\tconnString: string;\n\tschema: string;\n}\n\nexport class LangchainAgentFactory implements AgentFactory {\n\tprivate modelResolver: LangchainModelResolver;\n\n\tconstructor(\n\t\tprivate modelConfig: LangchainModelConfig,\n\t\tprivate saverConfig: PostgresSaverConfig,\n\t\tprivate storeConfig: PostgresStoreConfig,\n\t) {\n\t\tthis.modelResolver = new LangchainModelResolver(this.modelConfig);\n\t}\n\n\tprivate buildMemorySystemPrompt(slots: { name: string; usedFor: string }[]): string {\n\t\tconst lines = [\n\t\t\t'Long-term memory is enabled.',\n\t\t\t'Persist memories using the filesystem tools under these path prefixes:',\n\t\t\t...slots.map((slot) => {\n\t\t\t\tconst prefix = this.normalizeStoreRoutePrefix(slot.name);\n\t\t\t\treturn `- ${prefix}: ${slot.usedFor}`;\n\t\t\t}),\n\t\t];\n\n\t\treturn lines.join('\\n');\n\t}\n\n\tprivate buildHandoffsSystemPrompt(handoffs: { name: string; description: string }[]): string {\n\t\tconst lines = [\n\t\t\t'You can delegate tasks to the following subagents:',\n\t\t\t...handoffs.map((handoff) => `- ${handoff.name}: ${handoff.description}`),\n\t\t];\n\n\t\treturn lines.join('\\n');\n\t}\n\n\tprivate normalizeStoreRoutePrefix(prefix: string): string {\n\t\tconst trimmedPrefix = prefix.trim();\n\t\tif (trimmedPrefix.length === 0) {\n\t\t\tthrow new Error('Memory slot name cannot be empty');\n\t\t}\n\n\t\tconst withLeadingSlash = trimmedPrefix.startsWith('/') ? trimmedPrefix : `/${trimmedPrefix}`;\n\t\treturn withLeadingSlash.endsWith('/') ? withLeadingSlash : `${withLeadingSlash}/`;\n\t}\n\n\tasync createAgent(options: CreateAgentOptions): Promise<Agent> {\n\t\tlet deepAgentOptions: CreateOptions = {\n\t\t\tmodel: this.modelResolver.resolve(options.model, [], options.reasoning),\n\t\t};\n\n\t\tlet middlewares: AgentMiddleware[] = [];\n\t\tlet systemPrompt = options.instructions ?? '';\n\t\tlet disableStreamingForTools: string[] = [\n\t\t\t'write_todos',\n\t\t\t'ls',\n\t\t\t'read_file',\n\t\t\t'write_file',\n\t\t\t'edit_file',\n\t\t\t'glob',\n\t\t\t'grep',\n\t\t\t'task',\n\t\t];\n\t\tlet disableReportingForTools: string[] = disableStreamingForTools;\n\t\tlet disableModelStreamingFor: string[] = [];\n\n\t\tif (options.history) {\n\t\t\tconst checkpointer = PostgresSaver.fromConnString(this.saverConfig.connString, {\n\t\t\t\tschema: this.saverConfig.schema,\n\t\t\t});\n\n\t\t\tawait checkpointer.setup();\n\n\t\t\tdeepAgentOptions.checkpointer = checkpointer;\n\t\t}\n\n\t\tif (options.memory) {\n\t\t\tconst memorySystemPrompt = this.buildMemorySystemPrompt(options.memory.slots);\n\t\t\tsystemPrompt = systemPrompt ? `${systemPrompt}\\n\\n${memorySystemPrompt}` : memorySystemPrompt;\n\n\t\t\tdeepAgentOptions.store = new PostgresStore({\n\t\t\t\tconnectionOptions: this.storeConfig.connString,\n\t\t\t\tschema: this.storeConfig.schema,\n\t\t\t\tensureTables: true,\n\t\t\t});\n\t\t\t/**\n\t\t\t * StateBackend for ephemeral storage\n\t\t\t * StoreBackend for persistent storage\n\t\t\t */\n\t\t\tdeepAgentOptions.backend = (config) => {\n\t\t\t\tconst configWithAssistantId = { ...config, assistantId: options.memory?.assistantId };\n\t\t\t\tconst storeBackend = new StoreBackend(configWithAssistantId);\n\t\t\t\tconst routes = Object.fromEntries(\n\t\t\t\t\t(options.memory?.slots ?? []).map((slot) => {\n\t\t\t\t\t\tconst routePrefix = this.normalizeStoreRoutePrefix(slot.name);\n\t\t\t\t\t\treturn [routePrefix, storeBackend];\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\treturn new CompositeBackend(new StateBackend(configWithAssistantId), {\n\t\t\t\t\t...routes,\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tif (options.tools) {\n\t\t\tdeepAgentOptions.tools = options.tools.tools.map((t) =>\n\t\t\t\ttool(\n\t\t\t\t\tasync (input, options) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst res = await t.exec(input);\n\n\t\t\t\t\t\t\tif (typeof res === 'string') return res;\n\n\t\t\t\t\t\t\treturn JSON.stringify(res);\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tconsole.error('Error executing tool:', e);\n\t\t\t\t\t\t\treturn 'Something went wrong while executing the tool.';\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: t.name,\n\t\t\t\t\t\tdescription: t.description,\n\t\t\t\t\t\tschema: t.inputSchema,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\ttoolKit: t.toolKit,\n\t\t\t\t\t\t\ttoolKitIconUrl: t.toolKitIconUrl,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t\tmiddlewares.push(\n\t\t\t\tllmToolSelectorMiddleware({\n\t\t\t\t\tmodel: this.modelResolver.resolve(options.tools.model, ['tool-selector']),\n\t\t\t\t\tmaxTools: 128,\n\t\t\t\t\talwaysInclude: options.tools.alwaysIncludeTools ?? undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tdisableModelStreamingFor.push('tool-selector');\n\t\t}\n\n\t\tif (options.summarization)\n\t\t\tmiddlewares.push(\n\t\t\t\tsummarizationMiddleware({\n\t\t\t\t\tmodel: this.modelResolver.resolve(options.summarization.model),\n\t\t\t\t\ttrigger: {\n\t\t\t\t\t\ttokens: options.summarization.triggerAtTokens,\n\t\t\t\t\t},\n\t\t\t\t\tkeep: {\n\t\t\t\t\t\tmessages: options.summarization.keepMessages,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\n\t\tif (options.handoffs) {\n\t\t\toptions.handoffs.every((h) => {\n\t\t\t\tif (!(h.agent instanceof LangchainAgent)) {\n\t\t\t\t\tthrow new Error('Handoff agent must be an instance of LangchainAgent');\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst handoffsSystemPrompt = this.buildHandoffsSystemPrompt(options.handoffs);\n\t\t\tsystemPrompt = systemPrompt ? `${systemPrompt}\\n\\n${handoffsSystemPrompt}` : handoffsSystemPrompt;\n\n\t\t\tdeepAgentOptions.subagents = options.handoffs.map((h) => {\n\t\t\t\treturn {\n\t\t\t\t\tname: h.name,\n\t\t\t\t\tdescription: h.description,\n\t\t\t\t\trunnable: (h.agent as LangchainAgent).getLangchainAgent(),\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\tif (middlewares.length > 0) deepAgentOptions.middleware = middlewares;\n\n\t\tif (systemPrompt) deepAgentOptions.systemPrompt = systemPrompt;\n\n\t\tdeepAgentOptions.disableModelStreamingFor = disableModelStreamingFor;\n\t\tdeepAgentOptions.disableToolReportingFor = disableReportingForTools;\n\t\tdeepAgentOptions.disableToolStreamingFor = disableStreamingForTools;\n\n\t\treturn new LangchainAgent(deepAgentOptions);\n\t}\n}\n","import {\n\tAgent,\n\tAgentResult,\n\tAgentRunInput,\n\tContentBlock,\n\tStreamEvent,\n\tToolCall,\n\tUsageMeta,\n} from '@core/agent.interface';\nimport { ToolCallChunk, ToolMessage } from '@langchain/core/messages';\nimport { Command } from '@langchain/langgraph';\nimport { createDeepAgent, CreateDeepAgentParams } from 'deepagents';\nimport { AgentMiddleware, AIMessageChunk, BaseMessage, createMiddleware, ReactAgent, StructuredTool } from 'langchain';\nimport { convertToLangchainMessages } from './utils';\n\nconst ENABLE_STREAM_DEBUG_LOGS = false;\n\nfunction debugLogStream(type: StreamEvent['type'], text: string) {\n\tif (!ENABLE_STREAM_DEBUG_LOGS) return;\n\n\tconsole.warn(`${type}: ${text}`);\n}\n\nexport interface CreateOptions extends CreateDeepAgentParams {\n\t/**\n\t * Tool names to disable streaming for\n\t */\n\tdisableToolStreamingFor?: string[];\n\n\t/**\n\t * Tool names to disable streaming for\n\t */\n\tdisableToolReportingFor?: string[];\n\n\t/**\n\t * Model tags to disable streaming for\n\t */\n\tdisableModelStreamingFor?: string[];\n}\n\nexport class LangchainAgent implements Agent {\n\tprivate deepAgent: ReactAgent;\n\tprivate toolCalls: ToolCall[] = [];\n\tprivate tools?: StructuredTool[];\n\n\tconstructor(private params: CreateOptions) {\n\t\tthis.tools = params.tools;\n\n\t\tif (!params.disableModelStreamingFor) params.disableModelStreamingFor = [];\n\t\tif (!params.disableToolReportingFor) params.disableToolReportingFor = [];\n\t\tif (!params.disableToolStreamingFor) params.disableToolStreamingFor = [];\n\n\t\tlet middlewares: AgentMiddleware[] = [\n\t\t\tcreateMiddleware({\n\t\t\t\tname: 'toolCallsReporter',\n\t\t\t\twrapToolCall: async (request, handler) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst res = await handler(request);\n\n\t\t\t\t\t\tif (this.params.disableToolReportingFor?.includes(request.tool?.name as string)) return res;\n\n\t\t\t\t\t\tthis.toolCalls.push({\n\t\t\t\t\t\t\tid: request.toolCall.id as string,\n\t\t\t\t\t\t\tname: (request.tool?.name as string) || '',\n\t\t\t\t\t\t\tinput: request.toolCall.args,\n\t\t\t\t\t\t\toutput: res.toJSON(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Wrapped tool may sometimes return Command objects\n\t\t\t\t\t\t * which should actually trigger the \"updates\" mode\n\t\t\t\t\t\t * of stream. But we don't want that to happen. We\n\t\t\t\t\t\t * want to emit tool_result events from a single place.\n\t\t\t\t\t\t * So we extract the tool message from the update and\n\t\t\t\t\t\t * command.update.messages and return that. That way\n\t\t\t\t\t\t * 'messages' stream mode is triggered\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Hopefully this won't cause any issues.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (res instanceof Command) {\n\t\t\t\t\t\t\tconst resCast: {\n\t\t\t\t\t\t\t\tupdate?: {\n\t\t\t\t\t\t\t\t\tmessages?: BaseMessage[];\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t} = res as any;\n\n\t\t\t\t\t\t\tif (!resCast.update?.messages || resCast.update.messages.length == 0) return res;\n\n\t\t\t\t\t\t\tconst toolMessage = resCast.update.messages.find((m: BaseMessage) => m.type == 'tool');\n\n\t\t\t\t\t\t\tif (!toolMessage) return res;\n\n\t\t\t\t\t\t\treturn toolMessage as ToolMessage;\n\t\t\t\t\t\t} else return res;\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\treturn new ToolMessage({\n\t\t\t\t\t\t\tname: request.toolCall.name,\n\t\t\t\t\t\t\tcontent: 'Something went wrong: ' + e.message,\n\t\t\t\t\t\t\ttool_call_id: request.toolCall.id || 'TOOL_CALL_ERROR',\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\n\t\tif (params.middleware) middlewares = [...middlewares, ...params.middleware];\n\n\t\tparams.middleware = middlewares;\n\n\t\tthis.deepAgent = createDeepAgent(params);\n\t}\n\n\tasync run(input: AgentRunInput): Promise<AgentResult> {\n\t\tthis.toolCalls = []; // Reset tool calls for each run\n\n\t\t// Get current state to know how many messages existed before this turn\n\t\t// If no checkpointer is set, assume this is a fresh conversation\n\t\tlet messageCountBefore = 0;\n\t\ttry {\n\t\t\tconst stateBefore = await this.deepAgent.getState({\n\t\t\t\tconfigurable: {\n\t\t\t\t\tthreadId: input.threadId,\n\t\t\t\t\tthread_id: input.threadId,\n\t\t\t\t},\n\t\t\t});\n\t\t\tmessageCountBefore = (stateBefore as any)?.values?.messages?.length || 0;\n\t\t} catch {\n\t\t\t// No checkpointer set - this is fine, we'll count from 0\n\t\t}\n\n\t\tconst messages = convertToLangchainMessages(input.messages);\n\n\t\tconst result = await this.deepAgent.invoke(\n\t\t\t{\n\t\t\t\tmessages: messages,\n\t\t\t},\n\t\t\t{\n\t\t\t\tconfigurable: {\n\t\t\t\t\tthreadId: input.threadId,\n\t\t\t\t\tthread_id: input.threadId,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\t// Only sum usage from messages added in this turn\n\t\tconst newMessages = result.messages.slice(messageCountBefore);\n\t\tconst messagesWithUsage = newMessages.filter((m: any) => m.usage_metadata != null);\n\n\t\tlet usage = {\n\t\t\tinput_tokens: 0,\n\t\t\toutput_tokens: 0,\n\t\t\ttotal_tokens: 0,\n\t\t\tcache_read: 0,\n\t\t\treasoning_tokens: 0,\n\t\t};\n\n\t\tmessagesWithUsage.forEach((m: any) => {\n\t\t\tusage.input_tokens += m.usage_metadata.input_tokens || 0;\n\t\t\tusage.output_tokens += m.usage_metadata.output_tokens || 0;\n\t\t\tusage.total_tokens += m.usage_metadata.total_tokens || 0;\n\t\t\tusage.cache_read += m.usage_metadata.input_token_details?.cache_read || 0;\n\t\t\tusage.reasoning_tokens += m.usage_metadata.output_token_details?.reasoning || 0;\n\t\t});\n\n\t\t// Build content blocks from new messages\n\t\tconst contentBlocks: ContentBlock[] = [];\n\t\tconst toolCallInputs: { [toolCallId: string]: any } = {};\n\n\t\tfor (const msg of newMessages) {\n\t\t\tconst m = msg as any;\n\t\t\tif (m.type === 'ai') {\n\t\t\t\t// Store tool call inputs for later pairing\n\t\t\t\tif (m.tool_calls && m.tool_calls.length > 0) {\n\t\t\t\t\tfor (const tc of m.tool_calls) {\n\t\t\t\t\t\ttoolCallInputs[tc.id] = tc.args;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Add text content if present\n\t\t\t\tif (m.content) {\n\t\t\t\t\tconst textOutput = this.extractTextContent(m.content);\n\t\t\t\t\tif (textOutput.trim().length > 0) {\n\t\t\t\t\t\tcontentBlocks.push({\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\toutput: textOutput,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (m.type === 'tool') {\n\t\t\t\tcontentBlocks.push({\n\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\tname: m.name,\n\t\t\t\t\ttoolKit: this.getToolKitMeta(m.name).toolKit,\n\t\t\t\t\ttoolKitIconUrl: this.getToolKitMeta(m.name).toolKitIconUrl,\n\t\t\t\t\tinput: JSON.stringify(toolCallInputs[m.tool_call_id] || {}),\n\t\t\t\t\toutput: m.content.toString(),\n\t\t\t\t\ttoolCallId: m.tool_call_id,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: contentBlocks,\n\t\t\ttoolCalls: this.toolCalls,\n\t\t\tusage: {\n\t\t\t\tpromptTokens: usage.input_tokens,\n\t\t\t\tcompletionTokens: usage.output_tokens,\n\t\t\t\ttotalTokens: usage.total_tokens,\n\t\t\t\tcachedPromptTokens: usage.cache_read,\n\t\t\t\treasoningTokens: usage.reasoning_tokens,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync *stream(input: AgentRunInput): AsyncGenerator<StreamEvent> {\n\t\tthis.toolCalls = []; // Reset tool calls for each stream\n\t\tconst contentBlocks: ContentBlock[] = []; // this will be our final return value\n\t\tlet finalValue;\n\n\t\t// Initialize usage metadata - accumulated from updates mode (current turn only)\n\t\tlet usageMetadata: UsageMeta = {\n\t\t\tpromptTokens: 0,\n\t\t\tcompletionTokens: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcachedPromptTokens: 0,\n\t\t\treasoningTokens: 0,\n\t\t};\n\n\t\tconst messages = convertToLangchainMessages(input.messages);\n\n\t\tdebugLogStream('message_start', '');\n\n\t\t// Emit message start\n\t\tyield { type: 'message_start' };\n\n\t\tconst stream = await this.deepAgent.stream(\n\t\t\t{ messages },\n\t\t\t{\n\t\t\t\tconfigurable: {\n\t\t\t\t\tthreadId: input.threadId,\n\t\t\t\t\tthread_id: input.threadId,\n\t\t\t\t},\n\t\t\t\tstreamMode: ['messages', 'updates', 'values'],\n\t\t\t},\n\t\t);\n\n\t\tlet toolCalls: {\n\t\t\t[index: number]: {\n\t\t\t\ttoolCallId: string;\n\t\t\t\tname: string;\n\t\t\t};\n\t\t} = {};\n\t\tconst toolCallUpdates: {\n\t\t\t[toolCallId: string]: {\n\t\t\t\tname: string;\n\t\t\t\targs: any;\n\t\t\t};\n\t\t} = {};\n\n\t\t/**\n\t\t * Process chunks produced by the LLM\n\t\t */\n\t\tfor await (const chunk of stream) {\n\t\t\tconst [mode, data] = chunk;\n\n\t\t\tif (mode === 'messages') {\n\t\t\t\tconst [message, metadata] = data;\n\n\t\t\t\t/**\n\t\t\t\t * Some messages carry no meaningful information\n\t\t\t\t */\n\t\t\t\tif (this.shouldIgnoreMessage(message, metadata)) continue;\n\n\t\t\t\t/**\n\t\t\t\t * LLMs also stream the tool input tokens. If we see\n\t\t\t\t * tool_call_chunks inside the message, we know it's\n\t\t\t\t * a token stream for a tool call.\n\t\t\t\t */\n\t\t\t\tif (this.isToolCallMessage(message)) {\n\t\t\t\t\tconst aiMessage = message as AIMessageChunk;\n\t\t\t\t\tconst toolCallChunks = aiMessage.tool_call_chunks as ToolCallChunk[];\n\n\t\t\t\t\tfor (const toolChunk of toolCallChunks) {\n\t\t\t\t\t\tconst toolCallIndex = toolChunk.index as number;\n\n\t\t\t\t\t\tconst getToolCallInfo = () => {\n\t\t\t\t\t\t\treturn toolCalls[toolCallIndex];\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * On the first chunk, we get the tool name in\n\t\t\t\t\t\t * chunk.id. On sequential chunks this property\n\t\t\t\t\t\t * is set to defined. So if there is id in the\n\t\t\t\t\t\t * chunk; this is a tool_start event.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Also different tool calls are separated using\n\t\t\t\t\t\t * the \"index\" property. This exists in all tool\n\t\t\t\t\t\t * chunk messages.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (toolChunk.id) {\n\t\t\t\t\t\t\ttoolCalls[toolChunk.index as number] = {\n\t\t\t\t\t\t\t\ttoolCallId: toolChunk.id,\n\t\t\t\t\t\t\t\tname: toolChunk.name as string,\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tif (!this.shouldStreamToolEvent(getToolCallInfo().name)) continue;\n\n\t\t\t\t\t\t\tconst toolKitMeta = this.getToolKitMeta(getToolCallInfo().name);\n\n\t\t\t\t\t\t\tdebugLogStream('tool_start', `[${getToolCallInfo().toolCallId}] ${getToolCallInfo().name}`);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'tool_start',\n\t\t\t\t\t\t\t\tname: getToolCallInfo().name,\n\t\t\t\t\t\t\t\ttoolKit: toolKitMeta.toolKit,\n\t\t\t\t\t\t\t\ttoolKitIconUrl: toolKitMeta.toolKitIconUrl,\n\t\t\t\t\t\t\t\tindex: toolCallIndex,\n\t\t\t\t\t\t\t\ttoolCallId: getToolCallInfo().toolCallId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (toolChunk.args && toolChunk.args.length > 0) {\n\t\t\t\t\t\t\tif (!this.shouldStreamToolEvent(getToolCallInfo().name)) continue;\n\n\t\t\t\t\t\t\tdebugLogStream('tool_input_delta', `[${getToolCallInfo().toolCallId}] ${toolChunk.args}`);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'tool_input_delta',\n\t\t\t\t\t\t\t\tname: getToolCallInfo().name,\n\t\t\t\t\t\t\t\targs: toolChunk.args || '',\n\t\t\t\t\t\t\t\tindex: toolCallIndex,\n\t\t\t\t\t\t\t\ttoolCallId: getToolCallInfo().toolCallId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isReasoningMessage(message)) {\n\t\t\t\t\tconst contentArray = message.content as any[];\n\t\t\t\t\tfor (const block of contentArray) {\n\t\t\t\t\t\tif (block.type === 'reasoning' && block.reasoning) {\n\t\t\t\t\t\t\tdebugLogStream('reasoning_delta', block.reasoning);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'reasoning_delta',\n\t\t\t\t\t\t\t\tdelta: block.reasoning,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isArrayTextMessage(message)) {\n\t\t\t\t\tconst contentArray = message.content as any[];\n\t\t\t\t\tfor (const block of contentArray) {\n\t\t\t\t\t\tif (block.type === 'text' && block.text) {\n\t\t\t\t\t\t\tdebugLogStream('text_delta', block.text);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'text_delta',\n\t\t\t\t\t\t\t\tdelta: block.text,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (message?.content && typeof message.content === 'string') {\n\t\t\t\t\tconst content = message.content;\n\n\t\t\t\t\tif (content.length === 0) continue;\n\n\t\t\t\t\tif (message.type == 'tool') {\n\t\t\t\t\t\t// I know it's odd but ToolMessage.name seems to corelate to the tool name\n\t\t\t\t\t\tconst toolName = message.name as string;\n\t\t\t\t\t\tconst toolKitMeta = this.getToolKitMeta(toolName);\n\n\t\t\t\t\t\tconst toolCall = Object.entries(toolCalls).find(\n\t\t\t\t\t\t\t([_, value]) => value.toolCallId == (message as ToolMessage).tool_call_id,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!this.shouldStreamToolEvent(toolName)) continue;\n\n\t\t\t\t\t\tdebugLogStream('tool_result', `[${toolCall?.[1].toolCallId}] ${message.content}`);\n\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\ttype: 'tool_result',\n\t\t\t\t\t\t\tname: toolName,\n\t\t\t\t\t\t\tinput:\n\t\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t\tthis.toolCalls.find((tc) => tc.id == (toolCall as any)[1].toolCallId)?.input,\n\t\t\t\t\t\t\t\t) || '',\n\t\t\t\t\t\t\toutput: message.content,\n\t\t\t\t\t\t\ttoolKit: toolKitMeta.toolKit,\n\t\t\t\t\t\t\ttoolKitIconUrl: toolKitMeta.toolKitIconUrl,\n\t\t\t\t\t\t\tindex: toolCall?.[0] ? parseInt(toolCall[0]) : 99999,\n\t\t\t\t\t\t\ttoolCallId: toolCall?.[1] ? toolCall[1].toolCallId : 'NO_ID_FOUND',\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdebugLogStream('text_delta', content);\n\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\ttype: 'text_delta',\n\t\t\t\t\t\t\tdelta: content,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn('Unexpected messages stream chunk', chunk);\n\t\t\t\t}\n\t\t\t} else if (mode == 'updates') {\n\t\t\t\tconst update = data;\n\n\t\t\t\t/**\n\t\t\t\t * This is how we get the tool INPUTS and llm\n\t\t\t\t * tokens that'll be used in returned content\n\t\t\t\t * blocks\n\t\t\t\t */\n\t\t\t\tif (update.model_request?.messages) {\n\t\t\t\t\tconst aiMessageChunks: AIMessageChunk[] = update.model_request.messages.filter(\n\t\t\t\t\t\t(m) => m.type == 'ai',\n\t\t\t\t\t) as AIMessageChunk[];\n\n\t\t\t\t\tfor (let aiChunk of aiMessageChunks) {\n\t\t\t\t\t\t// Accumulate usage metadata from current turn's AI messages\n\t\t\t\t\t\tconst um = (aiChunk as any).usage_metadata;\n\t\t\t\t\t\tif (um) {\n\t\t\t\t\t\t\tusageMetadata.promptTokens += um.input_tokens || 0;\n\t\t\t\t\t\t\tusageMetadata.completionTokens += um.output_tokens || 0;\n\t\t\t\t\t\t\tusageMetadata.totalTokens += um.total_tokens || 0;\n\t\t\t\t\t\t\tusageMetadata.cachedPromptTokens += um.input_token_details?.cache_read || 0;\n\t\t\t\t\t\t\tusageMetadata.reasoningTokens =\n\t\t\t\t\t\t\t\t(usageMetadata.reasoningTokens || 0) + (um.output_token_details?.reasoning || 0);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (aiChunk.tool_calls && aiChunk.tool_calls.length > 0) {\n\t\t\t\t\t\t\tfor (let tc of aiChunk.tool_calls)\n\t\t\t\t\t\t\t\ttoolCallUpdates[tc.id as string] = {\n\t\t\t\t\t\t\t\t\tname: tc.name,\n\t\t\t\t\t\t\t\t\targs: tc.args,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if (aiChunk.content) {\n\t\t\t\t\t\t\tconst textOutput = this.extractTextContent(aiChunk.content);\n\t\t\t\t\t\t\tif (textOutput.trim().length > 0)\n\t\t\t\t\t\t\t\tcontentBlocks.push({\n\t\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\t\toutput: textOutput,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * This is how we get the tool OUTPUTS that'll be\n\t\t\t\t * used in returned content blocks\n\t\t\t\t */\n\t\t\t\tif (update.tools?.messages) {\n\t\t\t\t\tconst toolMessages: ToolMessage[] = update.tools.messages.filter(\n\t\t\t\t\t\t(m) => m.type == 'tool',\n\t\t\t\t\t) as ToolMessage[];\n\n\t\t\t\t\tfor (let tm of toolMessages) {\n\t\t\t\t\t\tconst input = JSON.stringify(toolCallUpdates[tm.tool_call_id].args);\n\t\t\t\t\t\tconst toolCall = this.toolCalls.find((tc) => tc.id == tm.tool_call_id);\n\n\t\t\t\t\t\tif (this.shouldStreamToolEvent(tm.name as string))\n\t\t\t\t\t\t\tcontentBlocks.push({\n\t\t\t\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\t\t\t\tname: tm.name as string,\n\t\t\t\t\t\t\t\ttoolKit: this.getToolKitMeta(tm.name as string).toolKit,\n\t\t\t\t\t\t\t\ttoolKitIconUrl: this.getToolKitMeta(tm.name as string).toolKitIconUrl,\n\t\t\t\t\t\t\t\tinput: toolCall ? JSON.stringify(toolCall.input) : null,\n\t\t\t\t\t\t\t\toutput: tm.content.toString(),\n\t\t\t\t\t\t\t\ttoolCallId: tm.tool_call_id,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// console.error('\\n----------');\n\t\t\t\t// console.error('UPDATE');\n\t\t\t\t// console.error(JSON.stringify(data, null, 2));\n\t\t\t\t// console.error('----------\\n');\n\t\t\t} else if (mode == 'values') finalValue = data;\n\t\t}\n\n\t\tdebugLogStream('message_end', '\\n');\n\n\t\tyield { type: 'final_content', content: contentBlocks, usage: usageMetadata };\n\n\t\tyield { type: 'message_end' };\n\t}\n\n\tgetLangchainAgent(): ReactAgent {\n\t\treturn this.deepAgent;\n\t}\n\n\t/**\n\t * Tools have metadata fields that we can use\n\t * to get which toolKit this tool belongs to\n\t * and what's the toolKit's icon url.\n\t *\n\t * So we first find the tool using the tool's\n\t * name, then we extract the toolkit metadata\n\t * from that tool's metadata.\n\t */\n\tprivate getToolKitMeta(toolName: string): {\n\t\ttoolKit: string;\n\t\ttoolKitIconUrl: string;\n\t} {\n\t\tif (!this.tools)\n\t\t\treturn {\n\t\t\t\ttoolKit: '',\n\t\t\t\ttoolKitIconUrl: '',\n\t\t\t};\n\n\t\tconst tool = this.tools.find((t) => t.name === toolName);\n\n\t\tif (!tool) return { toolKit: '', toolKitIconUrl: '' };\n\n\t\treturn {\n\t\t\ttoolKit: tool.metadata?.toolKit as string,\n\t\t\ttoolKitIconUrl: tool.metadata?.toolKitIconUrl as string,\n\t\t};\n\t}\n\n\tprivate isToolCallMessage(message: BaseMessage): boolean {\n\t\tif (!(message instanceof AIMessageChunk)) return false;\n\n\t\tconst toolCallChunks = message.tool_call_chunks;\n\n\t\tif (!toolCallChunks) return false;\n\n\t\tif (toolCallChunks.length == 0) return false;\n\n\t\treturn true;\n\t}\n\n\tprivate shouldIgnoreMessage = (message: BaseMessage, metadata: any) => {\n\t\tif (message.id == '__remove_all__') return true;\n\n\t\t/**\n\t\t * For some reason there are AIMessageChunk messages\n\t\t * with empty content + no tool_call_chunks\n\t\t */\n\t\tif (!this.isToolCallMessage(message) && (!message.content || message.content.length == 0)) return true;\n\n\t\t/**\n\t\t * This is the tool selector middleware\n\t\t */\n\t\tif (metadata?.langgraph_node?.includes('patchToolCallsMiddleware')) return true;\n\n\t\tfor (const disabled of this.params.disableModelStreamingFor || [])\n\t\t\tif (metadata?.tags.includes(disabled)) return true;\n\n\t\treturn false;\n\t};\n\n\tprivate shouldStreamToolEvent(toolName: string): boolean {\n\t\tconst shouldStream = !this.params.disableToolStreamingFor?.includes(toolName);\n\n\t\tif (!shouldStream && ENABLE_STREAM_DEBUG_LOGS) console.warn('SUPPRESSING TOOL EVENT: ' + toolName);\n\n\t\treturn shouldStream;\n\t}\n\n\tprivate isReasoningMessage(message: BaseMessage): boolean {\n\t\tif (!Array.isArray(message.content)) return false;\n\t\treturn (message.content as any[]).some((block) => block.type === 'reasoning' && block.reasoning);\n\t}\n\n\tprivate isArrayTextMessage(message: BaseMessage): boolean {\n\t\tif (!Array.isArray(message.content)) return false;\n\t\treturn (message.content as any[]).some((block) => block.type === 'text' && block.text);\n\t}\n\n\t/**\n\t * Extracts text from message content that may be a string\n\t * or an array of content blocks (as returned by reasoning models).\n\t */\n\tprivate extractTextContent(content: any): string {\n\t\tif (typeof content === 'string') return content;\n\n\t\tif (Array.isArray(content)) {\n\t\t\treturn content\n\t\t\t\t.filter((block) => block.type === 'text' && block.text)\n\t\t\t\t.map((block) => block.text)\n\t\t\t\t.join('');\n\t\t}\n\n\t\treturn content.toString();\n\t}\n}\n","import { Message } from '@core/agent.interface';\nimport { AIMessage, BaseMessage, HumanMessage, ToolMessage } from 'langchain';\n\nexport function convertToLangchainMessages(messages: Message[]): BaseMessage[] {\n\tconst result: BaseMessage[] = [];\n\tlet tcIdx = 0;\n\tlet pendingToolCallIds: string[] = [];\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === 'human') {\n\t\t\tresult.push(\n\t\t\t\tnew HumanMessage({\n\t\t\t\t\tcontent: msg.content.map((c) => {\n\t\t\t\t\t\tif (c.type === 'image') {\n\t\t\t\t\t\t\treturn { type: 'image_url', image_url: { url: c.url } };\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn c;\n\t\t\t\t\t}) as any,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (msg.role === 'ai') {\n\t\t\tif (msg.toolCalls && msg.toolCalls.length > 0) {\n\t\t\t\tpendingToolCallIds = msg.toolCalls.map(() => `tc_${++tcIdx}`);\n\t\t\t\tresult.push(\n\t\t\t\t\tnew AIMessage({\n\t\t\t\t\t\tcontent: msg.content,\n\t\t\t\t\t\ttool_calls: msg.toolCalls.map((tc, i) => ({\n\t\t\t\t\t\t\tid: pendingToolCallIds[i],\n\t\t\t\t\t\t\tname: tc.name,\n\t\t\t\t\t\t\targs: tc.input ? JSON.parse(tc.input) : {},\n\t\t\t\t\t\t})),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tresult.push(new AIMessage(msg.content));\n\t\t\t}\n\t\t} else if (msg.role === 'tool') {\n\t\t\tconst toolCallId = pendingToolCallIds.shift();\n\t\t\tif (!toolCallId)\n\t\t\t\tthrow new Error(`ToolMessage for \"${msg.name}\" without a preceding AiMessage with toolCalls`);\n\t\t\tresult.push(\n\t\t\t\tnew ToolMessage({\n\t\t\t\t\tcontent: msg.output,\n\t\t\t\t\ttool_call_id: toolCallId,\n\t\t\t\t\tname: msg.name,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';\nimport { ReasoningEffort } from 'openai/resources';\n\nexport type LangchainOpenAIConfig = {\n\tapiKey: string;\n};\n\nexport type LangchainAzureResourceConfig = {\n\tapiKey: string;\n\tendpoint: string;\n\tmodels: {\n\t\tmodel: string;\n\t\tapiVersion: string;\n\t\tdeploymentName: string;\n\t}[];\n};\n\nexport type ResourceName = string;\n\nexport type LangchainModelConfig = {\n\topenai?: Record<string, LangchainOpenAIConfig>;\n\tazure?: Record<ResourceName, LangchainAzureResourceConfig>;\n};\n\nexport class LangchainModelResolver {\n\tconstructor(private config: LangchainModelConfig) {}\n\n\tresolve(modelString: string, tags?: string[], reasoningEffort?: ReasoningEffort): BaseLanguageModel {\n\t\tconst parts = modelString.split(':');\n\n\t\tif (parts.length === 2) {\n\t\t\tconst [provider, modelName] = parts;\n\t\t\treturn this.resolveByProvider(provider, 'default', modelName, tags, reasoningEffort);\n\t\t}\n\n\t\tif (parts.length === 3) {\n\t\t\tconst [provider, configName, modelName] = parts;\n\t\t\treturn this.resolveByProvider(provider, configName, modelName, tags, reasoningEffort);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t'Model string must follow format \"provider:modelName\" (uses \"default\" config) or \"provider:configName:modelName\"',\n\t\t);\n\t}\n\n\tprivate resolveByProvider(\n\t\tprovider: string,\n\t\tconfigName: string,\n\t\tmodelName: string,\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): BaseLanguageModel {\n\t\tswitch (provider) {\n\t\t\tcase 'openai':\n\t\t\t\treturn this.resolveOpenAI(configName, modelName, tags, reasoningEffort);\n\t\t\tcase 'azure':\n\t\t\t\treturn this.resolveAzure(configName, modelName, tags, reasoningEffort);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model provider: ${provider}`);\n\t\t}\n\t}\n\n\tprivate resolveOpenAI(\n\t\tconfigName: string,\n\t\tmodelName: string,\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): ChatOpenAI {\n\t\tconst providerConfig = this.config.openai?.[configName];\n\t\tif (!providerConfig) {\n\t\t\tthrow new Error(`Configuration \"${configName}\" for provider \"openai\" is missing`);\n\t\t}\n\n\t\treturn new ChatOpenAI({\n\t\t\tapiKey: providerConfig.apiKey,\n\t\t\tmodelName: modelName,\n\t\t\ttags: tags,\n\t\t\t...(reasoningEffort && {\n\t\t\t\treasoning: {\n\t\t\t\t\teffort: reasoningEffort,\n\t\t\t\t\tsummary: 'auto',\n\t\t\t\t},\n\t\t\t\tuseResponsesApi: true,\n\t\t\t}),\n\t\t});\n\t}\n\n\tprivate resolveAzure(\n\t\tresourceName: string,\n\t\tmodelName: string,\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): BaseLanguageModel {\n\t\tconst resource = this.config.azure?.[resourceName];\n\t\tif (!resource) {\n\t\t\tthrow new Error(`Resource \"${resourceName}\" for provider \"azure\" is missing`);\n\t\t}\n\n\t\tconst modelEntry = resource.models.find((m) => m.model === modelName);\n\t\tif (!modelEntry) {\n\t\t\tthrow new Error(`Model \"${modelName}\" not found in Azure resource \"${resourceName}\"`);\n\t\t}\n\n\t\t/**\n\t\t * Reasoning models require the Responses API which AzureChatOpenAI\n\t\t * does not support. We use ChatOpenAI with the Azure Responses API\n\t\t * endpoint as the baseURL instead.\n\t\t */\n\t\tif (reasoningEffort) {\n\t\t\tconst responsesBaseURL = `${resource.endpoint.replace(/\\/$/, '')}/openai/responses?api-version=${modelEntry.apiVersion}`;\n\n\t\t\treturn new AzureChatOpenAI({\n\t\t\t\tmodel: modelEntry.model,\n\t\t\t\tazureOpenAIApiKey: resource.apiKey,\n\t\t\t\tazureOpenAIEndpoint: responsesBaseURL,\n\t\t\t\tazureOpenAIApiDeploymentName: modelEntry.deploymentName,\n\t\t\t\tazureOpenAIApiVersion: modelEntry.apiVersion,\n\t\t\t\ttags: tags,\n\t\t\t\t...(reasoningEffort && {\n\t\t\t\t\treasoning: {\n\t\t\t\t\t\teffort: reasoningEffort,\n\t\t\t\t\t\tsummary: 'auto',\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\n\t\treturn new AzureChatOpenAI({\n\t\t\tmodel: modelEntry.model,\n\t\t\tazureOpenAIApiKey: resource.apiKey,\n\t\t\tazureOpenAIEndpoint: resource.endpoint,\n\t\t\tazureOpenAIApiDeploymentName: modelEntry.deploymentName,\n\t\t\tazureOpenAIApiVersion: modelEntry.apiVersion,\n\t\t\ttags: tags,\n\t\t});\n\t}\n\n\tprivate extractInstanceName(endpoint: string): string {\n\t\ttry {\n\t\t\tconst url = new URL(endpoint);\n\t\t\treturn url.hostname.split('.')[0];\n\t\t} catch (e) {\n\t\t\treturn endpoint;\n\t\t}\n\t}\n}\n","import { ToolDefinition, ToolSpec } from '@core/agent.interface';\nimport { ToolProvider } from './tool-provider';\nimport { ToolCache } from '@core/tools/tool-cache';\n\ntype ProviderEntry<TContext> = {\n\ttype: 'provider';\n\tprovider: ToolProvider<TContext>;\n};\n\ntype StaticEntry = {\n\ttype: 'static';\n\ttools: ToolDefinition[];\n};\n\ntype Entry<TContext> = ProviderEntry<TContext> | StaticEntry;\n\nexport interface ToolRegistryOptions {\n\t/**\n\t * Shared cache for tool specs (e.g. Redis). Values are stored as JSON strings.\n\t */\n\ttoolSpecCache?: ToolCache;\n}\n\nexport class ToolRegistry<TContext> {\n\tprivate entries = new Map<string, Entry<TContext>>();\n\tprivate toolSpecCache?: ToolCache;\n\n\tconstructor(options: ToolRegistryOptions = {}) {\n\t\tthis.toolSpecCache = options.toolSpecCache;\n\t}\n\n\tregisterProvider(toolKit: string, provider: ToolProvider<TContext>): void {\n\t\tthis.entries.set(toolKit, { type: 'provider', provider });\n\t}\n\n\tregisterTools(toolKit: string, tools: ToolDefinition[]): void {\n\t\tthis.entries.set(toolKit, { type: 'static', tools });\n\t}\n\n\tasync getTools(toolKits: string[], context: TContext): Promise<ToolDefinition[]> {\n\t\tconst results: ToolDefinition[] = [];\n\n\t\tfor (const kit of toolKits) {\n\t\t\tconst entry = this.entries.get(kit);\n\t\t\tif (!entry) {\n\t\t\t\tthrow new Error(`No tools or provider registered for tool kit: ${kit}`);\n\t\t\t}\n\n\t\t\tif (entry.type === 'static') {\n\t\t\t\tresults.push(...entry.tools);\n\t\t\t} else {\n\t\t\t\tconst provider = entry.provider;\n\t\t\t\tconst specs = await this.getToolKitSpecs(kit, provider, context);\n\t\t\t\tconst tools = await provider.bindTools(specs, context);\n\t\t\t\tresults.push(...tools);\n\t\t\t}\n\t\t}\n\n\t\treturn results;\n\t}\n\n\tinvalidate(toolKit: string): void {\n\t\tconst entry = this.entries.get(toolKit);\n\n\t\tif (entry && entry.type === 'provider') this.toolSpecCache?.del(toolKit);\n\t}\n\n\tprivate async getToolKitSpecs(\n\t\ttoolKit: string,\n\t\tprovider: ToolProvider<TContext>,\n\t\tcontext: TContext,\n\t): Promise<ToolSpec[]> {\n\t\tconst cache = this.toolSpecCache;\n\n\t\tif (cache) {\n\t\t\ttry {\n\t\t\t\tconst cached = await cache.get(toolKit);\n\n\t\t\t\tif (cached) return cached;\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Something went wrong when hitting the cache', e);\n\t\t\t}\n\t\t}\n\n\t\tconst specs = (await provider.listToolKitSpecs(toolKit, context)) ?? [];\n\n\t\tif (cache) {\n\t\t\ttry {\n\t\t\t\tawait cache.set(toolKit, specs);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Something went wrong when setting the cache', e);\n\t\t\t}\n\t\t}\n\n\t\treturn specs;\n\t}\n}\n","import { ToolSpec } from '@core/agent.interface';\nimport Redis from 'ioredis';\nimport { z } from 'zod';\n\nexport interface ToolCache {\n\tget(toolKit: string): Promise<ToolSpec[] | null> | ToolSpec[] | null;\n\n\tset(toolKit: string, specs: ToolSpec[]): Promise<void>;\n\n\tdel(toolKit: string): Promise<void>;\n}\n\nexport class RedisToolCache implements ToolCache {\n\tprivate redis: Redis;\n\n\tconstructor(connectionString: string) {\n\t\tthis.redis = new Redis(connectionString);\n\t}\n\n\tasync get(toolKit: string): Promise<ToolSpec[] | null> {\n\t\tconst data = await this.redis.get(`tool-cache:${toolKit}`);\n\n\t\tif (!data) return null;\n\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(data);\n\n\t\t\tif (!Array.isArray(parsed)) return null;\n\n\t\t\treturn parsed.map((spec: any) => ({\n\t\t\t\t...spec,\n\t\t\t\tinputSchema: z.fromJSONSchema(spec.inputSchema),\n\t\t\t}));\n\t\t} catch (e) {\n\t\t\tconsole.error('Failed to parse cached tools', e);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync set(toolKit: string, specs: ToolSpec[]): Promise<void> {\n\t\tconst serialized = specs.map((spec) => ({\n\t\t\t...spec,\n\t\t\tinputSchema: spec.inputSchema.toJSONSchema(),\n\t\t}));\n\t\tawait this.redis.set(`tool-cache:${toolKit}`, JSON.stringify(serialized));\n\t}\n\n\tasync del(toolKit: string): Promise<void> {\n\t\tawait this.redis.del(`tool-cache:${toolKit}`);\n\t}\n}\n\nexport class InMemoryToolCache implements ToolCache {\n\tprivate cache = new Map<string, ToolSpec[]>();\n\n\tget(toolKit: string): ToolSpec[] | null {\n\t\treturn this.cache.get(`tool-cache:${toolKit}`) ?? null;\n\t}\n\n\tasync set(toolKit: string, specs: ToolSpec[]): Promise<void> {\n\t\tthis.cache.set(`tool-cache:${toolKit}`, specs);\n\t}\n\n\tasync del(toolKit: string): Promise<void> {\n\t\tthis.cache.delete(`tool-cache:${toolKit}`);\n\t}\n}\n"],"mappings":"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","names":["import_deepagents","import_langchain","import_langchain","input","tool","options","Redis"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/runtime/langchain/factory.ts","../src/runtime/langchain/agent.ts","../src/runtime/langchain/utils.ts","../src/runtime/langchain/model-resolver.ts","../src/core/tools/tool-registry.ts","../src/core/tools/tool-cache.ts"],"sourcesContent":["// Core Interfaces & Factory\nexport { AgentFactory, CreateAgentOptions, AgentHandoff } from './core/agent.factory';\nexport {\n\tAgent,\n\tAgentRunInput,\n\tAgentResult,\n\tMessage,\n\tHumanMessage,\n\tAiMessage,\n\tToolMessage,\n\tContentBlock,\n\tUsageMeta,\n\tToolSpec,\n\tToolDefinition,\n\tToolCall,\n\tStreamEvent,\n} from './core/agent.interface';\nexport { LangchainAgentFactory } from './runtime/langchain/factory';\nexport { type LangchainModelConfig } from './runtime/langchain/model-resolver';\n\n// Tools\nexport { ToolRegistry } from './core/tools/tool-registry';\nexport { ToolProvider } from './core/tools/tool-provider';\nexport { ToolCache, RedisToolCache, InMemoryToolCache } from './core/tools/tool-cache';\n","import { AgentFactory, CreateAgentOptions } from '@core/agent.factory';\nimport { Agent } from '@core/agent.interface';\nimport { PostgresSaver } from '@langchain/langgraph-checkpoint-postgres';\n// @ts-ignore -_-\nimport { PostgresStore } from '@langchain/langgraph-checkpoint-postgres/store';\nimport { CompositeBackend, StateBackend, StoreBackend } from 'deepagents';\nimport { AgentMiddleware, llmToolSelectorMiddleware, summarizationMiddleware, tool } from 'langchain';\nimport { CreateOptions, LangchainAgent } from './agent';\nimport { LangchainModelConfig, LangchainModelResolver } from './model-resolver';\n\nexport interface PostgresSaverConfig {\n\tconnString: string;\n\tschema: string;\n}\n\nexport interface PostgresStoreConfig {\n\tconnString: string;\n\tschema: string;\n}\n\nexport class LangchainAgentFactory implements AgentFactory {\n\tprivate modelResolver: LangchainModelResolver;\n\n\tconstructor(\n\t\tprivate modelConfig: LangchainModelConfig,\n\t\tprivate saverConfig: PostgresSaverConfig,\n\t\tprivate storeConfig: PostgresStoreConfig,\n\t) {\n\t\tthis.modelResolver = new LangchainModelResolver(this.modelConfig);\n\t}\n\n\tprivate buildMemorySystemPrompt(slots: { name: string; usedFor: string }[]): string {\n\t\tconst lines = [\n\t\t\t'Long-term memory is enabled.',\n\t\t\t'Persist memories using the filesystem tools under these path prefixes:',\n\t\t\t...slots.map((slot) => {\n\t\t\t\tconst prefix = this.normalizeStoreRoutePrefix(slot.name);\n\t\t\t\treturn `- ${prefix}: ${slot.usedFor}`;\n\t\t\t}),\n\t\t];\n\n\t\treturn lines.join('\\n');\n\t}\n\n\tprivate buildHandoffsSystemPrompt(handoffs: { name: string; description: string }[]): string {\n\t\tconst lines = [\n\t\t\t'You can delegate tasks to the following subagents:',\n\t\t\t...handoffs.map((handoff) => `- ${handoff.name}: ${handoff.description}`),\n\t\t];\n\n\t\treturn lines.join('\\n');\n\t}\n\n\tprivate normalizeStoreRoutePrefix(prefix: string): string {\n\t\tconst trimmedPrefix = prefix.trim();\n\t\tif (trimmedPrefix.length === 0) {\n\t\t\tthrow new Error('Memory slot name cannot be empty');\n\t\t}\n\n\t\tconst withLeadingSlash = trimmedPrefix.startsWith('/') ? trimmedPrefix : `/${trimmedPrefix}`;\n\t\treturn withLeadingSlash.endsWith('/') ? withLeadingSlash : `${withLeadingSlash}/`;\n\t}\n\n\tasync createAgent(options: CreateAgentOptions): Promise<Agent> {\n\t\tlet deepAgentOptions: CreateOptions = {\n\t\t\tmodel: this.modelResolver.resolve(options.model, [], options.reasoning),\n\t\t};\n\n\t\tlet middlewares: AgentMiddleware[] = [];\n\t\tlet systemPrompt = options.instructions ?? '';\n\t\tlet disableStreamingForTools: string[] = [\n\t\t\t'write_todos',\n\t\t\t'ls',\n\t\t\t'read_file',\n\t\t\t'write_file',\n\t\t\t'edit_file',\n\t\t\t'glob',\n\t\t\t'grep',\n\t\t\t'task',\n\t\t];\n\t\tlet disableReportingForTools: string[] = disableStreamingForTools;\n\t\tlet disableModelStreamingFor: string[] = [];\n\n\t\tif (options.history) {\n\t\t\tconst checkpointer = PostgresSaver.fromConnString(this.saverConfig.connString, {\n\t\t\t\tschema: this.saverConfig.schema,\n\t\t\t});\n\n\t\t\tawait checkpointer.setup();\n\n\t\t\tdeepAgentOptions.checkpointer = checkpointer;\n\t\t}\n\n\t\tif (options.memory) {\n\t\t\tconst memorySystemPrompt = this.buildMemorySystemPrompt(options.memory.slots);\n\t\t\tsystemPrompt = systemPrompt ? `${systemPrompt}\\n\\n${memorySystemPrompt}` : memorySystemPrompt;\n\n\t\t\tdeepAgentOptions.store = new PostgresStore({\n\t\t\t\tconnectionOptions: this.storeConfig.connString,\n\t\t\t\tschema: this.storeConfig.schema,\n\t\t\t\tensureTables: true,\n\t\t\t});\n\t\t\t/**\n\t\t\t * StateBackend for ephemeral storage\n\t\t\t * StoreBackend for persistent storage\n\t\t\t */\n\t\t\tdeepAgentOptions.backend = (config) => {\n\t\t\t\tconst configWithAssistantId = { ...config, assistantId: options.memory?.assistantId };\n\t\t\t\tconst storeBackend = new StoreBackend(configWithAssistantId);\n\t\t\t\tconst routes = Object.fromEntries(\n\t\t\t\t\t(options.memory?.slots ?? []).map((slot) => {\n\t\t\t\t\t\tconst routePrefix = this.normalizeStoreRoutePrefix(slot.name);\n\t\t\t\t\t\treturn [routePrefix, storeBackend];\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\treturn new CompositeBackend(new StateBackend(configWithAssistantId), {\n\t\t\t\t\t...routes,\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\tif (options.tools) {\n\t\t\tdeepAgentOptions.tools = options.tools.tools.map((t) =>\n\t\t\t\ttool(\n\t\t\t\t\tasync (input, options) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst res = await t.exec(input);\n\n\t\t\t\t\t\t\tif (typeof res === 'string') return res;\n\n\t\t\t\t\t\t\treturn JSON.stringify(res);\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tconsole.error('Error executing tool:', e);\n\t\t\t\t\t\t\treturn 'Something went wrong while executing the tool.';\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: t.name,\n\t\t\t\t\t\tdescription: t.description,\n\t\t\t\t\t\tschema: t.inputSchema,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\ttoolKit: t.toolKit,\n\t\t\t\t\t\t\ttoolKitIconUrl: t.toolKitIconUrl,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t\tmiddlewares.push(\n\t\t\t\tllmToolSelectorMiddleware({\n\t\t\t\t\tmodel: this.modelResolver.resolve(options.tools.model, ['tool-selector']),\n\t\t\t\t\tmaxTools: 128,\n\t\t\t\t\talwaysInclude: options.tools.alwaysIncludeTools ?? undefined,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tdisableModelStreamingFor.push('tool-selector');\n\t\t}\n\n\t\tif (options.summarization)\n\t\t\tmiddlewares.push(\n\t\t\t\tsummarizationMiddleware({\n\t\t\t\t\tmodel: this.modelResolver.resolve(options.summarization.model),\n\t\t\t\t\ttrigger: {\n\t\t\t\t\t\ttokens: options.summarization.triggerAtTokens,\n\t\t\t\t\t},\n\t\t\t\t\tkeep: {\n\t\t\t\t\t\tmessages: options.summarization.keepMessages,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\n\t\tif (options.handoffs) {\n\t\t\toptions.handoffs.every((h) => {\n\t\t\t\tif (!(h.agent instanceof LangchainAgent)) {\n\t\t\t\t\tthrow new Error('Handoff agent must be an instance of LangchainAgent');\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst handoffsSystemPrompt = this.buildHandoffsSystemPrompt(options.handoffs);\n\t\t\tsystemPrompt = systemPrompt ? `${systemPrompt}\\n\\n${handoffsSystemPrompt}` : handoffsSystemPrompt;\n\n\t\t\tdeepAgentOptions.subagents = options.handoffs.map((h) => {\n\t\t\t\treturn {\n\t\t\t\t\tname: h.name,\n\t\t\t\t\tdescription: h.description,\n\t\t\t\t\trunnable: (h.agent as LangchainAgent).getLangchainAgent(),\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\tif (middlewares.length > 0) deepAgentOptions.middleware = middlewares;\n\n\t\tif (systemPrompt) deepAgentOptions.systemPrompt = systemPrompt;\n\n\t\tdeepAgentOptions.disableModelStreamingFor = disableModelStreamingFor;\n\t\tdeepAgentOptions.disableToolReportingFor = disableReportingForTools;\n\t\tdeepAgentOptions.disableToolStreamingFor = disableStreamingForTools;\n\n\t\treturn new LangchainAgent(deepAgentOptions);\n\t}\n}\n","import {\n\tAgent,\n\tAgentResult,\n\tAgentRunInput,\n\tContentBlock,\n\tStreamEvent,\n\tToolCall,\n\tUsageMeta,\n} from '@core/agent.interface';\nimport { ToolCallChunk, ToolMessage } from '@langchain/core/messages';\nimport { Command } from '@langchain/langgraph';\nimport { createDeepAgent, CreateDeepAgentParams } from 'deepagents';\nimport { AgentMiddleware, AIMessageChunk, BaseMessage, createMiddleware, ReactAgent, StructuredTool } from 'langchain';\nimport { convertToLangchainMessages } from './utils';\n\nconst ENABLE_STREAM_DEBUG_LOGS = false;\n\nfunction debugLogStream(type: StreamEvent['type'], text: string) {\n\tif (!ENABLE_STREAM_DEBUG_LOGS) return;\n\n\tconsole.warn(`${type}: ${text}`);\n}\n\nexport interface CreateOptions extends CreateDeepAgentParams {\n\t/**\n\t * Tool names to disable streaming for\n\t */\n\tdisableToolStreamingFor?: string[];\n\n\t/**\n\t * Tool names to disable streaming for\n\t */\n\tdisableToolReportingFor?: string[];\n\n\t/**\n\t * Model tags to disable streaming for\n\t */\n\tdisableModelStreamingFor?: string[];\n}\n\nexport class LangchainAgent implements Agent {\n\tprivate deepAgent: ReactAgent;\n\tprivate toolCalls: ToolCall[] = [];\n\tprivate tools?: StructuredTool[];\n\n\tconstructor(private params: CreateOptions) {\n\t\tthis.tools = params.tools;\n\n\t\tif (!params.disableModelStreamingFor) params.disableModelStreamingFor = [];\n\t\tif (!params.disableToolReportingFor) params.disableToolReportingFor = [];\n\t\tif (!params.disableToolStreamingFor) params.disableToolStreamingFor = [];\n\n\t\tlet middlewares: AgentMiddleware[] = [\n\t\t\tcreateMiddleware({\n\t\t\t\tname: 'toolCallsReporter',\n\t\t\t\twrapToolCall: async (request, handler) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst res = await handler(request);\n\n\t\t\t\t\t\tif (this.params.disableToolReportingFor?.includes(request.tool?.name as string)) return res;\n\n\t\t\t\t\t\tthis.toolCalls.push({\n\t\t\t\t\t\t\tid: request.toolCall.id as string,\n\t\t\t\t\t\t\tname: (request.tool?.name as string) || '',\n\t\t\t\t\t\t\tinput: request.toolCall.args,\n\t\t\t\t\t\t\toutput: res.toJSON(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Wrapped tool may sometimes return Command objects\n\t\t\t\t\t\t * which should actually trigger the \"updates\" mode\n\t\t\t\t\t\t * of stream. But we don't want that to happen. We\n\t\t\t\t\t\t * want to emit tool_result events from a single place.\n\t\t\t\t\t\t * So we extract the tool message from the update and\n\t\t\t\t\t\t * command.update.messages and return that. That way\n\t\t\t\t\t\t * 'messages' stream mode is triggered\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Hopefully this won't cause any issues.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (res instanceof Command) {\n\t\t\t\t\t\t\tconst resCast: {\n\t\t\t\t\t\t\t\tupdate?: {\n\t\t\t\t\t\t\t\t\tmessages?: BaseMessage[];\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t} = res as any;\n\n\t\t\t\t\t\t\tif (!resCast.update?.messages || resCast.update.messages.length == 0) return res;\n\n\t\t\t\t\t\t\tconst toolMessage = resCast.update.messages.find((m: BaseMessage) => m.type == 'tool');\n\n\t\t\t\t\t\t\tif (!toolMessage) return res;\n\n\t\t\t\t\t\t\treturn toolMessage as ToolMessage;\n\t\t\t\t\t\t} else return res;\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\treturn new ToolMessage({\n\t\t\t\t\t\t\tname: request.toolCall.name,\n\t\t\t\t\t\t\tcontent: 'Something went wrong: ' + e.message,\n\t\t\t\t\t\t\ttool_call_id: request.toolCall.id || 'TOOL_CALL_ERROR',\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\n\t\tif (params.middleware) middlewares = [...middlewares, ...params.middleware];\n\n\t\tparams.middleware = middlewares;\n\n\t\tthis.deepAgent = createDeepAgent(params);\n\t}\n\n\tasync run(input: AgentRunInput): Promise<AgentResult> {\n\t\tthis.toolCalls = []; // Reset tool calls for each run\n\n\t\t// Get current state to know how many messages existed before this turn\n\t\t// If no checkpointer is set, assume this is a fresh conversation\n\t\tlet messageCountBefore = 0;\n\t\ttry {\n\t\t\tconst stateBefore = await this.deepAgent.getState({\n\t\t\t\tconfigurable: {\n\t\t\t\t\tthreadId: input.threadId,\n\t\t\t\t\tthread_id: input.threadId,\n\t\t\t\t},\n\t\t\t});\n\t\t\tmessageCountBefore = (stateBefore as any)?.values?.messages?.length || 0;\n\t\t} catch {\n\t\t\t// No checkpointer set - this is fine, we'll count from 0\n\t\t}\n\n\t\tconst messages = convertToLangchainMessages(input.messages);\n\n\t\tconst result = await this.deepAgent.invoke(\n\t\t\t{\n\t\t\t\tmessages: messages,\n\t\t\t},\n\t\t\t{\n\t\t\t\tconfigurable: {\n\t\t\t\t\tthreadId: input.threadId,\n\t\t\t\t\tthread_id: input.threadId,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\t// Only sum usage from messages added in this turn\n\t\tconst newMessages = result.messages.slice(messageCountBefore);\n\t\tconst messagesWithUsage = newMessages.filter((m: any) => m.usage_metadata != null);\n\n\t\tlet usage = {\n\t\t\tinput_tokens: 0,\n\t\t\toutput_tokens: 0,\n\t\t\ttotal_tokens: 0,\n\t\t\tcache_read: 0,\n\t\t\treasoning_tokens: 0,\n\t\t\tcache_creation: 0,\n\t\t};\n\n\t\tmessagesWithUsage.forEach((m: any) => {\n\t\t\tconst cacheRead = m.usage_metadata.input_token_details?.cache_read || 0;\n\t\t\tconst provider = m.response_metadata?.model_provider;\n\n\t\t\t// Anthropic reports input_tokens excluding cached tokens;\n\t\t\t// OpenAI (and unknown providers) include cached tokens in input_tokens\n\t\t\tconst inputTokens =\n\t\t\t\tprovider === 'anthropic'\n\t\t\t\t\t? m.usage_metadata.input_tokens || 0\n\t\t\t\t\t: (m.usage_metadata.input_tokens || 0) - cacheRead;\n\n\t\t\tusage.input_tokens += inputTokens;\n\t\t\tusage.output_tokens += m.usage_metadata.output_tokens || 0;\n\t\t\tusage.total_tokens += inputTokens + (m.usage_metadata.output_tokens || 0);\n\t\t\tusage.cache_read += cacheRead;\n\t\t\tusage.reasoning_tokens += m.usage_metadata.output_token_details?.reasoning || 0;\n\t\t\tusage.cache_creation += m.usage_metadata.input_token_details?.cache_creation || 0;\n\t\t});\n\n\t\t// Build content blocks from new messages\n\t\tconst contentBlocks: ContentBlock[] = [];\n\t\tconst toolCallInputs: { [toolCallId: string]: any } = {};\n\n\t\tfor (const msg of newMessages) {\n\t\t\tconst m = msg as any;\n\t\t\tif (m.type === 'ai') {\n\t\t\t\t// Store tool call inputs for later pairing\n\t\t\t\tif (m.tool_calls && m.tool_calls.length > 0) {\n\t\t\t\t\tfor (const tc of m.tool_calls) {\n\t\t\t\t\t\ttoolCallInputs[tc.id] = tc.args;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Add text content if present\n\t\t\t\tif (m.content) {\n\t\t\t\t\tconst textOutput = this.extractTextContent(m.content);\n\t\t\t\t\tif (textOutput.trim().length > 0) {\n\t\t\t\t\t\tcontentBlocks.push({\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\toutput: textOutput,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (m.type === 'tool') {\n\t\t\t\tcontentBlocks.push({\n\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\tname: m.name,\n\t\t\t\t\ttoolKit: this.getToolKitMeta(m.name).toolKit,\n\t\t\t\t\ttoolKitIconUrl: this.getToolKitMeta(m.name).toolKitIconUrl,\n\t\t\t\t\tinput: JSON.stringify(toolCallInputs[m.tool_call_id] || {}),\n\t\t\t\t\toutput: m.content.toString(),\n\t\t\t\t\ttoolCallId: m.tool_call_id,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: contentBlocks,\n\t\t\ttoolCalls: this.toolCalls,\n\t\t\tusage: {\n\t\t\t\tpromptTokens: usage.input_tokens,\n\t\t\t\tcompletionTokens: usage.output_tokens,\n\t\t\t\ttotalTokens: usage.total_tokens,\n\t\t\t\tcachedPromptTokens: usage.cache_read,\n\t\t\t\treasoningTokens: usage.reasoning_tokens,\n\t\t\t\tcacheCreationTokens: usage.cache_creation,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync *stream(input: AgentRunInput): AsyncGenerator<StreamEvent> {\n\t\tthis.toolCalls = []; // Reset tool calls for each stream\n\t\tconst contentBlocks: ContentBlock[] = []; // this will be our final return value\n\t\tlet finalValue;\n\n\t\t// Initialize usage metadata - accumulated from updates mode (current turn only)\n\t\tlet usageMetadata: UsageMeta = {\n\t\t\tpromptTokens: 0,\n\t\t\tcompletionTokens: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcachedPromptTokens: 0,\n\t\t\treasoningTokens: 0,\n\t\t\tcacheCreationTokens: 0,\n\t\t};\n\n\t\tconst messages = convertToLangchainMessages(input.messages);\n\n\t\tdebugLogStream('message_start', '');\n\n\t\t// Emit message start\n\t\tyield { type: 'message_start' };\n\n\t\tconst stream = await this.deepAgent.stream(\n\t\t\t{ messages },\n\t\t\t{\n\t\t\t\tconfigurable: {\n\t\t\t\t\tthreadId: input.threadId,\n\t\t\t\t\tthread_id: input.threadId,\n\t\t\t\t},\n\t\t\t\tstreamMode: ['messages', 'updates', 'values'],\n\t\t\t},\n\t\t);\n\n\t\tlet toolCalls: {\n\t\t\t[index: number]: {\n\t\t\t\ttoolCallId: string;\n\t\t\t\tname: string;\n\t\t\t};\n\t\t} = {};\n\t\tconst toolCallUpdates: {\n\t\t\t[toolCallId: string]: {\n\t\t\t\tname: string;\n\t\t\t\targs: any;\n\t\t\t};\n\t\t} = {};\n\n\t\t/**\n\t\t * Process chunks produced by the LLM\n\t\t */\n\t\tfor await (const chunk of stream) {\n\t\t\tconst [mode, data] = chunk;\n\n\t\t\tif (mode === 'messages') {\n\t\t\t\tconst [message, metadata] = data;\n\n\t\t\t\t/**\n\t\t\t\t * Some messages carry no meaningful information\n\t\t\t\t */\n\t\t\t\tif (this.shouldIgnoreMessage(message, metadata)) continue;\n\n\t\t\t\t/**\n\t\t\t\t * LLMs also stream the tool input tokens. If we see\n\t\t\t\t * tool_call_chunks inside the message, we know it's\n\t\t\t\t * a token stream for a tool call.\n\t\t\t\t */\n\t\t\t\tif (this.isToolCallMessage(message)) {\n\t\t\t\t\tconst aiMessage = message as AIMessageChunk;\n\t\t\t\t\tconst toolCallChunks = aiMessage.tool_call_chunks as ToolCallChunk[];\n\n\t\t\t\t\tfor (const toolChunk of toolCallChunks) {\n\t\t\t\t\t\tconst toolCallIndex = toolChunk.index as number;\n\n\t\t\t\t\t\tconst getToolCallInfo = () => {\n\t\t\t\t\t\t\treturn toolCalls[toolCallIndex];\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * On the first chunk, we get the tool name in\n\t\t\t\t\t\t * chunk.id. On sequential chunks this property\n\t\t\t\t\t\t * is set to defined. So if there is id in the\n\t\t\t\t\t\t * chunk; this is a tool_start event.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Also different tool calls are separated using\n\t\t\t\t\t\t * the \"index\" property. This exists in all tool\n\t\t\t\t\t\t * chunk messages.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (toolChunk.id) {\n\t\t\t\t\t\t\ttoolCalls[toolChunk.index as number] = {\n\t\t\t\t\t\t\t\ttoolCallId: toolChunk.id,\n\t\t\t\t\t\t\t\tname: toolChunk.name as string,\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tif (!this.shouldStreamToolEvent(getToolCallInfo().name)) continue;\n\n\t\t\t\t\t\t\tconst toolKitMeta = this.getToolKitMeta(getToolCallInfo().name);\n\n\t\t\t\t\t\t\tdebugLogStream('tool_start', `[${getToolCallInfo().toolCallId}] ${getToolCallInfo().name}`);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'tool_start',\n\t\t\t\t\t\t\t\tname: getToolCallInfo().name,\n\t\t\t\t\t\t\t\ttoolKit: toolKitMeta.toolKit,\n\t\t\t\t\t\t\t\ttoolKitIconUrl: toolKitMeta.toolKitIconUrl,\n\t\t\t\t\t\t\t\tindex: toolCallIndex,\n\t\t\t\t\t\t\t\ttoolCallId: getToolCallInfo().toolCallId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (toolChunk.args && toolChunk.args.length > 0) {\n\t\t\t\t\t\t\tif (!this.shouldStreamToolEvent(getToolCallInfo().name)) continue;\n\n\t\t\t\t\t\t\tdebugLogStream('tool_input_delta', `[${getToolCallInfo().toolCallId}] ${toolChunk.args}`);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'tool_input_delta',\n\t\t\t\t\t\t\t\tname: getToolCallInfo().name,\n\t\t\t\t\t\t\t\targs: toolChunk.args || '',\n\t\t\t\t\t\t\t\tindex: toolCallIndex,\n\t\t\t\t\t\t\t\ttoolCallId: getToolCallInfo().toolCallId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isReasoningMessage(message)) {\n\t\t\t\t\tconst contentArray = message.content as any[];\n\t\t\t\t\tfor (const block of contentArray) {\n\t\t\t\t\t\tconst delta =\n\t\t\t\t\t\t\t(block.type === 'reasoning' && block.reasoning) ||\n\t\t\t\t\t\t\t(block.type === 'thinking' && block.thinking);\n\t\t\t\t\t\tif (delta) {\n\t\t\t\t\t\t\tdebugLogStream('reasoning_delta', delta);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'reasoning_delta',\n\t\t\t\t\t\t\t\tdelta,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isArrayTextMessage(message)) {\n\t\t\t\t\tconst contentArray = message.content as any[];\n\t\t\t\t\tfor (const block of contentArray) {\n\t\t\t\t\t\tif (block.type === 'text' && block.text) {\n\t\t\t\t\t\t\tdebugLogStream('text_delta', block.text);\n\n\t\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\t\ttype: 'text_delta',\n\t\t\t\t\t\t\t\tdelta: block.text,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (message?.content && typeof message.content === 'string') {\n\t\t\t\t\tconst content = message.content;\n\n\t\t\t\t\tif (content.length === 0) continue;\n\n\t\t\t\t\tif (message.type == 'tool') {\n\t\t\t\t\t\t// I know it's odd but ToolMessage.name seems to corelate to the tool name\n\t\t\t\t\t\tconst toolName = message.name as string;\n\t\t\t\t\t\tconst toolKitMeta = this.getToolKitMeta(toolName);\n\n\t\t\t\t\t\tconst toolCall = Object.entries(toolCalls).find(\n\t\t\t\t\t\t\t([_, value]) => value.toolCallId == (message as ToolMessage).tool_call_id,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!this.shouldStreamToolEvent(toolName)) continue;\n\n\t\t\t\t\t\tdebugLogStream('tool_result', `[${toolCall?.[1].toolCallId}] ${message.content}`);\n\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\ttype: 'tool_result',\n\t\t\t\t\t\t\tname: toolName,\n\t\t\t\t\t\t\tinput:\n\t\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t\tthis.toolCalls.find((tc) => tc.id == (toolCall as any)[1].toolCallId)?.input,\n\t\t\t\t\t\t\t\t) || '',\n\t\t\t\t\t\t\toutput: message.content,\n\t\t\t\t\t\t\ttoolKit: toolKitMeta.toolKit,\n\t\t\t\t\t\t\ttoolKitIconUrl: toolKitMeta.toolKitIconUrl,\n\t\t\t\t\t\t\tindex: toolCall?.[0] ? parseInt(toolCall[0]) : 99999,\n\t\t\t\t\t\t\ttoolCallId: toolCall?.[1] ? toolCall[1].toolCallId : 'NO_ID_FOUND',\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdebugLogStream('text_delta', content);\n\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\ttype: 'text_delta',\n\t\t\t\t\t\t\tdelta: content,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn('Unexpected messages stream chunk', chunk);\n\t\t\t\t}\n\t\t\t} else if (mode == 'updates') {\n\t\t\t\tconst update = data;\n\n\t\t\t\t/**\n\t\t\t\t * This is how we get the tool INPUTS and llm\n\t\t\t\t * tokens that'll be used in returned content\n\t\t\t\t * blocks\n\t\t\t\t */\n\t\t\t\tif (update.model_request?.messages) {\n\t\t\t\t\tconst aiMessageChunks: AIMessageChunk[] = update.model_request.messages.filter(\n\t\t\t\t\t\t(m) => m.type == 'ai',\n\t\t\t\t\t) as AIMessageChunk[];\n\n\t\t\t\t\tfor (let aiChunk of aiMessageChunks) {\n\t\t\t\t\t\t// Accumulate usage metadata from current turn's AI messages\n\t\t\t\t\t\tconst um = aiChunk.usage_metadata;\n\t\t\t\t\t\tif (um) {\n\t\t\t\t\t\t\tconst cacheRead = um.input_token_details?.cache_read || 0;\n\t\t\t\t\t\t\tconst provider = aiChunk.response_metadata?.model_provider;\n\n\t\t\t\t\t\t\t// Anthropic reports input_tokens excluding cached tokens;\n\t\t\t\t\t\t\t// OpenAI (and unknown providers) include cached tokens in input_tokens\n\t\t\t\t\t\t\tconst inputTokens =\n\t\t\t\t\t\t\t\tprovider === 'anthropic' ? um.input_tokens || 0 : (um.input_tokens || 0) - cacheRead;\n\n\t\t\t\t\t\t\tusageMetadata.promptTokens += inputTokens;\n\t\t\t\t\t\t\tusageMetadata.completionTokens += um.output_tokens || 0;\n\t\t\t\t\t\t\tusageMetadata.totalTokens += inputTokens + (um.output_tokens || 0);\n\t\t\t\t\t\t\tusageMetadata.cachedPromptTokens! += cacheRead;\n\t\t\t\t\t\t\tusageMetadata.reasoningTokens =\n\t\t\t\t\t\t\t\t(usageMetadata.reasoningTokens || 0) + (um.output_token_details?.reasoning || 0);\n\t\t\t\t\t\t\tusageMetadata.cacheCreationTokens! += um.input_token_details?.cache_creation || 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (aiChunk.tool_calls && aiChunk.tool_calls.length > 0) {\n\t\t\t\t\t\t\tfor (let tc of aiChunk.tool_calls)\n\t\t\t\t\t\t\t\ttoolCallUpdates[tc.id as string] = {\n\t\t\t\t\t\t\t\t\tname: tc.name,\n\t\t\t\t\t\t\t\t\targs: tc.args,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if (aiChunk.content) {\n\t\t\t\t\t\t\tconst textOutput = this.extractTextContent(aiChunk.content);\n\t\t\t\t\t\t\tif (textOutput.trim().length > 0)\n\t\t\t\t\t\t\t\tcontentBlocks.push({\n\t\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\t\toutput: textOutput,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * This is how we get the tool OUTPUTS that'll be\n\t\t\t\t * used in returned content blocks\n\t\t\t\t */\n\t\t\t\tif (update.tools?.messages) {\n\t\t\t\t\tconst toolMessages: ToolMessage[] = update.tools.messages.filter(\n\t\t\t\t\t\t(m) => m.type == 'tool',\n\t\t\t\t\t) as ToolMessage[];\n\n\t\t\t\t\tfor (let tm of toolMessages) {\n\t\t\t\t\t\tconst input = JSON.stringify(toolCallUpdates[tm.tool_call_id].args);\n\t\t\t\t\t\tconst toolCall = this.toolCalls.find((tc) => tc.id == tm.tool_call_id);\n\n\t\t\t\t\t\tif (this.shouldStreamToolEvent(tm.name as string))\n\t\t\t\t\t\t\tcontentBlocks.push({\n\t\t\t\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\t\t\t\tname: tm.name as string,\n\t\t\t\t\t\t\t\ttoolKit: this.getToolKitMeta(tm.name as string).toolKit,\n\t\t\t\t\t\t\t\ttoolKitIconUrl: this.getToolKitMeta(tm.name as string).toolKitIconUrl,\n\t\t\t\t\t\t\t\tinput: toolCall ? JSON.stringify(toolCall.input) : null,\n\t\t\t\t\t\t\t\toutput: tm.content.toString(),\n\t\t\t\t\t\t\t\ttoolCallId: tm.tool_call_id,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// console.error('\\n----------');\n\t\t\t\t// console.error('UPDATE');\n\t\t\t\t// console.error(JSON.stringify(data, null, 2));\n\t\t\t\t// console.error('----------\\n');\n\t\t\t} else if (mode == 'values') finalValue = data;\n\t\t}\n\n\t\tdebugLogStream('message_end', '\\n');\n\n\t\tyield { type: 'final_content', content: contentBlocks, usage: usageMetadata };\n\n\t\tyield { type: 'message_end' };\n\t}\n\n\tgetLangchainAgent(): ReactAgent {\n\t\treturn this.deepAgent;\n\t}\n\n\t/**\n\t * Tools have metadata fields that we can use\n\t * to get which toolKit this tool belongs to\n\t * and what's the toolKit's icon url.\n\t *\n\t * So we first find the tool using the tool's\n\t * name, then we extract the toolkit metadata\n\t * from that tool's metadata.\n\t */\n\tprivate getToolKitMeta(toolName: string): {\n\t\ttoolKit: string;\n\t\ttoolKitIconUrl: string;\n\t} {\n\t\tif (!this.tools)\n\t\t\treturn {\n\t\t\t\ttoolKit: '',\n\t\t\t\ttoolKitIconUrl: '',\n\t\t\t};\n\n\t\tconst tool = this.tools.find((t) => t.name === toolName);\n\n\t\tif (!tool) return { toolKit: '', toolKitIconUrl: '' };\n\n\t\treturn {\n\t\t\ttoolKit: tool.metadata?.toolKit as string,\n\t\t\ttoolKitIconUrl: tool.metadata?.toolKitIconUrl as string,\n\t\t};\n\t}\n\n\tprivate isToolCallMessage(message: BaseMessage): boolean {\n\t\tif (!(message instanceof AIMessageChunk)) return false;\n\n\t\tconst toolCallChunks = message.tool_call_chunks;\n\n\t\tif (!toolCallChunks) return false;\n\n\t\tif (toolCallChunks.length == 0) return false;\n\n\t\treturn true;\n\t}\n\n\tprivate shouldIgnoreMessage = (message: BaseMessage, metadata: any) => {\n\t\tif (message.id == '__remove_all__') return true;\n\n\t\t/**\n\t\t * For some reason there are AIMessageChunk messages\n\t\t * with empty content + no tool_call_chunks\n\t\t */\n\t\tif (!this.isToolCallMessage(message) && (!message.content || message.content.length == 0)) return true;\n\n\t\t/**\n\t\t * This is the tool selector middleware\n\t\t */\n\t\tif (metadata?.langgraph_node?.includes('patchToolCallsMiddleware')) return true;\n\n\t\tfor (const disabled of this.params.disableModelStreamingFor || [])\n\t\t\tif (metadata?.tags.includes(disabled)) return true;\n\n\t\treturn false;\n\t};\n\n\tprivate shouldStreamToolEvent(toolName: string): boolean {\n\t\tconst shouldStream = !this.params.disableToolStreamingFor?.includes(toolName);\n\n\t\tif (!shouldStream && ENABLE_STREAM_DEBUG_LOGS) console.warn('SUPPRESSING TOOL EVENT: ' + toolName);\n\n\t\treturn shouldStream;\n\t}\n\n\tprivate isReasoningMessage(message: BaseMessage): boolean {\n\t\tif (!Array.isArray(message.content)) return false;\n\t\treturn (message.content as any[]).some((block) => block.type === 'reasoning' || block.type === 'thinking');\n\t}\n\n\tprivate isArrayTextMessage(message: BaseMessage): boolean {\n\t\tif (!Array.isArray(message.content)) return false;\n\t\treturn (message.content as any[]).some((block) => block.type === 'text');\n\t}\n\n\t/**\n\t * Extracts text from message content that may be a string\n\t * or an array of content blocks (as returned by reasoning models).\n\t */\n\tprivate extractTextContent(content: any): string {\n\t\tif (typeof content === 'string') return content;\n\n\t\tif (Array.isArray(content)) {\n\t\t\treturn content\n\t\t\t\t.filter((block) => block.type === 'text' && block.text)\n\t\t\t\t.map((block) => block.text)\n\t\t\t\t.join('');\n\t\t}\n\n\t\treturn content.toString();\n\t}\n}\n","import { Message } from '@core/agent.interface';\nimport { AIMessage, BaseMessage, HumanMessage, ToolMessage } from 'langchain';\n\nexport function convertToLangchainMessages(messages: Message[]): BaseMessage[] {\n\tconst result: BaseMessage[] = [];\n\tlet tcIdx = 0;\n\tlet pendingToolCallIds: string[] = [];\n\n\tfor (const msg of messages) {\n\t\tif (msg.role === 'human') {\n\t\t\tresult.push(\n\t\t\t\tnew HumanMessage({\n\t\t\t\t\tcontent: msg.content.map((c) => {\n\t\t\t\t\t\tif (c.type === 'image') {\n\t\t\t\t\t\t\treturn { type: 'image_url', image_url: { url: c.url } };\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn c;\n\t\t\t\t\t}) as any,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (msg.role === 'ai') {\n\t\t\tif (msg.toolCalls && msg.toolCalls.length > 0) {\n\t\t\t\tpendingToolCallIds = msg.toolCalls.map(() => `tc_${++tcIdx}`);\n\t\t\t\tresult.push(\n\t\t\t\t\tnew AIMessage({\n\t\t\t\t\t\tcontent: msg.content,\n\t\t\t\t\t\ttool_calls: msg.toolCalls.map((tc, i) => ({\n\t\t\t\t\t\t\tid: pendingToolCallIds[i],\n\t\t\t\t\t\t\tname: tc.name,\n\t\t\t\t\t\t\targs: tc.input ? JSON.parse(tc.input) : {},\n\t\t\t\t\t\t})),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tresult.push(new AIMessage(msg.content));\n\t\t\t}\n\t\t} else if (msg.role === 'tool') {\n\t\t\tconst toolCallId = pendingToolCallIds.shift();\n\t\t\tif (!toolCallId)\n\t\t\t\tthrow new Error(`ToolMessage for \"${msg.name}\" without a preceding AiMessage with toolCalls`);\n\t\t\tresult.push(\n\t\t\t\tnew ToolMessage({\n\t\t\t\t\tcontent: msg.output,\n\t\t\t\t\ttool_call_id: toolCallId,\n\t\t\t\t\tname: msg.name,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { ChatAnthropic } from '@langchain/anthropic';\nimport { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';\nimport { ReasoningEffort } from 'openai/resources';\n\nexport type LangchainOpenAIConfig = {\n\tapiKey: string;\n};\n\nexport type AzureModelProvider = 'openai' | 'anthropic';\n\nexport type LangchainAzureResourceConfig = {\n\tapiKey: string;\n\tmodels: {\n\t\tmodel: string;\n\t\tprovider: AzureModelProvider;\n\t\tendpoint: string;\n\t\tapiVersion: string;\n\t\tdeploymentName: string;\n\t}[];\n};\n\nexport type ResourceName = string;\n\nexport type LangchainModelConfig = {\n\topenai?: Record<string, LangchainOpenAIConfig>;\n\tazure?: Record<ResourceName, LangchainAzureResourceConfig>;\n};\n\nexport class LangchainModelResolver {\n\tconstructor(private config: LangchainModelConfig) {}\n\n\tresolve(modelString: string, tags?: string[], reasoningEffort?: ReasoningEffort): BaseLanguageModel {\n\t\tconst parts = modelString.split(':');\n\n\t\tif (parts.length === 1) {\n\t\t\tconst fullModelString = this.resolveFullModelString(modelString);\n\t\t\treturn this.resolve(fullModelString, tags, reasoningEffort);\n\t\t}\n\n\t\tif (parts.length === 2) {\n\t\t\tconst [provider, modelName] = parts;\n\t\t\treturn this.resolveByProvider(provider, modelName, modelName, tags, reasoningEffort);\n\t\t}\n\n\t\tif (parts.length === 3) {\n\t\t\tconst [provider, configName, modelName] = parts;\n\t\t\treturn this.resolveByProvider(provider, configName, modelName, tags, reasoningEffort);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t'Model string must follow format \"modelName\", \"provider:modelName\", or \"provider:configName:modelName\"',\n\t\t);\n\t}\n\n\tprivate resolveFullModelString(modelName: string): string {\n\t\tfor (const [provider, resources] of Object.entries(this.config)) {\n\t\t\tif (provider === 'openai') {\n\t\t\t\tif (modelName in (resources as Record<string, unknown>)) {\n\t\t\t\t\treturn `openai:${modelName}`;\n\t\t\t\t}\n\t\t\t} else if (provider === 'azure') {\n\t\t\t\tfor (const [resource, config] of Object.entries(\n\t\t\t\t\tresources as Record<string, { models: { model: string }[] }>,\n\t\t\t\t)) {\n\t\t\t\t\tif (config.models.some((m) => m.model === modelName)) {\n\t\t\t\t\t\treturn `azure:${resource}:${modelName}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(`Model \"${modelName}\" not found in model config`);\n\t}\n\n\tprivate resolveByProvider(\n\t\tprovider: string,\n\t\tconfigName: string,\n\t\tmodelName: string,\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): BaseLanguageModel {\n\t\tswitch (provider) {\n\t\t\tcase 'openai':\n\t\t\t\treturn this.resolveOpenAI(configName, modelName, tags, reasoningEffort);\n\t\t\tcase 'azure':\n\t\t\t\treturn this.resolveAzure(configName, modelName, tags, reasoningEffort);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model provider: ${provider}`);\n\t\t}\n\t}\n\n\tprivate resolveOpenAI(\n\t\tconfigName: string,\n\t\tmodelName: string,\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): ChatOpenAI {\n\t\tconst providerConfig = this.config.openai?.[configName];\n\t\tif (!providerConfig) {\n\t\t\tthrow new Error(`Configuration \"${configName}\" for provider \"openai\" is missing`);\n\t\t}\n\n\t\treturn new ChatOpenAI({\n\t\t\tapiKey: providerConfig.apiKey,\n\t\t\tmodelName: modelName,\n\t\t\ttags: tags,\n\t\t\t...(reasoningEffort && {\n\t\t\t\treasoning: {\n\t\t\t\t\teffort: reasoningEffort,\n\t\t\t\t\tsummary: 'auto',\n\t\t\t\t},\n\t\t\t\tuseResponsesApi: true,\n\t\t\t}),\n\t\t});\n\t}\n\n\tprivate resolveAzure(\n\t\tresourceName: string,\n\t\tmodelName: string,\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): BaseLanguageModel {\n\t\tconst resource = this.config.azure?.[resourceName];\n\t\tif (!resource) {\n\t\t\tthrow new Error(`Resource \"${resourceName}\" for provider \"azure\" is missing`);\n\t\t}\n\n\t\tconst modelEntry = resource.models.find((m) => m.model === modelName);\n\t\tif (!modelEntry) {\n\t\t\tthrow new Error(`Model \"${modelName}\" not found in Azure resource \"${resourceName}\"`);\n\t\t}\n\n\t\tswitch (modelEntry.provider) {\n\t\t\tcase 'anthropic':\n\t\t\t\treturn this.resolveAzureAnthropic(resource, modelEntry, tags, reasoningEffort);\n\t\t\tcase 'openai':\n\t\t\t\treturn this.resolveAzureOpenAI(resource, modelEntry, tags, reasoningEffort);\n\t\t}\n\t}\n\n\tprivate resolveAzureOpenAI(\n\t\tresource: LangchainAzureResourceConfig,\n\t\tmodelEntry: LangchainAzureResourceConfig['models'][number],\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): AzureChatOpenAI {\n\t\t/**\n\t\t * OpenAI reasoning models require the Responses API which AzureChatOpenAI\n\t\t * does not support. We rewrite the endpoint to the Azure Responses API path.\n\t\t */\n\t\tconst endpoint = reasoningEffort\n\t\t\t? `${modelEntry.endpoint.replace(/\\/$/, '')}/openai/responses?api-version=${modelEntry.apiVersion}`\n\t\t\t: modelEntry.endpoint;\n\n\t\treturn new AzureChatOpenAI({\n\t\t\tmodel: modelEntry.model,\n\t\t\tazureOpenAIApiKey: resource.apiKey,\n\t\t\tazureOpenAIEndpoint: endpoint,\n\t\t\tazureOpenAIApiDeploymentName: modelEntry.deploymentName,\n\t\t\tazureOpenAIApiVersion: modelEntry.apiVersion,\n\t\t\ttags: tags,\n\t\t\t...(reasoningEffort && {\n\t\t\t\treasoning: {\n\t\t\t\t\teffort: reasoningEffort,\n\t\t\t\t\tsummary: 'auto',\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\t}\n\n\tprivate static readonly THINKING_BUDGET: Record<string, number> = {\n\t\tminimal: 1024,\n\t\tlow: 4096,\n\t\tmedium: 10000,\n\t\thigh: 16000,\n\t\txhigh: 32000,\n\t};\n\n\tprivate resolveAzureAnthropic(\n\t\tresource: LangchainAzureResourceConfig,\n\t\tmodelEntry: LangchainAzureResourceConfig['models'][number],\n\t\ttags?: string[],\n\t\treasoningEffort?: ReasoningEffort,\n\t): ChatAnthropic {\n\t\tconst budgetTokens = reasoningEffort ? LangchainModelResolver.THINKING_BUDGET[reasoningEffort] : undefined;\n\n\t\treturn new ChatAnthropic({\n\t\t\tmodel: modelEntry.model,\n\t\t\tapiKey: resource.apiKey,\n\t\t\tclientOptions: { baseURL: modelEntry.endpoint },\n\t\t\ttags: tags,\n\t\t\t...(budgetTokens && {\n\t\t\t\tmaxTokens: budgetTokens * 2,\n\t\t\t\tthinking: {\n\t\t\t\t\ttype: 'enabled',\n\t\t\t\t\tbudget_tokens: budgetTokens,\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\t}\n}\n","import { ToolDefinition, ToolSpec } from '@core/agent.interface';\nimport { ToolProvider } from './tool-provider';\nimport { ToolCache } from '@core/tools/tool-cache';\n\ntype ProviderEntry<TContext> = {\n\ttype: 'provider';\n\tprovider: ToolProvider<TContext>;\n};\n\ntype StaticEntry = {\n\ttype: 'static';\n\ttools: ToolDefinition[];\n};\n\ntype Entry<TContext> = ProviderEntry<TContext> | StaticEntry;\n\nexport interface ToolRegistryOptions {\n\t/**\n\t * Shared cache for tool specs (e.g. Redis). Values are stored as JSON strings.\n\t */\n\ttoolSpecCache?: ToolCache;\n}\n\nexport class ToolRegistry<TContext> {\n\tprivate entries = new Map<string, Entry<TContext>>();\n\tprivate toolSpecCache?: ToolCache;\n\n\tconstructor(options: ToolRegistryOptions = {}) {\n\t\tthis.toolSpecCache = options.toolSpecCache;\n\t}\n\n\tregisterProvider(toolKit: string, provider: ToolProvider<TContext>): void {\n\t\tthis.entries.set(toolKit, { type: 'provider', provider });\n\t}\n\n\tregisterTools(toolKit: string, tools: ToolDefinition[]): void {\n\t\tthis.entries.set(toolKit, { type: 'static', tools });\n\t}\n\n\tasync getTools(toolKits: string[], context: TContext): Promise<ToolDefinition[]> {\n\t\tconst results: ToolDefinition[] = [];\n\n\t\tfor (const kit of toolKits) {\n\t\t\tconst entry = this.entries.get(kit);\n\t\t\tif (!entry) {\n\t\t\t\tthrow new Error(`No tools or provider registered for tool kit: ${kit}`);\n\t\t\t}\n\n\t\t\tif (entry.type === 'static') {\n\t\t\t\tresults.push(...entry.tools);\n\t\t\t} else {\n\t\t\t\tconst provider = entry.provider;\n\t\t\t\tconst specs = await this.getToolKitSpecs(kit, provider, context);\n\t\t\t\tconst tools = await provider.bindTools(specs, context);\n\t\t\t\tresults.push(...tools);\n\t\t\t}\n\t\t}\n\n\t\treturn results;\n\t}\n\n\tinvalidate(toolKit: string): void {\n\t\tconst entry = this.entries.get(toolKit);\n\n\t\tif (entry && entry.type === 'provider') this.toolSpecCache?.del(toolKit);\n\t}\n\n\tprivate async getToolKitSpecs(\n\t\ttoolKit: string,\n\t\tprovider: ToolProvider<TContext>,\n\t\tcontext: TContext,\n\t): Promise<ToolSpec[]> {\n\t\tconst cache = this.toolSpecCache;\n\n\t\tif (cache) {\n\t\t\ttry {\n\t\t\t\tconst cached = await cache.get(toolKit);\n\n\t\t\t\tif (cached) return cached;\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Something went wrong when hitting the cache', e);\n\t\t\t}\n\t\t}\n\n\t\tconst specs = (await provider.listToolKitSpecs(toolKit, context)) ?? [];\n\n\t\tif (cache) {\n\t\t\ttry {\n\t\t\t\tawait cache.set(toolKit, specs);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Something went wrong when setting the cache', e);\n\t\t\t}\n\t\t}\n\n\t\treturn specs;\n\t}\n}\n","import { ToolSpec } from '@core/agent.interface';\nimport Redis from 'ioredis';\nimport { z } from 'zod';\n\nexport interface ToolCache {\n\tget(toolKit: string): Promise<ToolSpec[] | null> | ToolSpec[] | null;\n\n\tset(toolKit: string, specs: ToolSpec[]): Promise<void>;\n\n\tdel(toolKit: string): Promise<void>;\n}\n\nexport class RedisToolCache implements ToolCache {\n\tprivate redis: Redis;\n\n\tconstructor(connectionString: string) {\n\t\tthis.redis = new Redis(connectionString);\n\t}\n\n\tasync get(toolKit: string): Promise<ToolSpec[] | null> {\n\t\tconst data = await this.redis.get(`tool-cache:${toolKit}`);\n\n\t\tif (!data) return null;\n\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(data);\n\n\t\t\tif (!Array.isArray(parsed)) return null;\n\n\t\t\treturn parsed.map((spec: any) => ({\n\t\t\t\t...spec,\n\t\t\t\tinputSchema: z.fromJSONSchema(spec.inputSchema),\n\t\t\t}));\n\t\t} catch (e) {\n\t\t\tconsole.error('Failed to parse cached tools', e);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync set(toolKit: string, specs: ToolSpec[]): Promise<void> {\n\t\tconst serialized = specs.map((spec) => ({\n\t\t\t...spec,\n\t\t\tinputSchema: spec.inputSchema.toJSONSchema(),\n\t\t}));\n\t\tawait this.redis.set(`tool-cache:${toolKit}`, JSON.stringify(serialized));\n\t}\n\n\tasync del(toolKit: string): Promise<void> {\n\t\tawait this.redis.del(`tool-cache:${toolKit}`);\n\t}\n}\n\nexport class InMemoryToolCache implements ToolCache {\n\tprivate cache = new Map<string, ToolSpec[]>();\n\n\tget(toolKit: string): ToolSpec[] | null {\n\t\treturn this.cache.get(`tool-cache:${toolKit}`) ?? null;\n\t}\n\n\tasync set(toolKit: string, specs: ToolSpec[]): Promise<void> {\n\t\tthis.cache.set(`tool-cache:${toolKit}`, specs);\n\t}\n\n\tasync del(toolKit: string): Promise<void> {\n\t\tthis.cache.delete(`tool-cache:${toolKit}`);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,2CAA8B;AAE9B,mBAA8B;AAC9B,IAAAA,qBAA6D;AAC7D,IAAAC,oBAA0F;;;ACG1F,sBAA2C;AAC3C,uBAAwB;AACxB,wBAAuD;AACvD,IAAAC,oBAA2G;;;ACX3G,uBAAkE;AAE3D,SAAS,2BAA2B,UAAoC;AAC9E,QAAM,SAAwB,CAAC;AAC/B,MAAI,QAAQ;AACZ,MAAI,qBAA+B,CAAC;AAEpC,aAAW,OAAO,UAAU;AAC3B,QAAI,IAAI,SAAS,SAAS;AACzB,aAAO;AAAA,QACN,IAAI,8BAAa;AAAA,UAChB,SAAS,IAAI,QAAQ,IAAI,CAAC,MAAM;AAC/B,gBAAI,EAAE,SAAS,SAAS;AACvB,qBAAO,EAAE,MAAM,aAAa,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE;AAAA,YACvD;AACA,mBAAO;AAAA,UACR,CAAC;AAAA,QACF,CAAC;AAAA,MACF;AAAA,IACD,WAAW,IAAI,SAAS,MAAM;AAC7B,UAAI,IAAI,aAAa,IAAI,UAAU,SAAS,GAAG;AAC9C,6BAAqB,IAAI,UAAU,IAAI,MAAM,MAAM,EAAE,KAAK,EAAE;AAC5D,eAAO;AAAA,UACN,IAAI,2BAAU;AAAA,YACb,SAAS,IAAI;AAAA,YACb,YAAY,IAAI,UAAU,IAAI,CAAC,IAAI,OAAO;AAAA,cACzC,IAAI,mBAAmB,CAAC;AAAA,cACxB,MAAM,GAAG;AAAA,cACT,MAAM,GAAG,QAAQ,KAAK,MAAM,GAAG,KAAK,IAAI,CAAC;AAAA,YAC1C,EAAE;AAAA,UACH,CAAC;AAAA,QACF;AAAA,MACD,OAAO;AACN,eAAO,KAAK,IAAI,2BAAU,IAAI,OAAO,CAAC;AAAA,MACvC;AAAA,IACD,WAAW,IAAI,SAAS,QAAQ;AAC/B,YAAM,aAAa,mBAAmB,MAAM;AAC5C,UAAI,CAAC;AACJ,cAAM,IAAI,MAAM,oBAAoB,IAAI,IAAI,gDAAgD;AAC7F,aAAO;AAAA,QACN,IAAI,6BAAY;AAAA,UACf,SAAS,IAAI;AAAA,UACb,cAAc;AAAA,UACd,MAAM,IAAI;AAAA,QACX,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;;;ADpCA,IAAM,2BAA2B;AAEjC,SAAS,eAAe,MAA2B,MAAc;AAChE,MAAI,CAAC,yBAA0B;AAE/B,UAAQ,KAAK,GAAG,IAAI,KAAK,IAAI,EAAE;AAChC;AAmBO,IAAM,iBAAN,MAAsC;AAAA,EAK5C,YAAoB,QAAuB;AAAvB;AACnB,SAAK,QAAQ,OAAO;AAEpB,QAAI,CAAC,OAAO,yBAA0B,QAAO,2BAA2B,CAAC;AACzE,QAAI,CAAC,OAAO,wBAAyB,QAAO,0BAA0B,CAAC;AACvE,QAAI,CAAC,OAAO,wBAAyB,QAAO,0BAA0B,CAAC;AAEvE,QAAI,cAAiC;AAAA,UACpC,oCAAiB;AAAA,QAChB,MAAM;AAAA,QACN,cAAc,OAAO,SAAS,YAAY;AACzC,cAAI;AACH,kBAAM,MAAM,MAAM,QAAQ,OAAO;AAEjC,gBAAI,KAAK,OAAO,yBAAyB,SAAS,QAAQ,MAAM,IAAc,EAAG,QAAO;AAExF,iBAAK,UAAU,KAAK;AAAA,cACnB,IAAI,QAAQ,SAAS;AAAA,cACrB,MAAO,QAAQ,MAAM,QAAmB;AAAA,cACxC,OAAO,QAAQ,SAAS;AAAA,cACxB,QAAQ,IAAI,OAAO;AAAA,YACpB,CAAC;AAaD,gBAAI,eAAe,0BAAS;AAC3B,oBAAM,UAIF;AAEJ,kBAAI,CAAC,QAAQ,QAAQ,YAAY,QAAQ,OAAO,SAAS,UAAU,EAAG,QAAO;AAE7E,oBAAM,cAAc,QAAQ,OAAO,SAAS,KAAK,CAAC,MAAmB,EAAE,QAAQ,MAAM;AAErF,kBAAI,CAAC,YAAa,QAAO;AAEzB,qBAAO;AAAA,YACR,MAAO,QAAO;AAAA,UACf,SAAS,GAAQ;AAChB,mBAAO,IAAI,4BAAY;AAAA,cACtB,MAAM,QAAQ,SAAS;AAAA,cACvB,SAAS,2BAA2B,EAAE;AAAA,cACtC,cAAc,QAAQ,SAAS,MAAM;AAAA,YACtC,CAAC;AAAA,UACF;AAAA,QACD;AAAA,MACD,CAAC;AAAA,IACF;AAEA,QAAI,OAAO,WAAY,eAAc,CAAC,GAAG,aAAa,GAAG,OAAO,UAAU;AAE1E,WAAO,aAAa;AAEpB,SAAK,gBAAY,mCAAgB,MAAM;AAAA,EACxC;AAAA,EArEQ;AAAA,EACA,YAAwB,CAAC;AAAA,EACzB;AAAA,EAqER,MAAM,IAAI,OAA4C;AACrD,SAAK,YAAY,CAAC;AAIlB,QAAI,qBAAqB;AACzB,QAAI;AACH,YAAM,cAAc,MAAM,KAAK,UAAU,SAAS;AAAA,QACjD,cAAc;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,WAAW,MAAM;AAAA,QAClB;AAAA,MACD,CAAC;AACD,2BAAsB,aAAqB,QAAQ,UAAU,UAAU;AAAA,IACxE,QAAQ;AAAA,IAER;AAEA,UAAM,WAAW,2BAA2B,MAAM,QAAQ;AAE1D,UAAM,SAAS,MAAM,KAAK,UAAU;AAAA,MACnC;AAAA,QACC;AAAA,MACD;AAAA,MACA;AAAA,QACC,cAAc;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,WAAW,MAAM;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AAGA,UAAM,cAAc,OAAO,SAAS,MAAM,kBAAkB;AAC5D,UAAM,oBAAoB,YAAY,OAAO,CAAC,MAAW,EAAE,kBAAkB,IAAI;AAEjF,QAAI,QAAQ;AAAA,MACX,cAAc;AAAA,MACd,eAAe;AAAA,MACf,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,IACjB;AAEA,sBAAkB,QAAQ,CAAC,MAAW;AACrC,YAAM,YAAY,EAAE,eAAe,qBAAqB,cAAc;AACtE,YAAM,WAAW,EAAE,mBAAmB;AAItC,YAAM,cACL,aAAa,cACV,EAAE,eAAe,gBAAgB,KAChC,EAAE,eAAe,gBAAgB,KAAK;AAE3C,YAAM,gBAAgB;AACtB,YAAM,iBAAiB,EAAE,eAAe,iBAAiB;AACzD,YAAM,gBAAgB,eAAe,EAAE,eAAe,iBAAiB;AACvE,YAAM,cAAc;AACpB,YAAM,oBAAoB,EAAE,eAAe,sBAAsB,aAAa;AAC9E,YAAM,kBAAkB,EAAE,eAAe,qBAAqB,kBAAkB;AAAA,IACjF,CAAC;AAGD,UAAM,gBAAgC,CAAC;AACvC,UAAM,iBAAgD,CAAC;AAEvD,eAAW,OAAO,aAAa;AAC9B,YAAM,IAAI;AACV,UAAI,EAAE,SAAS,MAAM;AAEpB,YAAI,EAAE,cAAc,EAAE,WAAW,SAAS,GAAG;AAC5C,qBAAW,MAAM,EAAE,YAAY;AAC9B,2BAAe,GAAG,EAAE,IAAI,GAAG;AAAA,UAC5B;AAAA,QACD;AAEA,YAAI,EAAE,SAAS;AACd,gBAAM,aAAa,KAAK,mBAAmB,EAAE,OAAO;AACpD,cAAI,WAAW,KAAK,EAAE,SAAS,GAAG;AACjC,0BAAc,KAAK;AAAA,cAClB,MAAM;AAAA,cACN,QAAQ;AAAA,YACT,CAAC;AAAA,UACF;AAAA,QACD;AAAA,MACD,WAAW,EAAE,SAAS,QAAQ;AAC7B,sBAAc,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,MAAM,EAAE;AAAA,UACR,SAAS,KAAK,eAAe,EAAE,IAAI,EAAE;AAAA,UACrC,gBAAgB,KAAK,eAAe,EAAE,IAAI,EAAE;AAAA,UAC5C,OAAO,KAAK,UAAU,eAAe,EAAE,YAAY,KAAK,CAAC,CAAC;AAAA,UAC1D,QAAQ,EAAE,QAAQ,SAAS;AAAA,UAC3B,YAAY,EAAE;AAAA,QACf,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO;AAAA,MACN,SAAS;AAAA,MACT,WAAW,KAAK;AAAA,MAChB,OAAO;AAAA,QACN,cAAc,MAAM;AAAA,QACpB,kBAAkB,MAAM;AAAA,QACxB,aAAa,MAAM;AAAA,QACnB,oBAAoB,MAAM;AAAA,QAC1B,iBAAiB,MAAM;AAAA,QACvB,qBAAqB,MAAM;AAAA,MAC5B;AAAA,IACD;AAAA,EACD;AAAA,EAEA,OAAO,OAAO,OAAmD;AAChE,SAAK,YAAY,CAAC;AAClB,UAAM,gBAAgC,CAAC;AACvC,QAAI;AAGJ,QAAI,gBAA2B;AAAA,MAC9B,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,oBAAoB;AAAA,MACpB,iBAAiB;AAAA,MACjB,qBAAqB;AAAA,IACtB;AAEA,UAAM,WAAW,2BAA2B,MAAM,QAAQ;AAE1D,mBAAe,iBAAiB,EAAE;AAGlC,UAAM,EAAE,MAAM,gBAAgB;AAE9B,UAAM,SAAS,MAAM,KAAK,UAAU;AAAA,MACnC,EAAE,SAAS;AAAA,MACX;AAAA,QACC,cAAc;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,WAAW,MAAM;AAAA,QAClB;AAAA,QACA,YAAY,CAAC,YAAY,WAAW,QAAQ;AAAA,MAC7C;AAAA,IACD;AAEA,QAAI,YAKA,CAAC;AACL,UAAM,kBAKF,CAAC;AAKL,qBAAiB,SAAS,QAAQ;AACjC,YAAM,CAAC,MAAM,IAAI,IAAI;AAErB,UAAI,SAAS,YAAY;AACxB,cAAM,CAAC,SAAS,QAAQ,IAAI;AAK5B,YAAI,KAAK,oBAAoB,SAAS,QAAQ,EAAG;AAOjD,YAAI,KAAK,kBAAkB,OAAO,GAAG;AACpC,gBAAM,YAAY;AAClB,gBAAM,iBAAiB,UAAU;AAEjC,qBAAW,aAAa,gBAAgB;AACvC,kBAAM,gBAAgB,UAAU;AAEhC,kBAAM,kBAAkB,MAAM;AAC7B,qBAAO,UAAU,aAAa;AAAA,YAC/B;AAYA,gBAAI,UAAU,IAAI;AACjB,wBAAU,UAAU,KAAe,IAAI;AAAA,gBACtC,YAAY,UAAU;AAAA,gBACtB,MAAM,UAAU;AAAA,cACjB;AAEA,kBAAI,CAAC,KAAK,sBAAsB,gBAAgB,EAAE,IAAI,EAAG;AAEzD,oBAAM,cAAc,KAAK,eAAe,gBAAgB,EAAE,IAAI;AAE9D,6BAAe,cAAc,IAAI,gBAAgB,EAAE,UAAU,KAAK,gBAAgB,EAAE,IAAI,EAAE;AAE1F,oBAAM;AAAA,gBACL,MAAM;AAAA,gBACN,MAAM,gBAAgB,EAAE;AAAA,gBACxB,SAAS,YAAY;AAAA,gBACrB,gBAAgB,YAAY;AAAA,gBAC5B,OAAO;AAAA,gBACP,YAAY,gBAAgB,EAAE;AAAA,cAC/B;AAAA,YACD;AAEA,gBAAI,UAAU,QAAQ,UAAU,KAAK,SAAS,GAAG;AAChD,kBAAI,CAAC,KAAK,sBAAsB,gBAAgB,EAAE,IAAI,EAAG;AAEzD,6BAAe,oBAAoB,IAAI,gBAAgB,EAAE,UAAU,KAAK,UAAU,IAAI,EAAE;AAExF,oBAAM;AAAA,gBACL,MAAM;AAAA,gBACN,MAAM,gBAAgB,EAAE;AAAA,gBACxB,MAAM,UAAU,QAAQ;AAAA,gBACxB,OAAO;AAAA,gBACP,YAAY,gBAAgB,EAAE;AAAA,cAC/B;AAAA,YACD;AAAA,UACD;AAAA,QACD,WAAW,KAAK,mBAAmB,OAAO,GAAG;AAC5C,gBAAM,eAAe,QAAQ;AAC7B,qBAAW,SAAS,cAAc;AACjC,kBAAM,QACJ,MAAM,SAAS,eAAe,MAAM,aACpC,MAAM,SAAS,cAAc,MAAM;AACrC,gBAAI,OAAO;AACV,6BAAe,mBAAmB,KAAK;AAEvC,oBAAM;AAAA,gBACL,MAAM;AAAA,gBACN;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD,WAAW,KAAK,mBAAmB,OAAO,GAAG;AAC5C,gBAAM,eAAe,QAAQ;AAC7B,qBAAW,SAAS,cAAc;AACjC,gBAAI,MAAM,SAAS,UAAU,MAAM,MAAM;AACxC,6BAAe,cAAc,MAAM,IAAI;AAEvC,oBAAM;AAAA,gBACL,MAAM;AAAA,gBACN,OAAO,MAAM;AAAA,cACd;AAAA,YACD;AAAA,UACD;AAAA,QACD,WAAW,SAAS,WAAW,OAAO,QAAQ,YAAY,UAAU;AACnE,gBAAM,UAAU,QAAQ;AAExB,cAAI,QAAQ,WAAW,EAAG;AAE1B,cAAI,QAAQ,QAAQ,QAAQ;AAE3B,kBAAM,WAAW,QAAQ;AACzB,kBAAM,cAAc,KAAK,eAAe,QAAQ;AAEhD,kBAAM,WAAW,OAAO,QAAQ,SAAS,EAAE;AAAA,cAC1C,CAAC,CAAC,GAAG,KAAK,MAAM,MAAM,cAAe,QAAwB;AAAA,YAC9D;AAEA,gBAAI,CAAC,KAAK,sBAAsB,QAAQ,EAAG;AAE3C,2BAAe,eAAe,IAAI,WAAW,CAAC,EAAE,UAAU,KAAK,QAAQ,OAAO,EAAE;AAEhF,kBAAM;AAAA,cACL,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OACC,KAAK;AAAA,gBACJ,KAAK,UAAU,KAAK,CAAC,OAAO,GAAG,MAAO,SAAiB,CAAC,EAAE,UAAU,GAAG;AAAA,cACxE,KAAK;AAAA,cACN,QAAQ,QAAQ;AAAA,cAChB,SAAS,YAAY;AAAA,cACrB,gBAAgB,YAAY;AAAA,cAC5B,OAAO,WAAW,CAAC,IAAI,SAAS,SAAS,CAAC,CAAC,IAAI;AAAA,cAC/C,YAAY,WAAW,CAAC,IAAI,SAAS,CAAC,EAAE,aAAa;AAAA,YACtD;AAAA,UACD,OAAO;AACN,2BAAe,cAAc,OAAO;AAEpC,kBAAM;AAAA,cACL,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,QACD,OAAO;AACN,kBAAQ,KAAK,oCAAoC,KAAK;AAAA,QACvD;AAAA,MACD,WAAW,QAAQ,WAAW;AAC7B,cAAM,SAAS;AAOf,YAAI,OAAO,eAAe,UAAU;AACnC,gBAAM,kBAAoC,OAAO,cAAc,SAAS;AAAA,YACvE,CAAC,MAAM,EAAE,QAAQ;AAAA,UAClB;AAEA,mBAAS,WAAW,iBAAiB;AAEpC,kBAAM,KAAK,QAAQ;AACnB,gBAAI,IAAI;AACP,oBAAM,YAAY,GAAG,qBAAqB,cAAc;AACxD,oBAAM,WAAW,QAAQ,mBAAmB;AAI5C,oBAAM,cACL,aAAa,cAAc,GAAG,gBAAgB,KAAK,GAAG,gBAAgB,KAAK;AAE5E,4BAAc,gBAAgB;AAC9B,4BAAc,oBAAoB,GAAG,iBAAiB;AACtD,4BAAc,eAAe,eAAe,GAAG,iBAAiB;AAChE,4BAAc,sBAAuB;AACrC,4BAAc,mBACZ,cAAc,mBAAmB,MAAM,GAAG,sBAAsB,aAAa;AAC/E,4BAAc,uBAAwB,GAAG,qBAAqB,kBAAkB;AAAA,YACjF;AAEA,gBAAI,QAAQ,cAAc,QAAQ,WAAW,SAAS,GAAG;AACxD,uBAAS,MAAM,QAAQ;AACtB,gCAAgB,GAAG,EAAY,IAAI;AAAA,kBAClC,MAAM,GAAG;AAAA,kBACT,MAAM,GAAG;AAAA,gBACV;AAAA,YACF,WAAW,QAAQ,SAAS;AAC3B,oBAAM,aAAa,KAAK,mBAAmB,QAAQ,OAAO;AAC1D,kBAAI,WAAW,KAAK,EAAE,SAAS;AAC9B,8BAAc,KAAK;AAAA,kBAClB,MAAM;AAAA,kBACN,QAAQ;AAAA,gBACT,CAAC;AAAA,YACH;AAAA,UACD;AAAA,QACD;AAMA,YAAI,OAAO,OAAO,UAAU;AAC3B,gBAAM,eAA8B,OAAO,MAAM,SAAS;AAAA,YACzD,CAAC,MAAM,EAAE,QAAQ;AAAA,UAClB;AAEA,mBAAS,MAAM,cAAc;AAC5B,kBAAMC,SAAQ,KAAK,UAAU,gBAAgB,GAAG,YAAY,EAAE,IAAI;AAClE,kBAAM,WAAW,KAAK,UAAU,KAAK,CAAC,OAAO,GAAG,MAAM,GAAG,YAAY;AAErE,gBAAI,KAAK,sBAAsB,GAAG,IAAc;AAC/C,4BAAc,KAAK;AAAA,gBAClB,MAAM;AAAA,gBACN,MAAM,GAAG;AAAA,gBACT,SAAS,KAAK,eAAe,GAAG,IAAc,EAAE;AAAA,gBAChD,gBAAgB,KAAK,eAAe,GAAG,IAAc,EAAE;AAAA,gBACvD,OAAO,WAAW,KAAK,UAAU,SAAS,KAAK,IAAI;AAAA,gBACnD,QAAQ,GAAG,QAAQ,SAAS;AAAA,gBAC5B,YAAY,GAAG;AAAA,cAChB,CAAC;AAAA,UACH;AAAA,QACD;AAAA,MAMD,WAAW,QAAQ,SAAU,cAAa;AAAA,IAC3C;AAEA,mBAAe,eAAe,IAAI;AAElC,UAAM,EAAE,MAAM,iBAAiB,SAAS,eAAe,OAAO,cAAc;AAE5E,UAAM,EAAE,MAAM,cAAc;AAAA,EAC7B;AAAA,EAEA,oBAAgC;AAC/B,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,eAAe,UAGrB;AACD,QAAI,CAAC,KAAK;AACT,aAAO;AAAA,QACN,SAAS;AAAA,QACT,gBAAgB;AAAA,MACjB;AAED,UAAMC,QAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAEvD,QAAI,CAACA,MAAM,QAAO,EAAE,SAAS,IAAI,gBAAgB,GAAG;AAEpD,WAAO;AAAA,MACN,SAASA,MAAK,UAAU;AAAA,MACxB,gBAAgBA,MAAK,UAAU;AAAA,IAChC;AAAA,EACD;AAAA,EAEQ,kBAAkB,SAA+B;AACxD,QAAI,EAAE,mBAAmB,kCAAiB,QAAO;AAEjD,UAAM,iBAAiB,QAAQ;AAE/B,QAAI,CAAC,eAAgB,QAAO;AAE5B,QAAI,eAAe,UAAU,EAAG,QAAO;AAEvC,WAAO;AAAA,EACR;AAAA,EAEQ,sBAAsB,CAAC,SAAsB,aAAkB;AACtE,QAAI,QAAQ,MAAM,iBAAkB,QAAO;AAM3C,QAAI,CAAC,KAAK,kBAAkB,OAAO,MAAM,CAAC,QAAQ,WAAW,QAAQ,QAAQ,UAAU,GAAI,QAAO;AAKlG,QAAI,UAAU,gBAAgB,SAAS,0BAA0B,EAAG,QAAO;AAE3E,eAAW,YAAY,KAAK,OAAO,4BAA4B,CAAC;AAC/D,UAAI,UAAU,KAAK,SAAS,QAAQ,EAAG,QAAO;AAE/C,WAAO;AAAA,EACR;AAAA,EAEQ,sBAAsB,UAA2B;AACxD,UAAM,eAAe,CAAC,KAAK,OAAO,yBAAyB,SAAS,QAAQ;AAE5E,QAAI,CAAC,gBAAgB,yBAA0B,SAAQ,KAAK,6BAA6B,QAAQ;AAEjG,WAAO;AAAA,EACR;AAAA,EAEQ,mBAAmB,SAA+B;AACzD,QAAI,CAAC,MAAM,QAAQ,QAAQ,OAAO,EAAG,QAAO;AAC5C,WAAQ,QAAQ,QAAkB,KAAK,CAAC,UAAU,MAAM,SAAS,eAAe,MAAM,SAAS,UAAU;AAAA,EAC1G;AAAA,EAEQ,mBAAmB,SAA+B;AACzD,QAAI,CAAC,MAAM,QAAQ,QAAQ,OAAO,EAAG,QAAO;AAC5C,WAAQ,QAAQ,QAAkB,KAAK,CAAC,UAAU,MAAM,SAAS,MAAM;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB,SAAsB;AAChD,QAAI,OAAO,YAAY,SAAU,QAAO;AAExC,QAAI,MAAM,QAAQ,OAAO,GAAG;AAC3B,aAAO,QACL,OAAO,CAAC,UAAU,MAAM,SAAS,UAAU,MAAM,IAAI,EACrD,IAAI,CAAC,UAAU,MAAM,IAAI,EACzB,KAAK,EAAE;AAAA,IACV;AAEA,WAAO,QAAQ,SAAS;AAAA,EACzB;AACD;;;AE9lBA,uBAA8B;AAC9B,oBAA4C;AA2BrC,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EACnC,YAAoB,QAA8B;AAA9B;AAAA,EAA+B;AAAA,EAEnD,QAAQ,aAAqB,MAAiB,iBAAsD;AACnG,UAAM,QAAQ,YAAY,MAAM,GAAG;AAEnC,QAAI,MAAM,WAAW,GAAG;AACvB,YAAM,kBAAkB,KAAK,uBAAuB,WAAW;AAC/D,aAAO,KAAK,QAAQ,iBAAiB,MAAM,eAAe;AAAA,IAC3D;AAEA,QAAI,MAAM,WAAW,GAAG;AACvB,YAAM,CAAC,UAAU,SAAS,IAAI;AAC9B,aAAO,KAAK,kBAAkB,UAAU,WAAW,WAAW,MAAM,eAAe;AAAA,IACpF;AAEA,QAAI,MAAM,WAAW,GAAG;AACvB,YAAM,CAAC,UAAU,YAAY,SAAS,IAAI;AAC1C,aAAO,KAAK,kBAAkB,UAAU,YAAY,WAAW,MAAM,eAAe;AAAA,IACrF;AAEA,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,uBAAuB,WAA2B;AACzD,eAAW,CAAC,UAAU,SAAS,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AAChE,UAAI,aAAa,UAAU;AAC1B,YAAI,aAAc,WAAuC;AACxD,iBAAO,UAAU,SAAS;AAAA,QAC3B;AAAA,MACD,WAAW,aAAa,SAAS;AAChC,mBAAW,CAAC,UAAU,MAAM,KAAK,OAAO;AAAA,UACvC;AAAA,QACD,GAAG;AACF,cAAI,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS,GAAG;AACrD,mBAAO,SAAS,QAAQ,IAAI,SAAS;AAAA,UACtC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,IAAI,MAAM,UAAU,SAAS,6BAA6B;AAAA,EACjE;AAAA,EAEQ,kBACP,UACA,YACA,WACA,MACA,iBACoB;AACpB,YAAQ,UAAU;AAAA,MACjB,KAAK;AACJ,eAAO,KAAK,cAAc,YAAY,WAAW,MAAM,eAAe;AAAA,MACvE,KAAK;AACJ,eAAO,KAAK,aAAa,YAAY,WAAW,MAAM,eAAe;AAAA,MACtE;AACC,cAAM,IAAI,MAAM,+BAA+B,QAAQ,EAAE;AAAA,IAC3D;AAAA,EACD;AAAA,EAEQ,cACP,YACA,WACA,MACA,iBACa;AACb,UAAM,iBAAiB,KAAK,OAAO,SAAS,UAAU;AACtD,QAAI,CAAC,gBAAgB;AACpB,YAAM,IAAI,MAAM,kBAAkB,UAAU,oCAAoC;AAAA,IACjF;AAEA,WAAO,IAAI,yBAAW;AAAA,MACrB,QAAQ,eAAe;AAAA,MACvB;AAAA,MACA;AAAA,MACA,GAAI,mBAAmB;AAAA,QACtB,WAAW;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,QACV;AAAA,QACA,iBAAiB;AAAA,MAClB;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEQ,aACP,cACA,WACA,MACA,iBACoB;AACpB,UAAM,WAAW,KAAK,OAAO,QAAQ,YAAY;AACjD,QAAI,CAAC,UAAU;AACd,YAAM,IAAI,MAAM,aAAa,YAAY,mCAAmC;AAAA,IAC7E;AAEA,UAAM,aAAa,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS;AACpE,QAAI,CAAC,YAAY;AAChB,YAAM,IAAI,MAAM,UAAU,SAAS,kCAAkC,YAAY,GAAG;AAAA,IACrF;AAEA,YAAQ,WAAW,UAAU;AAAA,MAC5B,KAAK;AACJ,eAAO,KAAK,sBAAsB,UAAU,YAAY,MAAM,eAAe;AAAA,MAC9E,KAAK;AACJ,eAAO,KAAK,mBAAmB,UAAU,YAAY,MAAM,eAAe;AAAA,IAC5E;AAAA,EACD;AAAA,EAEQ,mBACP,UACA,YACA,MACA,iBACkB;AAKlB,UAAM,WAAW,kBACd,GAAG,WAAW,SAAS,QAAQ,OAAO,EAAE,CAAC,iCAAiC,WAAW,UAAU,KAC/F,WAAW;AAEd,WAAO,IAAI,8BAAgB;AAAA,MAC1B,OAAO,WAAW;AAAA,MAClB,mBAAmB,SAAS;AAAA,MAC5B,qBAAqB;AAAA,MACrB,8BAA8B,WAAW;AAAA,MACzC,uBAAuB,WAAW;AAAA,MAClC;AAAA,MACA,GAAI,mBAAmB;AAAA,QACtB,WAAW;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,QACV;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEA,OAAwB,kBAA0C;AAAA,IACjE,SAAS;AAAA,IACT,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,EACR;AAAA,EAEQ,sBACP,UACA,YACA,MACA,iBACgB;AAChB,UAAM,eAAe,kBAAkB,wBAAuB,gBAAgB,eAAe,IAAI;AAEjG,WAAO,IAAI,+BAAc;AAAA,MACxB,OAAO,WAAW;AAAA,MAClB,QAAQ,SAAS;AAAA,MACjB,eAAe,EAAE,SAAS,WAAW,SAAS;AAAA,MAC9C;AAAA,MACA,GAAI,gBAAgB;AAAA,QACnB,WAAW,eAAe;AAAA,QAC1B,UAAU;AAAA,UACT,MAAM;AAAA,UACN,eAAe;AAAA,QAChB;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACF;AACD;;;AHrLO,IAAM,wBAAN,MAAoD;AAAA,EAG1D,YACS,aACA,aACA,aACP;AAHO;AACA;AACA;AAER,SAAK,gBAAgB,IAAI,uBAAuB,KAAK,WAAW;AAAA,EACjE;AAAA,EARQ;AAAA,EAUA,wBAAwB,OAAoD;AACnF,UAAM,QAAQ;AAAA,MACb;AAAA,MACA;AAAA,MACA,GAAG,MAAM,IAAI,CAAC,SAAS;AACtB,cAAM,SAAS,KAAK,0BAA0B,KAAK,IAAI;AACvD,eAAO,KAAK,MAAM,KAAK,KAAK,OAAO;AAAA,MACpC,CAAC;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACvB;AAAA,EAEQ,0BAA0B,UAA2D;AAC5F,UAAM,QAAQ;AAAA,MACb;AAAA,MACA,GAAG,SAAS,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,QAAQ,WAAW,EAAE;AAAA,IACzE;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACvB;AAAA,EAEQ,0BAA0B,QAAwB;AACzD,UAAM,gBAAgB,OAAO,KAAK;AAClC,QAAI,cAAc,WAAW,GAAG;AAC/B,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACnD;AAEA,UAAM,mBAAmB,cAAc,WAAW,GAAG,IAAI,gBAAgB,IAAI,aAAa;AAC1F,WAAO,iBAAiB,SAAS,GAAG,IAAI,mBAAmB,GAAG,gBAAgB;AAAA,EAC/E;AAAA,EAEA,MAAM,YAAY,SAA6C;AAC9D,QAAI,mBAAkC;AAAA,MACrC,OAAO,KAAK,cAAc,QAAQ,QAAQ,OAAO,CAAC,GAAG,QAAQ,SAAS;AAAA,IACvE;AAEA,QAAI,cAAiC,CAAC;AACtC,QAAI,eAAe,QAAQ,gBAAgB;AAC3C,QAAI,2BAAqC;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,QAAI,2BAAqC;AACzC,QAAI,2BAAqC,CAAC;AAE1C,QAAI,QAAQ,SAAS;AACpB,YAAM,eAAe,mDAAc,eAAe,KAAK,YAAY,YAAY;AAAA,QAC9E,QAAQ,KAAK,YAAY;AAAA,MAC1B,CAAC;AAED,YAAM,aAAa,MAAM;AAEzB,uBAAiB,eAAe;AAAA,IACjC;AAEA,QAAI,QAAQ,QAAQ;AACnB,YAAM,qBAAqB,KAAK,wBAAwB,QAAQ,OAAO,KAAK;AAC5E,qBAAe,eAAe,GAAG,YAAY;AAAA;AAAA,EAAO,kBAAkB,KAAK;AAE3E,uBAAiB,QAAQ,IAAI,2BAAc;AAAA,QAC1C,mBAAmB,KAAK,YAAY;AAAA,QACpC,QAAQ,KAAK,YAAY;AAAA,QACzB,cAAc;AAAA,MACf,CAAC;AAKD,uBAAiB,UAAU,CAAC,WAAW;AACtC,cAAM,wBAAwB,EAAE,GAAG,QAAQ,aAAa,QAAQ,QAAQ,YAAY;AACpF,cAAM,eAAe,IAAI,gCAAa,qBAAqB;AAC3D,cAAM,SAAS,OAAO;AAAA,WACpB,QAAQ,QAAQ,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS;AAC3C,kBAAM,cAAc,KAAK,0BAA0B,KAAK,IAAI;AAC5D,mBAAO,CAAC,aAAa,YAAY;AAAA,UAClC,CAAC;AAAA,QACF;AAEA,eAAO,IAAI,oCAAiB,IAAI,gCAAa,qBAAqB,GAAG;AAAA,UACpE,GAAG;AAAA,QACJ,CAAC;AAAA,MACF;AAAA,IACD;AAEA,QAAI,QAAQ,OAAO;AAClB,uBAAiB,QAAQ,QAAQ,MAAM,MAAM;AAAA,QAAI,CAAC,UACjD;AAAA,UACC,OAAO,OAAOC,aAAY;AACzB,gBAAI;AACH,oBAAM,MAAM,MAAM,EAAE,KAAK,KAAK;AAE9B,kBAAI,OAAO,QAAQ,SAAU,QAAO;AAEpC,qBAAO,KAAK,UAAU,GAAG;AAAA,YAC1B,SAAS,GAAG;AACX,sBAAQ,MAAM,yBAAyB,CAAC;AACxC,qBAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA;AAAA,YACC,MAAM,EAAE;AAAA,YACR,aAAa,EAAE;AAAA,YACf,QAAQ,EAAE;AAAA,YACV,UAAU;AAAA,cACT,SAAS,EAAE;AAAA,cACX,gBAAgB,EAAE;AAAA,YACnB;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,kBAAY;AAAA,YACX,6CAA0B;AAAA,UACzB,OAAO,KAAK,cAAc,QAAQ,QAAQ,MAAM,OAAO,CAAC,eAAe,CAAC;AAAA,UACxE,UAAU;AAAA,UACV,eAAe,QAAQ,MAAM,sBAAsB;AAAA,QACpD,CAAC;AAAA,MACF;AACA,+BAAyB,KAAK,eAAe;AAAA,IAC9C;AAEA,QAAI,QAAQ;AACX,kBAAY;AAAA,YACX,2CAAwB;AAAA,UACvB,OAAO,KAAK,cAAc,QAAQ,QAAQ,cAAc,KAAK;AAAA,UAC7D,SAAS;AAAA,YACR,QAAQ,QAAQ,cAAc;AAAA,UAC/B;AAAA,UACA,MAAM;AAAA,YACL,UAAU,QAAQ,cAAc;AAAA,UACjC;AAAA,QACD,CAAC;AAAA,MACF;AAED,QAAI,QAAQ,UAAU;AACrB,cAAQ,SAAS,MAAM,CAAC,MAAM;AAC7B,YAAI,EAAE,EAAE,iBAAiB,iBAAiB;AACzC,gBAAM,IAAI,MAAM,qDAAqD;AAAA,QACtE;AAAA,MACD,CAAC;AAED,YAAM,uBAAuB,KAAK,0BAA0B,QAAQ,QAAQ;AAC5E,qBAAe,eAAe,GAAG,YAAY;AAAA;AAAA,EAAO,oBAAoB,KAAK;AAE7E,uBAAiB,YAAY,QAAQ,SAAS,IAAI,CAAC,MAAM;AACxD,eAAO;AAAA,UACN,MAAM,EAAE;AAAA,UACR,aAAa,EAAE;AAAA,UACf,UAAW,EAAE,MAAyB,kBAAkB;AAAA,QACzD;AAAA,MACD,CAAC;AAAA,IACF;AAEA,QAAI,YAAY,SAAS,EAAG,kBAAiB,aAAa;AAE1D,QAAI,aAAc,kBAAiB,eAAe;AAElD,qBAAiB,2BAA2B;AAC5C,qBAAiB,0BAA0B;AAC3C,qBAAiB,0BAA0B;AAE3C,WAAO,IAAI,eAAe,gBAAgB;AAAA,EAC3C;AACD;;;AIjLO,IAAM,eAAN,MAA6B;AAAA,EAC3B,UAAU,oBAAI,IAA6B;AAAA,EAC3C;AAAA,EAER,YAAY,UAA+B,CAAC,GAAG;AAC9C,SAAK,gBAAgB,QAAQ;AAAA,EAC9B;AAAA,EAEA,iBAAiB,SAAiB,UAAwC;AACzE,SAAK,QAAQ,IAAI,SAAS,EAAE,MAAM,YAAY,SAAS,CAAC;AAAA,EACzD;AAAA,EAEA,cAAc,SAAiB,OAA+B;AAC7D,SAAK,QAAQ,IAAI,SAAS,EAAE,MAAM,UAAU,MAAM,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,SAAS,UAAoB,SAA8C;AAChF,UAAM,UAA4B,CAAC;AAEnC,eAAW,OAAO,UAAU;AAC3B,YAAM,QAAQ,KAAK,QAAQ,IAAI,GAAG;AAClC,UAAI,CAAC,OAAO;AACX,cAAM,IAAI,MAAM,iDAAiD,GAAG,EAAE;AAAA,MACvE;AAEA,UAAI,MAAM,SAAS,UAAU;AAC5B,gBAAQ,KAAK,GAAG,MAAM,KAAK;AAAA,MAC5B,OAAO;AACN,cAAM,WAAW,MAAM;AACvB,cAAM,QAAQ,MAAM,KAAK,gBAAgB,KAAK,UAAU,OAAO;AAC/D,cAAM,QAAQ,MAAM,SAAS,UAAU,OAAO,OAAO;AACrD,gBAAQ,KAAK,GAAG,KAAK;AAAA,MACtB;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,WAAW,SAAuB;AACjC,UAAM,QAAQ,KAAK,QAAQ,IAAI,OAAO;AAEtC,QAAI,SAAS,MAAM,SAAS,WAAY,MAAK,eAAe,IAAI,OAAO;AAAA,EACxE;AAAA,EAEA,MAAc,gBACb,SACA,UACA,SACsB;AACtB,UAAM,QAAQ,KAAK;AAEnB,QAAI,OAAO;AACV,UAAI;AACH,cAAM,SAAS,MAAM,MAAM,IAAI,OAAO;AAEtC,YAAI,OAAQ,QAAO;AAAA,MACpB,SAAS,GAAG;AACX,gBAAQ,MAAM,+CAA+C,CAAC;AAAA,MAC/D;AAAA,IACD;AAEA,UAAM,QAAS,MAAM,SAAS,iBAAiB,SAAS,OAAO,KAAM,CAAC;AAEtE,QAAI,OAAO;AACV,UAAI;AACH,cAAM,MAAM,IAAI,SAAS,KAAK;AAAA,MAC/B,SAAS,GAAG;AACX,gBAAQ,MAAM,+CAA+C,CAAC;AAAA,MAC/D;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AACD;;;AC/FA,qBAAkB;AAClB,iBAAkB;AAUX,IAAM,iBAAN,MAA0C;AAAA,EACxC;AAAA,EAER,YAAY,kBAA0B;AACrC,SAAK,QAAQ,IAAI,eAAAC,QAAM,gBAAgB;AAAA,EACxC;AAAA,EAEA,MAAM,IAAI,SAA6C;AACtD,UAAM,OAAO,MAAM,KAAK,MAAM,IAAI,cAAc,OAAO,EAAE;AAEzD,QAAI,CAAC,KAAM,QAAO;AAElB,QAAI;AACH,YAAM,SAAS,KAAK,MAAM,IAAI;AAE9B,UAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AAEnC,aAAO,OAAO,IAAI,CAAC,UAAe;AAAA,QACjC,GAAG;AAAA,QACH,aAAa,aAAE,eAAe,KAAK,WAAW;AAAA,MAC/C,EAAE;AAAA,IACH,SAAS,GAAG;AACX,cAAQ,MAAM,gCAAgC,CAAC;AAC/C,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,IAAI,SAAiB,OAAkC;AAC5D,UAAM,aAAa,MAAM,IAAI,CAAC,UAAU;AAAA,MACvC,GAAG;AAAA,MACH,aAAa,KAAK,YAAY,aAAa;AAAA,IAC5C,EAAE;AACF,UAAM,KAAK,MAAM,IAAI,cAAc,OAAO,IAAI,KAAK,UAAU,UAAU,CAAC;AAAA,EACzE;AAAA,EAEA,MAAM,IAAI,SAAgC;AACzC,UAAM,KAAK,MAAM,IAAI,cAAc,OAAO,EAAE;AAAA,EAC7C;AACD;AAEO,IAAM,oBAAN,MAA6C;AAAA,EAC3C,QAAQ,oBAAI,IAAwB;AAAA,EAE5C,IAAI,SAAoC;AACvC,WAAO,KAAK,MAAM,IAAI,cAAc,OAAO,EAAE,KAAK;AAAA,EACnD;AAAA,EAEA,MAAM,IAAI,SAAiB,OAAkC;AAC5D,SAAK,MAAM,IAAI,cAAc,OAAO,IAAI,KAAK;AAAA,EAC9C;AAAA,EAEA,MAAM,IAAI,SAAgC;AACzC,SAAK,MAAM,OAAO,cAAc,OAAO,EAAE;AAAA,EAC1C;AACD;","names":["import_deepagents","import_langchain","import_langchain","input","tool","options","Redis"]}
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LangchainModelResolver,
3
3
  convertToLangchainMessages
4
- } from "./chunk-KCENDSNH.mjs";
4
+ } from "./chunk-7F2JW33M.mjs";
5
5
 
6
6
  // src/runtime/langchain/factory.ts
7
7
  import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres";
@@ -95,14 +95,19 @@ var LangchainAgent = class {
95
95
  output_tokens: 0,
96
96
  total_tokens: 0,
97
97
  cache_read: 0,
98
- reasoning_tokens: 0
98
+ reasoning_tokens: 0,
99
+ cache_creation: 0
99
100
  };
100
101
  messagesWithUsage.forEach((m) => {
101
- usage.input_tokens += m.usage_metadata.input_tokens || 0;
102
+ const cacheRead = m.usage_metadata.input_token_details?.cache_read || 0;
103
+ const provider = m.response_metadata?.model_provider;
104
+ const inputTokens = provider === "anthropic" ? m.usage_metadata.input_tokens || 0 : (m.usage_metadata.input_tokens || 0) - cacheRead;
105
+ usage.input_tokens += inputTokens;
102
106
  usage.output_tokens += m.usage_metadata.output_tokens || 0;
103
- usage.total_tokens += m.usage_metadata.total_tokens || 0;
104
- usage.cache_read += m.usage_metadata.input_token_details?.cache_read || 0;
107
+ usage.total_tokens += inputTokens + (m.usage_metadata.output_tokens || 0);
108
+ usage.cache_read += cacheRead;
105
109
  usage.reasoning_tokens += m.usage_metadata.output_token_details?.reasoning || 0;
110
+ usage.cache_creation += m.usage_metadata.input_token_details?.cache_creation || 0;
106
111
  });
107
112
  const contentBlocks = [];
108
113
  const toolCallInputs = {};
@@ -143,7 +148,8 @@ var LangchainAgent = class {
143
148
  completionTokens: usage.output_tokens,
144
149
  totalTokens: usage.total_tokens,
145
150
  cachedPromptTokens: usage.cache_read,
146
- reasoningTokens: usage.reasoning_tokens
151
+ reasoningTokens: usage.reasoning_tokens,
152
+ cacheCreationTokens: usage.cache_creation
147
153
  }
148
154
  };
149
155
  }
@@ -156,7 +162,8 @@ var LangchainAgent = class {
156
162
  completionTokens: 0,
157
163
  totalTokens: 0,
158
164
  cachedPromptTokens: 0,
159
- reasoningTokens: 0
165
+ reasoningTokens: 0,
166
+ cacheCreationTokens: 0
160
167
  };
161
168
  const messages = convertToLangchainMessages(input.messages);
162
169
  debugLogStream("message_start", "");
@@ -218,11 +225,12 @@ var LangchainAgent = class {
218
225
  } else if (this.isReasoningMessage(message)) {
219
226
  const contentArray = message.content;
220
227
  for (const block of contentArray) {
221
- if (block.type === "reasoning" && block.reasoning) {
222
- debugLogStream("reasoning_delta", block.reasoning);
228
+ const delta = block.type === "reasoning" && block.reasoning || block.type === "thinking" && block.thinking;
229
+ if (delta) {
230
+ debugLogStream("reasoning_delta", delta);
223
231
  yield {
224
232
  type: "reasoning_delta",
225
- delta: block.reasoning
233
+ delta
226
234
  };
227
235
  }
228
236
  }
@@ -279,11 +287,15 @@ var LangchainAgent = class {
279
287
  for (let aiChunk of aiMessageChunks) {
280
288
  const um = aiChunk.usage_metadata;
281
289
  if (um) {
282
- usageMetadata.promptTokens += um.input_tokens || 0;
290
+ const cacheRead = um.input_token_details?.cache_read || 0;
291
+ const provider = aiChunk.response_metadata?.model_provider;
292
+ const inputTokens = provider === "anthropic" ? um.input_tokens || 0 : (um.input_tokens || 0) - cacheRead;
293
+ usageMetadata.promptTokens += inputTokens;
283
294
  usageMetadata.completionTokens += um.output_tokens || 0;
284
- usageMetadata.totalTokens += um.total_tokens || 0;
285
- usageMetadata.cachedPromptTokens += um.input_token_details?.cache_read || 0;
295
+ usageMetadata.totalTokens += inputTokens + (um.output_tokens || 0);
296
+ usageMetadata.cachedPromptTokens += cacheRead;
286
297
  usageMetadata.reasoningTokens = (usageMetadata.reasoningTokens || 0) + (um.output_token_details?.reasoning || 0);
298
+ usageMetadata.cacheCreationTokens += um.input_token_details?.cache_creation || 0;
287
299
  }
288
300
  if (aiChunk.tool_calls && aiChunk.tool_calls.length > 0) {
289
301
  for (let tc of aiChunk.tool_calls)
@@ -373,11 +385,11 @@ var LangchainAgent = class {
373
385
  }
374
386
  isReasoningMessage(message) {
375
387
  if (!Array.isArray(message.content)) return false;
376
- return message.content.some((block) => block.type === "reasoning" && block.reasoning);
388
+ return message.content.some((block) => block.type === "reasoning" || block.type === "thinking");
377
389
  }
378
390
  isArrayTextMessage(message) {
379
391
  if (!Array.isArray(message.content)) return false;
380
- return message.content.some((block) => block.type === "text" && block.text);
392
+ return message.content.some((block) => block.type === "text");
381
393
  }
382
394
  /**
383
395
  * Extracts text from message content that may be a string