@flutchai/flutch-sdk 0.1.7 → 0.1.9

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.d.cts CHANGED
@@ -9,6 +9,7 @@ import { Registry } from 'prom-client';
9
9
  import { Response, Request } from 'express';
10
10
  import { DiscoveryService, MetadataScanner, ModuleRef } from '@nestjs/core';
11
11
  import { StructuredTool } from '@langchain/core/tools';
12
+ import { RunnableConfig } from '@langchain/core/runnables';
12
13
  import { ChatAnthropic } from '@langchain/anthropic';
13
14
  import { ChatCohere } from '@langchain/cohere';
14
15
  import { ChatMistralAI } from '@langchain/mistralai';
@@ -1135,18 +1136,6 @@ declare class EventProcessor {
1135
1136
  processEvent(acc: StreamAccumulator, event: any, onPartial?: (chunk: string) => void): void;
1136
1137
  getResult(acc: StreamAccumulator): {
1137
1138
  content: IStoredMessageContent;
1138
- metrics: {
1139
- modelCalls: Array<{
1140
- nodeName: string;
1141
- timestamp: number;
1142
- modelId: string;
1143
- promptTokens: number;
1144
- completionTokens: number;
1145
- totalTokens: number;
1146
- latencyMs: number;
1147
- }>;
1148
- apiCalls: any[];
1149
- } | null;
1150
1139
  trace: {
1151
1140
  events: IGraphTraceEvent[];
1152
1141
  startedAt: number;
@@ -1162,9 +1151,9 @@ declare class EventProcessor {
1162
1151
 
1163
1152
  declare class LangGraphEngine implements IGraphEngine {
1164
1153
  private readonly eventProcessor;
1165
- private readonly configService;
1154
+ private readonly configService?;
1166
1155
  private readonly logger;
1167
- constructor(eventProcessor: EventProcessor, configService: ConfigService);
1156
+ constructor(eventProcessor: EventProcessor, configService?: ConfigService);
1168
1157
  invokeGraph(graph: any, config: any, signal?: AbortSignal): Promise<any>;
1169
1158
  streamGraph(graph: any, config: any, onPartial: (chunk: string) => void, signal?: AbortSignal): Promise<any>;
1170
1159
  private sendMetricsWebhook;
@@ -1418,7 +1407,6 @@ declare class McpConverter {
1418
1407
  private readonly mcpRuntimeUrl;
1419
1408
  constructor(mcpRuntimeUrl?: string);
1420
1409
  private jsonSchemaToZod;
1421
- private mapPrimitiveSchema;
1422
1410
  convertTool(mcpTool: McpTool): LangChainStructuredTool;
1423
1411
  convertTools(mcpTools: McpTool[]): Promise<LangChainStructuredTool[]>;
1424
1412
  fetchAndConvertTools(filter?: string): Promise<LangChainStructuredTool[]>;
@@ -1445,6 +1433,10 @@ declare class McpRuntimeHttpClient implements McpRuntimeClient {
1445
1433
  executeTool(name: string, args: any, context?: any): Promise<ToolExecutionResult>;
1446
1434
  getToolStats(): Promise<any>;
1447
1435
  isHealthy(): Promise<boolean>;
1436
+ executeToolWithEvents(toolCallId: string, toolName: string, enrichedArgs: Record<string, any>, executionContext: Record<string, any>, config?: RunnableConfig): Promise<{
1437
+ content: string;
1438
+ success: boolean;
1439
+ }>;
1448
1440
  }
1449
1441
 
1450
1442
  declare enum RetrieverSearchType {
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ import { Registry } from 'prom-client';
9
9
  import { Response, Request } from 'express';
10
10
  import { DiscoveryService, MetadataScanner, ModuleRef } from '@nestjs/core';
11
11
  import { StructuredTool } from '@langchain/core/tools';
12
+ import { RunnableConfig } from '@langchain/core/runnables';
12
13
  import { ChatAnthropic } from '@langchain/anthropic';
13
14
  import { ChatCohere } from '@langchain/cohere';
14
15
  import { ChatMistralAI } from '@langchain/mistralai';
@@ -1135,18 +1136,6 @@ declare class EventProcessor {
1135
1136
  processEvent(acc: StreamAccumulator, event: any, onPartial?: (chunk: string) => void): void;
1136
1137
  getResult(acc: StreamAccumulator): {
1137
1138
  content: IStoredMessageContent;
1138
- metrics: {
1139
- modelCalls: Array<{
1140
- nodeName: string;
1141
- timestamp: number;
1142
- modelId: string;
1143
- promptTokens: number;
1144
- completionTokens: number;
1145
- totalTokens: number;
1146
- latencyMs: number;
1147
- }>;
1148
- apiCalls: any[];
1149
- } | null;
1150
1139
  trace: {
1151
1140
  events: IGraphTraceEvent[];
1152
1141
  startedAt: number;
@@ -1162,9 +1151,9 @@ declare class EventProcessor {
1162
1151
 
1163
1152
  declare class LangGraphEngine implements IGraphEngine {
1164
1153
  private readonly eventProcessor;
1165
- private readonly configService;
1154
+ private readonly configService?;
1166
1155
  private readonly logger;
1167
- constructor(eventProcessor: EventProcessor, configService: ConfigService);
1156
+ constructor(eventProcessor: EventProcessor, configService?: ConfigService);
1168
1157
  invokeGraph(graph: any, config: any, signal?: AbortSignal): Promise<any>;
1169
1158
  streamGraph(graph: any, config: any, onPartial: (chunk: string) => void, signal?: AbortSignal): Promise<any>;
1170
1159
  private sendMetricsWebhook;
@@ -1418,7 +1407,6 @@ declare class McpConverter {
1418
1407
  private readonly mcpRuntimeUrl;
1419
1408
  constructor(mcpRuntimeUrl?: string);
1420
1409
  private jsonSchemaToZod;
1421
- private mapPrimitiveSchema;
1422
1410
  convertTool(mcpTool: McpTool): LangChainStructuredTool;
1423
1411
  convertTools(mcpTools: McpTool[]): Promise<LangChainStructuredTool[]>;
1424
1412
  fetchAndConvertTools(filter?: string): Promise<LangChainStructuredTool[]>;
@@ -1445,6 +1433,10 @@ declare class McpRuntimeHttpClient implements McpRuntimeClient {
1445
1433
  executeTool(name: string, args: any, context?: any): Promise<ToolExecutionResult>;
1446
1434
  getToolStats(): Promise<any>;
1447
1435
  isHealthy(): Promise<boolean>;
1436
+ executeToolWithEvents(toolCallId: string, toolName: string, enrichedArgs: Record<string, any>, executionContext: Record<string, any>, config?: RunnableConfig): Promise<{
1437
+ content: string;
1438
+ success: boolean;
1439
+ }>;
1448
1440
  }
1449
1441
 
1450
1442
  declare enum RetrieverSearchType {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- import { Injectable, Post, UseGuards, Req, Controller, Inject, Get, Body, Res, Param, Logger, Module, UnauthorizedException, Optional, Headers, NotFoundException, InternalServerErrorException, ForbiddenException, ValidationPipe, HttpException, HttpStatus } from '@nestjs/common';
2
+ import { Injectable, Post, UseGuards, Req, Controller, Inject, Get, Body, Res, Param, Logger, Optional, Module, UnauthorizedException, Headers, NotFoundException, InternalServerErrorException, ForbiddenException, ValidationPipe, HttpException, HttpStatus } from '@nestjs/common';
3
3
  import { ApiOperation, ApiResponse, ApiTags, ApiParam, DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
4
4
  import * as fs from 'fs';
5
5
  import * as path2 from 'path';
@@ -13,6 +13,7 @@ import * as LangGraph from '@langchain/langgraph';
13
13
  import { DynamicStructuredTool } from '@langchain/core/tools';
14
14
  import { z } from 'zod';
15
15
  import axios2 from 'axios';
16
+ import { parseCallbackConfigArg, CallbackManager } from '@langchain/core/callbacks/manager';
16
17
  import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
17
18
  import { AzureChatOpenAI } from '@langchain/azure-openai';
18
19
  import { ChatAnthropic } from '@langchain/anthropic';
@@ -3047,9 +3048,6 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
3047
3048
  if (this.manifest?.companySlug && this.manifest?.name) {
3048
3049
  return `${this.manifest.companySlug}.${this.manifest.name}::${this.version}`;
3049
3050
  }
3050
- console.log(
3051
- `DEBUG graphType: manifest=${!!this.manifest}, companySlug=${this.manifest?.companySlug}, name=${this.manifest?.name}, version=${this.version}`
3052
- );
3053
3051
  return `unknown::${this.version}`;
3054
3052
  }
3055
3053
  /**
@@ -3381,6 +3379,9 @@ var UniversalGraphService = class {
3381
3379
  this.engine = engine;
3382
3380
  this.endpointRegistry = endpointRegistry;
3383
3381
  this.logger.log("UniversalGraphService initialized");
3382
+ if (!this.engine) {
3383
+ this.logger.error("GRAPH_ENGINE is not properly injected!");
3384
+ }
3384
3385
  }
3385
3386
  logger = new Logger(UniversalGraphService.name);
3386
3387
  /**
@@ -4301,7 +4302,7 @@ function sanitizeTraceData(value, depth = 0, seen = /* @__PURE__ */ new WeakSet(
4301
4302
  return null;
4302
4303
  }
4303
4304
  if (typeof value === "string") {
4304
- return value.length > opts.maxStringLength ? `${value.slice(0, opts.maxStringLength)}\u2026` : value;
4305
+ return value;
4305
4306
  }
4306
4307
  if (typeof value === "number" || typeof value === "boolean") {
4307
4308
  return value;
@@ -4376,11 +4377,11 @@ function sanitizeTraceError(error, options) {
4376
4377
  raw: sanitizeTraceData(error, 0, /* @__PURE__ */ new WeakSet(), options)
4377
4378
  };
4378
4379
  }
4379
- var GraphEngineType = /* @__PURE__ */ ((GraphEngineType2) => {
4380
- GraphEngineType2["LANGGRAPH"] = "langgraph";
4381
- GraphEngineType2["LANGFLOW"] = "langflow";
4382
- GraphEngineType2["FLOWISE"] = "flowise";
4383
- return GraphEngineType2;
4380
+ var GraphEngineType = /* @__PURE__ */ ((GraphEngineType3) => {
4381
+ GraphEngineType3["LANGGRAPH"] = "langgraph";
4382
+ GraphEngineType3["LANGFLOW"] = "langflow";
4383
+ GraphEngineType3["FLOWISE"] = "flowise";
4384
+ return GraphEngineType3;
4384
4385
  })(GraphEngineType || {});
4385
4386
  var GraphEngineFactory = class {
4386
4387
  constructor(langgraph) {
@@ -4557,6 +4558,31 @@ var EventProcessor = class {
4557
4558
  }
4558
4559
  return;
4559
4560
  }
4561
+ if (event.event === "on_tool_start") {
4562
+ this.logger.log("\u{1F527} Tool execution started", {
4563
+ toolName: event.name,
4564
+ input: event.data?.input,
4565
+ runId: event.run_id,
4566
+ metadata: event.metadata
4567
+ });
4568
+ return;
4569
+ }
4570
+ if (event.event === "on_tool_end") {
4571
+ this.logger.log("\u2705 Tool execution completed", {
4572
+ toolName: event.name,
4573
+ output: typeof event.data?.output === "string" ? event.data.output.substring(0, 200) + (event.data.output.length > 200 ? "..." : "") : event.data?.output,
4574
+ runId: event.run_id
4575
+ });
4576
+ return;
4577
+ }
4578
+ if (event.event === "on_tool_error") {
4579
+ this.logger.error("\u274C Tool execution failed", {
4580
+ toolName: event.name,
4581
+ error: event.data?.error,
4582
+ runId: event.run_id
4583
+ });
4584
+ return;
4585
+ }
4560
4586
  if (event.event === "on_chat_model_end") {
4561
4587
  const output = event.data?.output;
4562
4588
  const usageMetadata = output?.usage_metadata || output?.usageMetadata;
@@ -4682,42 +4708,9 @@ var EventProcessor = class {
4682
4708
  /**
4683
4709
  * Build final result from accumulator
4684
4710
  * Uses generation if available, otherwise falls back to streamed text
4685
- * Returns content and metrics separately (metrics should NOT be stored in message.metadata)
4711
+ * Returns content and trace events (metrics should be extracted from trace on backend)
4686
4712
  */
4687
4713
  getResult(acc) {
4688
- const totalPromptTokens = acc.llmCalls.reduce(
4689
- (sum, call) => sum + call.promptTokens,
4690
- 0
4691
- );
4692
- const totalCompletionTokens = acc.llmCalls.reduce(
4693
- (sum, call) => sum + call.completionTokens,
4694
- 0
4695
- );
4696
- const totalTokens = acc.llmCalls.reduce(
4697
- (sum, call) => sum + call.totalTokens,
4698
- 0
4699
- );
4700
- this.logger.log("\u{1F4CA} Final metrics collected", {
4701
- llmCallsCount: acc.llmCalls.length,
4702
- totalPromptTokens,
4703
- totalCompletionTokens,
4704
- totalTokens,
4705
- modelIds: acc.llmCalls.map((c) => c.modelId)
4706
- });
4707
- const metrics = acc.llmCalls.length > 0 ? {
4708
- modelCalls: acc.llmCalls.map((call) => ({
4709
- nodeName: call.nodeName || "unknown",
4710
- timestamp: call.timestamp,
4711
- modelId: call.modelId,
4712
- promptTokens: call.promptTokens,
4713
- completionTokens: call.completionTokens,
4714
- totalTokens: call.totalTokens,
4715
- latencyMs: 0
4716
- // Not calculated from events
4717
- })),
4718
- apiCalls: []
4719
- // TODO: Add API calls tracking (rerank, embeddings) via custom events
4720
- } : null;
4721
4714
  const startedAt = acc.traceStartedAt ?? Date.now();
4722
4715
  const completedAt = acc.traceCompletedAt ?? startedAt;
4723
4716
  const trace = acc.traceEvents.length > 0 ? {
@@ -4746,7 +4739,6 @@ var EventProcessor = class {
4746
4739
  metadata: acc.generation?.metadata || {},
4747
4740
  reasoningChains: acc.reasoningChains.length > 0 ? acc.reasoningChains : void 0
4748
4741
  },
4749
- metrics,
4750
4742
  trace
4751
4743
  };
4752
4744
  }
@@ -4826,6 +4818,9 @@ var LangGraphEngine = class {
4826
4818
  constructor(eventProcessor, configService) {
4827
4819
  this.eventProcessor = eventProcessor;
4828
4820
  this.configService = configService;
4821
+ if (!eventProcessor) {
4822
+ this.logger.error("EventProcessor is undefined/null!");
4823
+ }
4829
4824
  }
4830
4825
  logger = new Logger(LangGraphEngine.name);
4831
4826
  /**
@@ -4858,33 +4853,14 @@ var LangGraphEngine = class {
4858
4853
  );
4859
4854
  }
4860
4855
  }
4861
- const { content, metrics, trace } = this.eventProcessor.getResult(acc);
4856
+ const { content, trace } = this.eventProcessor.getResult(acc);
4862
4857
  this.logger.debug("[STREAM-RESULT] Got result from EventProcessor", {
4863
4858
  hasContent: !!content,
4864
- hasMetrics: !!metrics,
4865
- modelCallsCount: metrics?.modelCalls?.length || 0,
4866
- apiCallsCount: metrics?.apiCalls?.length || 0,
4867
4859
  hasContext: !!config.configurable?.context,
4868
4860
  hasTrace: !!trace,
4869
- traceEvents: trace?.events?.length || 0
4861
+ traceEvents: trace?.events?.length || 0,
4862
+ totalModelCalls: trace?.totalModelCalls || 0
4870
4863
  });
4871
- if (metrics && metrics.modelCalls?.length > 0 && config.configurable?.context) {
4872
- const context = config.configurable.context;
4873
- await this.sendMetricsWebhook({
4874
- messageId: context.messageId || "unknown",
4875
- threadId: context.threadId || "unknown",
4876
- userId: context.userId || "unknown",
4877
- agentId: context.agentId || "unknown",
4878
- companyId: context.companyId || "unknown",
4879
- metrics
4880
- });
4881
- } else {
4882
- this.logger.debug("[METRICS-WEBHOOK] Skipping webhook", {
4883
- hasMetrics: !!metrics,
4884
- modelCallsCount: metrics?.modelCalls?.length || 0,
4885
- hasContext: !!config.configurable?.context
4886
- });
4887
- }
4888
4864
  if (trace && trace.events.length > 0 && config.configurable?.context) {
4889
4865
  const context = config.configurable.context;
4890
4866
  this.logger.debug("[TRACE-WEBHOOK] Sending trace events batch", {
@@ -4928,8 +4904,8 @@ var LangGraphEngine = class {
4928
4904
  */
4929
4905
  async sendMetricsWebhook(payload) {
4930
4906
  try {
4931
- const backendUrl = this.configService.get("API_URL") || "http://amelie-service";
4932
- const internalToken = this.configService.get("INTERNAL_API_TOKEN");
4907
+ const backendUrl = this.configService?.get("API_URL") || "http://amelie-service";
4908
+ const internalToken = this.configService?.get("INTERNAL_API_TOKEN");
4933
4909
  if (!internalToken) {
4934
4910
  this.logger.warn(
4935
4911
  "[METRICS-WEBHOOK] INTERNAL_API_TOKEN not configured, skipping webhook"
@@ -4968,8 +4944,8 @@ var LangGraphEngine = class {
4968
4944
  }
4969
4945
  async sendTraceEventsBatch(payload) {
4970
4946
  try {
4971
- const backendUrl = this.configService.get("API_URL") || "http://amelie-service";
4972
- const internalToken = this.configService.get("INTERNAL_API_TOKEN");
4947
+ const backendUrl = this.configService?.get("API_URL") || "http://amelie-service";
4948
+ const internalToken = this.configService?.get("INTERNAL_API_TOKEN");
4973
4949
  if (!internalToken) {
4974
4950
  this.logger.warn(
4975
4951
  "[TRACE-EVENTS-BATCH] INTERNAL_API_TOKEN not configured, skipping batch webhook"
@@ -5051,7 +5027,8 @@ var LangGraphEngine = class {
5051
5027
  }
5052
5028
  };
5053
5029
  LangGraphEngine = __decorateClass([
5054
- Injectable()
5030
+ Injectable(),
5031
+ __decorateParam(1, Optional())
5055
5032
  ], LangGraphEngine);
5056
5033
 
5057
5034
  // src/core/universal-graph.module.ts
@@ -5127,9 +5104,16 @@ var UniversalGraphModule = class {
5127
5104
  // Discovery services from @nestjs/core
5128
5105
  MetadataScanner,
5129
5106
  // Event processor for stream handling
5130
- EventProcessor,
5107
+ {
5108
+ provide: EventProcessor,
5109
+ useFactory: () => new EventProcessor()
5110
+ },
5131
5111
  // Graph engines
5132
- LangGraphEngine,
5112
+ {
5113
+ provide: LangGraphEngine,
5114
+ useFactory: (eventProcessor) => new LangGraphEngine(eventProcessor, void 0),
5115
+ inject: [EventProcessor]
5116
+ },
5133
5117
  BuilderRegistryService,
5134
5118
  GraphEngineFactory,
5135
5119
  VersionedGraphService,
@@ -5235,12 +5219,8 @@ var UniversalGraphModule = class {
5235
5219
  },
5236
5220
  {
5237
5221
  provide: "GRAPH_ENGINE",
5238
- useFactory: (factory) => {
5239
- return factory.getEngine(
5240
- options.engineType || "langgraph" /* LANGGRAPH */
5241
- );
5242
- },
5243
- inject: [GraphEngineFactory]
5222
+ useFactory: (langGraphEngine) => langGraphEngine,
5223
+ inject: [LangGraphEngine]
5244
5224
  },
5245
5225
  {
5246
5226
  provide: "GRAPH_BUILDERS",
@@ -5360,47 +5340,65 @@ var McpConverter = class _McpConverter {
5360
5340
  mcpRuntimeUrl;
5361
5341
  constructor(mcpRuntimeUrl = "http://localhost:3004") {
5362
5342
  this.mcpRuntimeUrl = mcpRuntimeUrl;
5343
+ this.logger.log(
5344
+ `\u{1F527} McpConverter initialized with SDK version 0.1.8 (manual jsonSchemaToZod)`
5345
+ );
5363
5346
  }
5364
5347
  /**
5365
- * Convert JSON Schema to simplified Zod schema for LangChain
5348
+ * Convert JSON Schema to Zod schema manually
5349
+ * This creates a standard Zod schema that zodToJsonSchema can convert back properly
5366
5350
  */
5367
5351
  jsonSchemaToZod(jsonSchema) {
5368
5352
  if (!jsonSchema || typeof jsonSchema !== "object") {
5369
5353
  return z.any();
5370
5354
  }
5371
- if (jsonSchema.type !== "object") {
5372
- return this.mapPrimitiveSchema(jsonSchema.type, true);
5373
- }
5374
- const properties = jsonSchema.properties || {};
5375
- const required = Array.isArray(jsonSchema.required) ? jsonSchema.required : [];
5376
- const zodShape = {};
5377
- for (const [key, prop] of Object.entries(properties)) {
5378
- const propDef = prop;
5379
- const isRequired = required.includes(key);
5380
- const schemaType = propDef?.type ?? "any";
5381
- const mappedType = this.mapPrimitiveSchema(schemaType, isRequired);
5382
- zodShape[key] = mappedType;
5383
- }
5384
- const baseObject = z.object(zodShape);
5385
- const configuredObject = jsonSchema.additionalProperties === false ? baseObject.strict() : baseObject.passthrough();
5386
- return configuredObject;
5387
- }
5388
- mapPrimitiveSchema(type, required) {
5389
- const optionalize = (schema) => required ? schema : schema.optional();
5390
- switch (type) {
5391
- case "string":
5392
- return optionalize(z.string());
5393
- case "number":
5394
- case "integer":
5395
- return optionalize(z.number());
5396
- case "boolean":
5397
- return optionalize(z.boolean());
5398
- case "array":
5399
- return optionalize(z.array(z.any()));
5400
- case "object":
5401
- return optionalize(z.record(z.any()));
5402
- default:
5403
- return optionalize(z.any());
5355
+ try {
5356
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
5357
+ const shape = {};
5358
+ for (const [key, propSchema] of Object.entries(jsonSchema.properties)) {
5359
+ const prop = propSchema;
5360
+ let zodProp;
5361
+ switch (prop.type) {
5362
+ case "string":
5363
+ zodProp = z.string();
5364
+ break;
5365
+ case "number":
5366
+ zodProp = z.number();
5367
+ break;
5368
+ case "boolean":
5369
+ zodProp = z.boolean();
5370
+ break;
5371
+ case "integer":
5372
+ zodProp = z.number().int();
5373
+ break;
5374
+ case "array":
5375
+ zodProp = z.array(z.any());
5376
+ break;
5377
+ case "object":
5378
+ zodProp = z.record(z.any());
5379
+ break;
5380
+ default:
5381
+ zodProp = z.any();
5382
+ }
5383
+ if (prop.description) {
5384
+ zodProp = zodProp.describe(prop.description);
5385
+ }
5386
+ if (!jsonSchema.required?.includes(key)) {
5387
+ zodProp = zodProp.optional();
5388
+ }
5389
+ shape[key] = zodProp;
5390
+ }
5391
+ return z.object(shape);
5392
+ }
5393
+ this.logger.warn(
5394
+ `Unsupported JSON Schema structure, falling back to z.any()`
5395
+ );
5396
+ return z.any();
5397
+ } catch (error) {
5398
+ this.logger.warn(
5399
+ `Failed to convert JSON Schema, falling back to z.any(): ${error}`
5400
+ );
5401
+ return z.any();
5404
5402
  }
5405
5403
  }
5406
5404
  /**
@@ -5409,6 +5407,27 @@ var McpConverter = class _McpConverter {
5409
5407
  convertTool(mcpTool) {
5410
5408
  const logger2 = this.logger;
5411
5409
  const mcpRuntimeUrl = this.mcpRuntimeUrl;
5410
+ let enhancedDescription = mcpTool.description;
5411
+ if (mcpTool.inputSchema?.properties) {
5412
+ const paramDescriptions = [];
5413
+ for (const [key, propSchema] of Object.entries(
5414
+ mcpTool.inputSchema.properties
5415
+ )) {
5416
+ const prop = propSchema;
5417
+ if (prop.description) {
5418
+ const isRequired = mcpTool.inputSchema.required?.includes(key);
5419
+ paramDescriptions.push(
5420
+ `- ${key}${isRequired ? " (required)" : ""}: ${prop.description}`
5421
+ );
5422
+ }
5423
+ }
5424
+ if (paramDescriptions.length > 0) {
5425
+ enhancedDescription = `${mcpTool.description}
5426
+
5427
+ Parameters:
5428
+ ${paramDescriptions.join("\n")}`;
5429
+ }
5430
+ }
5412
5431
  const schema = this.jsonSchemaToZod(mcpTool.inputSchema);
5413
5432
  logger2.debug(
5414
5433
  `\u{1F527} [${mcpTool.name}] Original schema:`,
@@ -5417,9 +5436,48 @@ var McpConverter = class _McpConverter {
5417
5436
  logger2.debug(
5418
5437
  `\u{1F527} [${mcpTool.name}] Using schema type: ${schema?._def?.typeName ?? "unknown"}`
5419
5438
  );
5439
+ if (schema?._def?.shape && typeof schema._def.shape === "function") {
5440
+ try {
5441
+ const shape = schema._def.shape();
5442
+ logger2.debug(
5443
+ `\u{1F527} [${mcpTool.name}] Converted Zod schema shape:`,
5444
+ JSON.stringify(
5445
+ Object.entries(shape).reduce(
5446
+ (acc, [key, val]) => {
5447
+ acc[key] = {
5448
+ type: val?._def?.typeName,
5449
+ description: val?._def?.description,
5450
+ optional: val?._def?.typeName === "ZodOptional"
5451
+ };
5452
+ return acc;
5453
+ },
5454
+ {}
5455
+ ),
5456
+ null,
5457
+ 2
5458
+ )
5459
+ );
5460
+ } catch (error) {
5461
+ logger2.debug(
5462
+ `\u{1F527} [${mcpTool.name}] Could not extract Zod schema shape: ${error}`
5463
+ );
5464
+ }
5465
+ }
5466
+ try {
5467
+ const { zodToJsonSchema } = __require("zod-to-json-schema");
5468
+ const convertedJsonSchema = zodToJsonSchema(schema);
5469
+ logger2.warn(
5470
+ `\u{1F527} [${mcpTool.name}] JSON Schema that LangChain will use:`,
5471
+ JSON.stringify(convertedJsonSchema, null, 2)
5472
+ );
5473
+ } catch (error) {
5474
+ logger2.warn(
5475
+ `\u{1F527} [${mcpTool.name}] Could not convert Zod to JSON Schema: ${error}`
5476
+ );
5477
+ }
5420
5478
  return new DynamicStructuredTool({
5421
5479
  name: mcpTool.name,
5422
- description: mcpTool.description,
5480
+ description: enhancedDescription,
5423
5481
  schema,
5424
5482
  func: async (input) => {
5425
5483
  logger2.log(`\u{1F527} [${mcpTool.name}] LLM INPUT: ${JSON.stringify(input)}`);
@@ -5736,6 +5794,58 @@ var McpRuntimeHttpClient = class {
5736
5794
  return false;
5737
5795
  }
5738
5796
  }
5797
+ /**
5798
+ * Execute tool with LangChain event emission
5799
+ * @param toolCallId - Tool call ID from LLM
5800
+ * @param toolName - Tool name
5801
+ * @param enrichedArgs - Merged arguments (toolConfig + LLM args)
5802
+ * @param executionContext - Execution context (userId, agentId, etc.)
5803
+ * @param config - RunnableConfig with callbacks
5804
+ * @returns Tool execution result with content
5805
+ */
5806
+ async executeToolWithEvents(toolCallId, toolName, enrichedArgs, executionContext, config) {
5807
+ const parsedConfig = parseCallbackConfigArg(config);
5808
+ const callbackManager = CallbackManager.configure(parsedConfig.callbacks);
5809
+ let runManager;
5810
+ try {
5811
+ runManager = await callbackManager?.handleToolStart(
5812
+ {
5813
+ name: toolName,
5814
+ lc: 1,
5815
+ type: "not_implemented",
5816
+ id: ["langchain", "tools", "mcp", toolName]
5817
+ },
5818
+ JSON.stringify(enrichedArgs),
5819
+ parsedConfig.runId,
5820
+ void 0,
5821
+ parsedConfig.tags,
5822
+ parsedConfig.metadata,
5823
+ toolName
5824
+ );
5825
+ const result = await this.executeTool(
5826
+ toolName,
5827
+ enrichedArgs,
5828
+ executionContext
5829
+ );
5830
+ const content = result.success ? JSON.stringify(result) : result.error || JSON.stringify(result);
5831
+ await runManager?.handleToolEnd(content);
5832
+ return {
5833
+ content,
5834
+ success: result.success
5835
+ };
5836
+ } catch (error) {
5837
+ this.logger.error(`Error executing tool ${toolName}:`, error);
5838
+ await runManager?.handleToolError(error);
5839
+ const errorContent = JSON.stringify({
5840
+ success: false,
5841
+ error: error instanceof Error ? error.message : "Tool execution failed"
5842
+ });
5843
+ return {
5844
+ content: errorContent,
5845
+ success: false
5846
+ };
5847
+ }
5848
+ }
5739
5849
  };
5740
5850
  McpRuntimeHttpClient = __decorateClass([
5741
5851
  Injectable()