@flutchai/flutch-sdk 0.7.7 → 0.7.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 CHANGED
@@ -2131,7 +2131,8 @@ exports.GraphController = class _GraphController {
2131
2131
  async getSupportedGraphTypes() {
2132
2132
  return this.graphService.getSupportedGraphTypes();
2133
2133
  }
2134
- async generateAnswer(payload) {
2134
+ async generateAnswer(payload, res) {
2135
+ this.cancelOnDisconnect(res, payload.requestId);
2135
2136
  try {
2136
2137
  return await this.graphService.generateAnswer(payload);
2137
2138
  } catch (error) {
@@ -2144,6 +2145,7 @@ exports.GraphController = class _GraphController {
2144
2145
  res.setHeader("Transfer-Encoding", "chunked");
2145
2146
  res.setHeader("Cache-Control", "no-cache");
2146
2147
  res.setHeader("Connection", "keep-alive");
2148
+ this.cancelOnDisconnect(res, payload.requestId);
2147
2149
  try {
2148
2150
  this.logger.debug(`[CONTROLLER] Starting streamAnswer for requestId: ${payload.requestId}`);
2149
2151
  const result = await this.graphService.streamAnswer(payload, (chunk) => {
@@ -2181,6 +2183,19 @@ exports.GraphController = class _GraphController {
2181
2183
  res.end();
2182
2184
  }
2183
2185
  }
2186
+ /**
2187
+ * A caller that hangs up before the answer is done — its own timeout, a
2188
+ * restart, a cancelled parent run — no longer waits for it, so the run is
2189
+ * cancelled: left going, it keeps calling models and tools nobody reads.
2190
+ */
2191
+ cancelOnDisconnect(res, requestId) {
2192
+ if (!requestId) return;
2193
+ res.on("close", () => {
2194
+ if (res.writableFinished) return;
2195
+ this.logger.warn(`[CONTROLLER] Caller disconnected before the answer: cancelling ${requestId}`);
2196
+ this.graphService.cancelGeneration(requestId).catch((error) => this.logger.warn(`[CONTROLLER] Cancel after disconnect failed for ${requestId}: ${error.message}`));
2197
+ });
2198
+ }
2184
2199
  async cancelGeneration(requestId) {
2185
2200
  try {
2186
2201
  await this.graphService.cancelGeneration(requestId);
@@ -2254,9 +2269,13 @@ _ts_decorate8([
2254
2269
  description: "Answer generated"
2255
2270
  }),
2256
2271
  _ts_param4(0, common.Body()),
2272
+ _ts_param4(1, common.Res({
2273
+ passthrough: true
2274
+ })),
2257
2275
  _ts_metadata6("design:type", Function),
2258
2276
  _ts_metadata6("design:paramtypes", [
2259
- typeof IGraphRequestPayload === "undefined" ? Object : IGraphRequestPayload
2277
+ typeof IGraphRequestPayload === "undefined" ? Object : IGraphRequestPayload,
2278
+ typeof express.Response === "undefined" ? Object : express.Response
2260
2279
  ]),
2261
2280
  _ts_metadata6("design:returntype", Promise)
2262
2281
  ], exports.GraphController.prototype, "generateAnswer", null);
@@ -7037,7 +7056,7 @@ exports.McpRuntimeHttpClient = class _McpRuntimeHttpClient {
7037
7056
  /**
7038
7057
  * Execute a tool by name with given arguments
7039
7058
  */
7040
- async executeTool(name, args, context, mcpServers) {
7059
+ async executeTool(name, args, context, mcpServers, signal) {
7041
7060
  try {
7042
7061
  this.logger.debug(`Executing tool: ${name} with args:`, args);
7043
7062
  const payload = {
@@ -7050,7 +7069,9 @@ exports.McpRuntimeHttpClient = class _McpRuntimeHttpClient {
7050
7069
  if (mcpServers && mcpServers.length > 0) {
7051
7070
  payload.mcpServers = mcpServers;
7052
7071
  }
7053
- const response = await this.httpClient.post("/tools/execute", payload);
7072
+ const response = signal ? await this.httpClient.post("/tools/execute", payload, {
7073
+ signal
7074
+ }) : await this.httpClient.post("/tools/execute", payload);
7054
7075
  this.logger.log(`Tool ${name} executed successfully`);
7055
7076
  return response.data;
7056
7077
  } catch (error) {
@@ -7118,7 +7139,7 @@ exports.McpRuntimeHttpClient = class _McpRuntimeHttpClient {
7118
7139
  toolName
7119
7140
  ]
7120
7141
  }, JSON.stringify(enrichedArgs), parsedConfig.runId, void 0, parsedConfig.tags, parsedConfig.metadata, toolName);
7121
- const result = await this.executeTool(toolName, enrichedArgs, executionContext, mcpServers);
7142
+ const result = await this.executeTool(toolName, enrichedArgs, executionContext, mcpServers, config?.signal);
7122
7143
  const content = result.success ? JSON.stringify(result) : result.error || JSON.stringify(result);
7123
7144
  await runManager?.handleToolEnd(content);
7124
7145
  return {
@@ -7588,6 +7609,22 @@ function buildEffortRequestFields(effort) {
7588
7609
  } : void 0;
7589
7610
  }
7590
7611
  __name(buildEffortRequestFields, "buildEffortRequestFields");
7612
+ function buildReasoningRequestFields(effort, thinking) {
7613
+ if (!effort && !thinking) return void 0;
7614
+ return {
7615
+ ...effort && {
7616
+ output_config: {
7617
+ effort
7618
+ }
7619
+ },
7620
+ ...thinking && {
7621
+ thinking: {
7622
+ type: thinking
7623
+ }
7624
+ }
7625
+ };
7626
+ }
7627
+ __name(buildReasoningRequestFields, "buildReasoningRequestFields");
7591
7628
  function resolveSamplingParams(modelIdentifiers, requested, supportsSamplingParams) {
7592
7629
  const accepted = supportsSamplingParams ?? modelIdentifiers.every((id) => modelAcceptsSamplingParams(id));
7593
7630
  if (accepted) {
@@ -7935,7 +7972,8 @@ var ModelInitializer = class _ModelInitializer {
7935
7972
  const withSampling = config.supportsSamplingParams === void 0 ? withMcp : `${withMcp}:sp:${config.supportsSamplingParams}`;
7936
7973
  const withCache = config.promptCache === void 0 && config.promptCacheTtl === void 0 ? withSampling : `${withSampling}:pc:${config.promptCache ?? "auto"}:${config.promptCacheTtl ?? "default"}`;
7937
7974
  const withEffort = config.effort === void 0 ? withCache : `${withCache}:eff:${config.effort}`;
7938
- return config.toolSearch?.enabled ? `${withEffort}:ts:${JSON.stringify(config.toolSearch)}` : withEffort;
7975
+ const withThinking = config.thinking === void 0 ? withEffort : `${withEffort}:th:${config.thinking}`;
7976
+ return config.toolSearch?.enabled ? `${withThinking}:ts:${JSON.stringify(config.toolSearch)}` : withThinking;
7939
7977
  }
7940
7978
  // Chat model creators
7941
7979
  chatModelCreators = {
@@ -7950,7 +7988,7 @@ var ModelInitializer = class _ModelInitializer {
7950
7988
  }
7951
7989
  return new openai.ChatOpenAI(config);
7952
7990
  },
7953
- [ModelProvider.ANTHROPIC]: ({ modelName, defaultTemperature, defaultMaxTokens, apiToken, baseURL }, promptCacheControl) => {
7991
+ [ModelProvider.ANTHROPIC]: ({ modelName, defaultTemperature, defaultMaxTokens, apiToken, baseURL, defaultThinking }, promptCacheControl) => {
7954
7992
  const routerURL = resolveRouterURL(baseURL);
7955
7993
  return new anthropic.ChatAnthropic({
7956
7994
  modelName,
@@ -7967,6 +8005,12 @@ var ModelInitializer = class _ModelInitializer {
7967
8005
  ...promptCacheControl && {
7968
8006
  cache_control: promptCacheControl
7969
8007
  },
8008
+ // The thinking mode as the API's own parameter; absent when unset.
8009
+ ...defaultThinking && {
8010
+ thinking: {
8011
+ type: defaultThinking
8012
+ }
8013
+ },
7970
8014
  anthropicApiKey: apiToken || this.resolveApiKey(ModelProvider.ANTHROPIC),
7971
8015
  ...routerURL && {
7972
8016
  anthropicApiUrl: routerURL
@@ -8173,7 +8217,8 @@ var ModelInitializer = class _ModelInitializer {
8173
8217
  defaultTemperature: sampling.temperature,
8174
8218
  defaultMaxTokens: toOptionalNumber(config.maxTokens) ?? toOptionalNumber(modelConfig.defaultMaxTokens),
8175
8219
  baseURL: config.baseURL ?? modelConfig.baseURL,
8176
- defaultEffort: config.effort ?? modelConfig.defaultEffort
8220
+ defaultEffort: config.effort ?? modelConfig.defaultEffort,
8221
+ defaultThinking: config.thinking ?? modelConfig.defaultThinking
8177
8222
  };
8178
8223
  const promptCacheControl = resolvePromptCacheControl([
8179
8224
  finalConfig.bedrockModelId,
@@ -8185,7 +8230,7 @@ var ModelInitializer = class _ModelInitializer {
8185
8230
  this.logger.debug(`Creating new chat model instance: ${cacheKey}`);
8186
8231
  let model;
8187
8232
  if (finalConfig.useBedrock && finalConfig.bedrockModelId) {
8188
- const effortFields = buildEffortRequestFields(config.effort ?? modelConfig.defaultEffort);
8233
+ const effortFields = buildReasoningRequestFields(config.effort ?? modelConfig.defaultEffort, config.thinking ?? modelConfig.defaultThinking);
8189
8234
  model = new FlutchChatBedrockConverse({
8190
8235
  model: finalConfig.bedrockModelId,
8191
8236
  region: this.resolveBedrockRegion(),
@@ -9190,6 +9235,7 @@ exports.bootstrap = bootstrap;
9190
9235
  exports.buildEffortRequestFields = buildEffortRequestFields;
9191
9236
  exports.buildOAuthAuthorizationUrl = buildOAuthAuthorizationUrl;
9192
9237
  exports.buildOpenAIModelConfig = buildOpenAIModelConfig;
9238
+ exports.buildReasoningRequestFields = buildReasoningRequestFields;
9193
9239
  exports.clearAttachmentDataStore = clearAttachmentDataStore;
9194
9240
  exports.createEndpointDescriptors = createEndpointDescriptors;
9195
9241
  exports.createGraphAttachment = createGraphAttachment;