@flutchai/flutch-sdk 0.1.10 → 0.1.11

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 CHANGED
@@ -5545,37 +5545,43 @@ var McpToolFilter = class _McpToolFilter {
5545
5545
  logger = new common.Logger(_McpToolFilter.name);
5546
5546
  mcpConverter;
5547
5547
  /**
5548
- * Fetch available tools from MCP runtime with optional filtering
5549
- * @param enabledTools Array of tool names to filter for
5550
- * @returns Array of LangChain Tool instances
5548
+ * Fetch available tools from MCP runtime with dynamic schema generation
5549
+ * @param toolsConfig Array of tool configurations with dynamic config
5550
+ * @returns Array of LangChain Tool instances with dynamic schemas
5551
5551
  */
5552
- async getFilteredTools(enabledTools = []) {
5552
+ async getFilteredTools(toolsConfig = []) {
5553
5553
  this.logger.debug(
5554
- `[DEBUG] Getting filtered tools. Enabled: ${enabledTools.join(", ")}`
5554
+ `[DEBUG] Getting filtered tools with dynamic schemas. Config: ${JSON.stringify(toolsConfig)}`
5555
5555
  );
5556
5556
  this.logger.debug(`[DEBUG] MCP Runtime URL: ${this.mcpRuntimeUrl}`);
5557
- if (enabledTools.length === 0) {
5558
- this.logger.debug("No tools enabled, returning empty array");
5557
+ if (toolsConfig.length === 0) {
5558
+ this.logger.debug("No tools configured, returning empty array");
5559
5559
  return [];
5560
5560
  }
5561
5561
  try {
5562
- const filterParam = enabledTools.join(",");
5563
5562
  this.logger.debug(
5564
- `[DEBUG] Making HTTP request to: ${this.mcpRuntimeUrl}/tools/list with filter: ${filterParam}`
5563
+ `[DEBUG] Making HTTP POST request to: ${this.mcpRuntimeUrl}/tools/schemas`
5564
+ );
5565
+ this.logger.debug(`[DEBUG] Request body: ${JSON.stringify(toolsConfig)}`);
5566
+ const response = await axios2__default.default.post(
5567
+ `${this.mcpRuntimeUrl}/tools/schemas`,
5568
+ { tools: toolsConfig },
5569
+ {
5570
+ timeout: 5e3,
5571
+ headers: {
5572
+ "Content-Type": "application/json"
5573
+ }
5574
+ }
5565
5575
  );
5566
- const response = await axios2__default.default.get(`${this.mcpRuntimeUrl}/tools/list`, {
5567
- params: { filter: filterParam },
5568
- timeout: 5e3
5569
- });
5570
5576
  this.logger.debug(
5571
5577
  `[DEBUG] HTTP response status: ${response.status}, data length: ${Array.isArray(response.data) ? response.data.length : "not array"}`
5572
5578
  );
5573
- const filteredTools = Array.isArray(response.data) ? response.data : [];
5579
+ const dynamicTools = Array.isArray(response.data) ? response.data : [];
5574
5580
  this.logger.debug(
5575
- `Retrieved ${filteredTools.length} filtered MCP tools for: ${enabledTools.join(", ")}`
5581
+ `Retrieved ${dynamicTools.length} dynamic tool schemas from MCP Runtime`
5576
5582
  );
5577
5583
  const mcpClient = {
5578
- getTools: async () => filteredTools,
5584
+ getTools: async () => dynamicTools,
5579
5585
  executeTool: async (name, args) => {
5580
5586
  this.logger.debug(`[DEBUG] Executing tool ${name} with args:`, args);
5581
5587
  const response2 = await axios2__default.default.post(
@@ -5590,20 +5596,20 @@ var McpToolFilter = class _McpToolFilter {
5590
5596
  isHealthy: async () => true
5591
5597
  };
5592
5598
  this.logger.log(
5593
- `\u{1F680} [McpToolFilter] Converting ${filteredTools.length} tools using new McpConverter`
5599
+ `\u{1F680} [McpToolFilter] Converting ${dynamicTools.length} dynamic tools using McpConverter`
5594
5600
  );
5595
- const tools = await this.mcpConverter.convertTools(filteredTools);
5601
+ const tools = await this.mcpConverter.convertTools(dynamicTools);
5596
5602
  this.logger.log(
5597
5603
  `\u{1F680} [McpToolFilter] Converted tools: ${tools.map((t) => t.name).join(", ")}`
5598
5604
  );
5599
5605
  this.logger.log(
5600
- `Configured ${tools.length} tools from MCP runtime: ${filteredTools.map((t) => t.name).join(", ")}`
5606
+ `Configured ${tools.length} tools with dynamic schemas from MCP runtime: ${dynamicTools.map((t) => t.name).join(", ")}`
5601
5607
  );
5602
5608
  return tools;
5603
5609
  } catch (error) {
5604
5610
  const errorMessage = error instanceof Error ? error.message : String(error);
5605
5611
  this.logger.warn(
5606
- `[DEBUG] Failed to fetch tools from MCP runtime (${this.mcpRuntimeUrl}): ${errorMessage}`
5612
+ `[DEBUG] Failed to fetch dynamic tool schemas from MCP runtime (${this.mcpRuntimeUrl}): ${errorMessage}`
5607
5613
  );
5608
5614
  this.logger.warn(`[DEBUG] Error details:`, {
5609
5615
  error,
@@ -6148,8 +6154,30 @@ var ModelInitializer = class _ModelInitializer {
6148
6154
  /**
6149
6155
  * Generate cache key for model instances based on configuration
6150
6156
  */
6151
- generateModelCacheKey(modelId, temperature, maxTokens, modelType) {
6152
- return `${modelId}:${temperature || "default"}:${maxTokens || "default"}:${modelType || "chat" /* CHAT */}`;
6157
+ /**
6158
+ * Generate hash from toolsConfig for cache key
6159
+ * Uses MD5 hash to create short, unique identifier
6160
+ */
6161
+ hashToolsConfig(toolsConfig) {
6162
+ const sorted = toolsConfig.map((t) => `${t.toolName}:${t.enabled}:${JSON.stringify(t.config || {})}`).sort().join("|");
6163
+ return crypto.createHash("md5").update(sorted).digest("hex").slice(0, 16);
6164
+ }
6165
+ /**
6166
+ * Generate cache key from ModelByIdConfig
6167
+ * Format: modelId:temperature:maxTokens[:toolsHash]
6168
+ * Example: "model123:0.7:4096" or "model123:0.7:4096:a1b2c3d4e5f6g7h8"
6169
+ */
6170
+ generateModelCacheKey(config) {
6171
+ const parts = [
6172
+ config.modelId,
6173
+ config.temperature ?? "default",
6174
+ config.maxTokens ?? "default"
6175
+ ];
6176
+ if (config.toolsConfig && config.toolsConfig.length > 0) {
6177
+ const toolsHash = this.hashToolsConfig(config.toolsConfig);
6178
+ parts.push(toolsHash);
6179
+ }
6180
+ return parts.join(":");
6153
6181
  }
6154
6182
  /**
6155
6183
  * TEMPORARY SOLUTION for compatibility with new OpenAI models
@@ -6386,12 +6414,7 @@ var ModelInitializer = class _ModelInitializer {
6386
6414
  ["voyageai" /* VOYAGEAI */]: void 0
6387
6415
  };
6388
6416
  async initializeChatModel(config) {
6389
- const cacheKey = this.generateModelCacheKey(
6390
- config.modelId,
6391
- config.temperature,
6392
- config.maxTokens,
6393
- "chat" /* CHAT */
6394
- );
6417
+ const cacheKey = this.generateModelCacheKey(config);
6395
6418
  const cachedModel = this.modelInstanceCache.get(cacheKey);
6396
6419
  if (cachedModel) {
6397
6420
  this.logger.debug(`Using cached chat model instance: ${cacheKey}`);
@@ -6429,17 +6452,70 @@ var ModelInitializer = class _ModelInitializer {
6429
6452
  metadataKeys: Object.keys(model.metadata || {}),
6430
6453
  hasModelId: !!model.metadata?.modelId
6431
6454
  });
6455
+ this.logger.debug(`[TOOLS CHECK] toolsConfig exists: ${!!config.toolsConfig}, customTools exists: ${!!config.customTools}`);
6456
+ if (config.toolsConfig) {
6457
+ this.logger.debug(`[TOOLS CHECK] toolsConfig length: ${config.toolsConfig.length}, content: ${JSON.stringify(config.toolsConfig)}`);
6458
+ }
6459
+ if (config.toolsConfig || config.customTools) {
6460
+ this.logger.debug(`[TOOLS] Calling bindToolsToModel with toolsConfig: ${JSON.stringify(config.toolsConfig)}`);
6461
+ const boundModel = await this.bindToolsToModel(
6462
+ model,
6463
+ config.toolsConfig,
6464
+ config.customTools
6465
+ );
6466
+ this.logger.debug(`[TOOLS] bindToolsToModel returned successfully`);
6467
+ this.modelInstanceCache.set(cacheKey, boundModel);
6468
+ return boundModel;
6469
+ }
6432
6470
  this.modelInstanceCache.set(cacheKey, model);
6433
6471
  return model;
6434
6472
  }
6473
+ /**
6474
+ * Bind tools to model (merge toolsConfig and customTools)
6475
+ * For toolsConfig: fetch tool executors from MCP Runtime
6476
+ * For customTools: use as-is (already prepared DynamicStructuredTool)
6477
+ *
6478
+ * Returns:
6479
+ * - Runnable when tools are bound (model.bindTools returns Runnable)
6480
+ * - BaseChatModel when no tools
6481
+ */
6482
+ async bindToolsToModel(model, toolsConfig, customTools) {
6483
+ const allTools = [];
6484
+ if (toolsConfig && toolsConfig.length > 0) {
6485
+ try {
6486
+ const enabledToolsConfig = toolsConfig.filter((tc) => tc.enabled !== false);
6487
+ if (enabledToolsConfig.length > 0) {
6488
+ this.logger.debug(
6489
+ `Fetching ${enabledToolsConfig.length} tools with dynamic schemas from MCP Runtime: ${enabledToolsConfig.map((tc) => tc.toolName).join(", ")}`
6490
+ );
6491
+ const mcpToolFilter = new McpToolFilter();
6492
+ const mcpTools = await mcpToolFilter.getFilteredTools(
6493
+ enabledToolsConfig
6494
+ );
6495
+ this.logger.debug(
6496
+ `Successfully fetched ${mcpTools.length} tools with dynamic schemas from MCP Runtime`
6497
+ );
6498
+ allTools.push(...mcpTools);
6499
+ }
6500
+ } catch (error) {
6501
+ this.logger.error(
6502
+ `Failed to fetch tools from MCP Runtime: ${error instanceof Error ? error.message : String(error)}`
6503
+ );
6504
+ }
6505
+ }
6506
+ if (customTools && customTools.length > 0) {
6507
+ allTools.push(...customTools);
6508
+ this.logger.debug(`Added ${customTools.length} custom tools to model`);
6509
+ }
6510
+ if (allTools.length > 0) {
6511
+ this.logger.debug(`Binding ${allTools.length} tools to model`);
6512
+ const modelWithTools = model.bindTools(allTools);
6513
+ return modelWithTools;
6514
+ }
6515
+ return model;
6516
+ }
6435
6517
  async initializeRerankModel(config) {
6436
- const cacheKey = this.generateModelCacheKey(
6437
- config.modelId,
6438
- void 0,
6439
- // rerank models typically don't use temperature
6440
- config.maxTokens,
6441
- "rerank" /* RERANK */
6442
- );
6518
+ const cacheKey = this.generateModelCacheKey(config);
6443
6519
  const cachedModel = this.modelInstanceCache.get(cacheKey);
6444
6520
  if (cachedModel) {
6445
6521
  this.logger.debug(`Using cached rerank model instance: ${cacheKey}`);
@@ -6467,14 +6543,7 @@ var ModelInitializer = class _ModelInitializer {
6467
6543
  return model;
6468
6544
  }
6469
6545
  async initializeEmbeddingModel(config) {
6470
- const cacheKey = this.generateModelCacheKey(
6471
- config.modelId,
6472
- void 0,
6473
- // embedding models typically don't use temperature
6474
- void 0,
6475
- // embedding models typically don't use maxTokens
6476
- "embedding" /* EMBEDDING */
6477
- );
6546
+ const cacheKey = this.generateModelCacheKey(config);
6478
6547
  const cachedModel = this.modelInstanceCache.get(cacheKey);
6479
6548
  if (cachedModel) {
6480
6549
  this.logger.debug(`Using cached embedding model instance: ${cacheKey}`);
@@ -6622,7 +6691,7 @@ var ModelInitializer = class _ModelInitializer {
6622
6691
  }
6623
6692
  // Simple API request for microservices (copy from original LLMInitializer)
6624
6693
  async fetchFromApi(modelId) {
6625
- const apiUrl = process.env.API_URL || "http://amelie-service";
6694
+ const apiUrl = process.env.API_URL;
6626
6695
  const token = process.env.INTERNAL_API_TOKEN;
6627
6696
  if (!token) {
6628
6697
  throw new Error("INTERNAL_API_TOKEN required for API mode");
@@ -6666,40 +6735,6 @@ var ModelInitializer = class _ModelInitializer {
6666
6735
  return result;
6667
6736
  }
6668
6737
  };
6669
- function prepareModelWithTools(model, tools, baseConfig = {}) {
6670
- if (tools.length === 0) {
6671
- return {
6672
- modelWithTools: model,
6673
- finalConfig: baseConfig,
6674
- toolsMethod: "none"
6675
- };
6676
- }
6677
- if (model.bindTools && typeof model.bindTools === "function") {
6678
- try {
6679
- const modelWithTools = model.bindTools(tools);
6680
- return {
6681
- modelWithTools,
6682
- finalConfig: baseConfig,
6683
- toolsMethod: "bindTools"
6684
- };
6685
- } catch (error) {
6686
- const invokeConfig2 = { tools };
6687
- const finalConfig2 = { ...baseConfig, ...invokeConfig2 };
6688
- return {
6689
- modelWithTools: model,
6690
- finalConfig: finalConfig2,
6691
- toolsMethod: "manual"
6692
- };
6693
- }
6694
- }
6695
- const invokeConfig = { tools };
6696
- const finalConfig = { ...baseConfig, ...invokeConfig };
6697
- return {
6698
- modelWithTools: model,
6699
- finalConfig,
6700
- toolsMethod: "manual"
6701
- };
6702
- }
6703
6738
 
6704
6739
  // src/retriever/enums.ts
6705
6740
  var RetrieverSearchType = /* @__PURE__ */ ((RetrieverSearchType2) => {
@@ -7049,7 +7084,6 @@ exports.getUIEndpointClassMetadata = getUIEndpointClassMetadata;
7049
7084
  exports.getUIEndpointMethodsMetadata = getUIEndpointMethodsMetadata;
7050
7085
  exports.hasCallbacks = hasCallbacks;
7051
7086
  exports.hasUIEndpoints = hasUIEndpoints;
7052
- exports.prepareModelWithTools = prepareModelWithTools;
7053
7087
  exports.registerFinanceExampleCallback = registerFinanceExampleCallback;
7054
7088
  exports.registerUIEndpointsFromClass = registerUIEndpointsFromClass;
7055
7089
  exports.sanitizeTraceData = sanitizeTraceData;