@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.cjs +224 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -15
- package/dist/index.d.ts +7 -15
- package/dist/index.js +225 -115
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
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
|
|
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
|
|
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,
|
|
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
|
|
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__ */ ((
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
return
|
|
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
|
|
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,
|
|
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
|
|
4932
|
-
const internalToken = this.configService
|
|
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
|
|
4972
|
-
const internalToken = this.configService
|
|
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
|
-
|
|
5107
|
+
{
|
|
5108
|
+
provide: EventProcessor,
|
|
5109
|
+
useFactory: () => new EventProcessor()
|
|
5110
|
+
},
|
|
5131
5111
|
// Graph engines
|
|
5132
|
-
|
|
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: (
|
|
5239
|
-
|
|
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
|
|
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
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
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:
|
|
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()
|