graphlit-client 1.0.20250622007 → 1.0.20250627001

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/client.js CHANGED
@@ -8,7 +8,7 @@ import * as Documents from "./generated/graphql-documents.js";
8
8
  import * as dotenv from "dotenv";
9
9
  import { getServiceType, getModelName } from "./model-mapping.js";
10
10
  import { UIEventAdapter } from "./streaming/ui-event-adapter.js";
11
- import { formatMessagesForOpenAI, formatMessagesForAnthropic, formatMessagesForGoogle, formatMessagesForCohere, formatMessagesForMistral, formatMessagesForBedrock, } from "./streaming/llm-formatters.js";
11
+ import { formatMessagesForOpenAI, formatMessagesForAnthropic, formatMessagesForGoogle, formatMessagesForMistral, formatMessagesForBedrock, } from "./streaming/llm-formatters.js";
12
12
  import { streamWithOpenAI, streamWithAnthropic, streamWithGoogle, streamWithGroq, streamWithCerebras, streamWithCohere, streamWithMistral, streamWithBedrock, streamWithDeepseek, } from "./streaming/providers.js";
13
13
  // Optional imports for streaming LLM clients
14
14
  // These are peer dependencies and may not be installed
@@ -20,6 +20,7 @@ let Anthropic;
20
20
  let GoogleGenerativeAI;
21
21
  let Groq;
22
22
  let CohereClient;
23
+ let CohereClientV2;
23
24
  let Mistral;
24
25
  let BedrockRuntimeClient;
25
26
  try {
@@ -74,6 +75,7 @@ catch (e) {
74
75
  }
75
76
  try {
76
77
  CohereClient = optionalRequire("cohere-ai").CohereClient;
78
+ CohereClientV2 = optionalRequire("cohere-ai").CohereClientV2;
77
79
  if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
78
80
  console.log("[SDK Loading] Cohere SDK loaded successfully");
79
81
  }
@@ -875,6 +877,34 @@ class Graphlit {
875
877
  correlationId: correlationId,
876
878
  });
877
879
  }
880
+ async queryMicrosoftCalendars(properties) {
881
+ return this.queryAndCheckError(Documents.QueryMicrosoftCalendars, {
882
+ properties: properties,
883
+ });
884
+ }
885
+ async queryGoogleCalendars(properties) {
886
+ return this.queryAndCheckError(Documents.QueryGoogleCalendars, {
887
+ properties: properties,
888
+ });
889
+ }
890
+ async queryBoxFolders(properties, folderId) {
891
+ return this.queryAndCheckError(Documents.QueryBoxFolders, {
892
+ properties: properties,
893
+ folderId: folderId,
894
+ });
895
+ }
896
+ async queryDropboxFolders(properties, folderPath) {
897
+ return this.queryAndCheckError(Documents.QueryDropboxFolders, {
898
+ properties: properties,
899
+ folderPath: folderPath,
900
+ });
901
+ }
902
+ async queryGoogleDriveFolders(properties, folderId) {
903
+ return this.queryAndCheckError(Documents.QueryGoogleDriveFolders, {
904
+ properties: properties,
905
+ folderId: folderId,
906
+ });
907
+ }
878
908
  async queryOneDriveFolders(properties, folderId) {
879
909
  return this.queryAndCheckError(Documents.QueryOneDriveFolders, {
880
910
  properties: properties,
@@ -998,6 +1028,108 @@ class Graphlit {
998
1028
  async queryModels(filter) {
999
1029
  return this.queryAndCheckError(Documents.QueryModels, { filter: filter });
1000
1030
  }
1031
+ async createConnector(connector) {
1032
+ return this.mutateAndCheckError(Documents.CreateConnector, { connector: connector });
1033
+ }
1034
+ async updateConnector(connector) {
1035
+ return this.mutateAndCheckError(Documents.UpdateConnector, { connector: connector });
1036
+ }
1037
+ /*
1038
+ public async upsertConnector(
1039
+ connector: Types.ConnectorInput
1040
+ ): Promise<Types.UpsertConnectorMutation> {
1041
+ return this.mutateAndCheckError<
1042
+ Types.UpsertConnectorMutation,
1043
+ { connector: Types.ConnectorInput }
1044
+ >(Documents.UpsertConnector, { connector: connector });
1045
+ }
1046
+ */
1047
+ async deleteConnector(id) {
1048
+ return this.mutateAndCheckError(Documents.DeleteConnector, { id: id });
1049
+ }
1050
+ /*
1051
+ public async deleteConnectors(
1052
+ ids: string[],
1053
+ isSynchronous?: boolean
1054
+ ): Promise<Types.DeleteConnectorsMutation> {
1055
+ return this.mutateAndCheckError<
1056
+ Types.DeleteConnectorsMutation,
1057
+ { ids: string[]; isSynchronous?: boolean }
1058
+ >(Documents.DeleteConnectors, { ids: ids, isSynchronous: isSynchronous });
1059
+ }
1060
+
1061
+ public async deleteAllConnectors(
1062
+ filter?: Types.ConnectorFilter,
1063
+ isSynchronous?: boolean,
1064
+ correlationId?: string
1065
+ ): Promise<Types.DeleteAllConnectorsMutation> {
1066
+ return this.mutateAndCheckError<
1067
+ Types.DeleteAllConnectorsMutation,
1068
+ {
1069
+ filter?: Types.ConnectorFilter;
1070
+ isSynchronous?: boolean;
1071
+ correlationId?: string;
1072
+ }
1073
+ >(Documents.DeleteAllConnectors, {
1074
+ filter: filter,
1075
+ isSynchronous: isSynchronous,
1076
+ correlationId: correlationId,
1077
+ });
1078
+ }
1079
+ */
1080
+ async getConnector(id) {
1081
+ return this.queryAndCheckError(Documents.GetConnector, { id: id });
1082
+ }
1083
+ async queryConnectors(filter) {
1084
+ return this.queryAndCheckError(Documents.QueryConnectors, { filter: filter });
1085
+ }
1086
+ async countConnectors(filter) {
1087
+ return this.queryAndCheckError(Documents.CountConnectors, { filter: filter });
1088
+ }
1089
+ /*
1090
+ public async connectorExists(
1091
+ filter?: Types.ConnectorFilter
1092
+ ): Promise<Types.ConnectorExistsQuery> {
1093
+ return this.queryAndCheckError<
1094
+ Types.QueryConnectorsQuery,
1095
+ { filter?: Types.ConnectorFilter }
1096
+ >(Documents.ConnectorExists, { filter: filter });
1097
+ }
1098
+ */
1099
+ async createView(view) {
1100
+ return this.mutateAndCheckError(Documents.CreateView, { view: view });
1101
+ }
1102
+ async updateView(view) {
1103
+ return this.mutateAndCheckError(Documents.UpdateView, { view: view });
1104
+ }
1105
+ async upsertView(view) {
1106
+ return this.mutateAndCheckError(Documents.UpsertView, { view: view });
1107
+ }
1108
+ async deleteView(id) {
1109
+ return this.mutateAndCheckError(Documents.DeleteView, { id: id });
1110
+ }
1111
+ async deleteViews(ids, isSynchronous) {
1112
+ return this.mutateAndCheckError(Documents.DeleteViews, { ids: ids, isSynchronous: isSynchronous });
1113
+ }
1114
+ async deleteAllViews(filter, isSynchronous, correlationId) {
1115
+ return this.mutateAndCheckError(Documents.DeleteAllViews, {
1116
+ filter: filter,
1117
+ isSynchronous: isSynchronous,
1118
+ correlationId: correlationId,
1119
+ });
1120
+ }
1121
+ async getView(id) {
1122
+ return this.queryAndCheckError(Documents.GetView, { id: id });
1123
+ }
1124
+ async queryViews(filter) {
1125
+ return this.queryAndCheckError(Documents.QueryViews, { filter: filter });
1126
+ }
1127
+ async countViews(filter) {
1128
+ return this.queryAndCheckError(Documents.CountViews, { filter: filter });
1129
+ }
1130
+ async viewExists(filter) {
1131
+ return this.queryAndCheckError(Documents.ViewExists, { filter: filter });
1132
+ }
1001
1133
  async createWorkflow(workflow) {
1002
1134
  return this.mutateAndCheckError(Documents.CreateWorkflow, { workflow: workflow });
1003
1135
  }
@@ -1621,7 +1753,7 @@ class Graphlit {
1621
1753
  * @param specification - Optional specification to check compatibility
1622
1754
  * @returns true if streaming is available, false otherwise
1623
1755
  */
1624
- supportsStreaming(specification) {
1756
+ supportsStreaming(specification, tools) {
1625
1757
  // If we have a full specification, check its service type
1626
1758
  if (specification) {
1627
1759
  const serviceType = specification.serviceType;
@@ -1649,12 +1781,26 @@ class Graphlit {
1649
1781
  case Types.ModelServiceTypes.Cerebras:
1650
1782
  return OpenAI !== undefined || this.cerebrasClient !== undefined;
1651
1783
  case Types.ModelServiceTypes.Cohere:
1652
- return CohereClient !== undefined || this.cohereClient !== undefined;
1784
+ return (CohereClient !== undefined ||
1785
+ CohereClientV2 !== undefined ||
1786
+ this.cohereClient !== undefined);
1653
1787
  case Types.ModelServiceTypes.Mistral:
1654
1788
  return Mistral !== undefined || this.mistralClient !== undefined;
1655
1789
  case Types.ModelServiceTypes.Bedrock:
1656
- return (BedrockRuntimeClient !== undefined ||
1657
- this.bedrockClient !== undefined);
1790
+ const hasBedrockClient = BedrockRuntimeClient !== undefined ||
1791
+ this.bedrockClient !== undefined;
1792
+ // Bedrock Llama models don't support tools in streaming mode
1793
+ if (hasBedrockClient && tools && tools.length > 0) {
1794
+ const bedrockModel = specification.bedrock?.model;
1795
+ if (bedrockModel === Types.BedrockModels.Llama_4Maverick_17B ||
1796
+ bedrockModel === Types.BedrockModels.Llama_4Scout_17B) {
1797
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1798
+ console.log(`⚠️ [supportsStreaming] Bedrock Llama model ${bedrockModel} does not support tools in streaming mode - will fallback to non-streaming`);
1799
+ }
1800
+ return false; // Force fallback to promptAgent for tool support
1801
+ }
1802
+ }
1803
+ return hasBedrockClient;
1658
1804
  case Types.ModelServiceTypes.Deepseek:
1659
1805
  return OpenAI !== undefined || this.deepseekClient !== undefined;
1660
1806
  default:
@@ -1668,7 +1814,9 @@ class Graphlit {
1668
1814
  const hasGoogle = GoogleGenerativeAI !== undefined || this.googleClient !== undefined;
1669
1815
  const hasGroq = Groq !== undefined || this.groqClient !== undefined;
1670
1816
  const hasCerebras = OpenAI !== undefined || this.cerebrasClient !== undefined;
1671
- const hasCohere = CohereClient !== undefined || this.cohereClient !== undefined;
1817
+ const hasCohere = CohereClient !== undefined ||
1818
+ CohereClientV2 !== undefined ||
1819
+ this.cohereClient !== undefined;
1672
1820
  const hasMistral = Mistral !== undefined || this.mistralClient !== undefined;
1673
1821
  const hasBedrock = BedrockRuntimeClient !== undefined || this.bedrockClient !== undefined;
1674
1822
  return (hasOpenAI ||
@@ -1886,7 +2034,7 @@ class Graphlit {
1886
2034
  }
1887
2035
  }
1888
2036
  // Check streaming support - fallback to promptAgent if not supported
1889
- if (fullSpec && !this.supportsStreaming(fullSpec)) {
2037
+ if (fullSpec && !this.supportsStreaming(fullSpec, tools)) {
1890
2038
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1891
2039
  console.log("\n⚠️ [streamAgent] Streaming not supported, falling back to promptAgent with same conversation");
1892
2040
  }
@@ -1901,6 +2049,31 @@ class Graphlit {
1901
2049
  conversationId: actualConversationId,
1902
2050
  timestamp: new Date(),
1903
2051
  });
2052
+ // Debug logging for fallback
2053
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2054
+ console.log(`📊 [streamAgent fallback] promptAgent result:`, {
2055
+ hasMessage: !!promptResult.message,
2056
+ messageLength: promptResult.message?.length,
2057
+ toolCallsCount: promptResult.toolCalls?.length || 0,
2058
+ toolResultsCount: promptResult.toolResults?.length || 0,
2059
+ toolCalls: promptResult.toolCalls,
2060
+ toolResults: promptResult.toolResults?.map((tr) => ({
2061
+ name: tr.name,
2062
+ hasResult: !!tr.result,
2063
+ hasError: !!tr.error,
2064
+ })),
2065
+ });
2066
+ }
2067
+ // Emit tool events if there were tool calls
2068
+ if (promptResult.toolCalls && promptResult.toolCalls.length > 0) {
2069
+ for (const toolCall of promptResult.toolCalls) {
2070
+ onEvent({
2071
+ type: "tool_update",
2072
+ toolCall: toolCall,
2073
+ status: "completed",
2074
+ });
2075
+ }
2076
+ }
1904
2077
  // Emit the final message as a single update (simulating streaming)
1905
2078
  onEvent({
1906
2079
  type: "message_update",
@@ -1909,7 +2082,7 @@ class Graphlit {
1909
2082
  message: promptResult.message,
1910
2083
  role: Types.ConversationRoleTypes.Assistant,
1911
2084
  timestamp: new Date().toISOString(),
1912
- toolCalls: [],
2085
+ toolCalls: promptResult.toolCalls || [],
1913
2086
  },
1914
2087
  isStreaming: false,
1915
2088
  });
@@ -1921,7 +2094,7 @@ class Graphlit {
1921
2094
  message: promptResult.message,
1922
2095
  role: Types.ConversationRoleTypes.Assistant,
1923
2096
  timestamp: new Date().toISOString(),
1924
- toolCalls: [],
2097
+ toolCalls: promptResult.toolCalls || [],
1925
2098
  },
1926
2099
  });
1927
2100
  return; // Exit early after successful fallback
@@ -2104,7 +2277,7 @@ class Graphlit {
2104
2277
  await this.streamWithOpenAI(specification, openaiMessages, tools, uiAdapter, (message, calls) => {
2105
2278
  roundMessage = message;
2106
2279
  toolCalls = calls;
2107
- });
2280
+ }, abortSignal);
2108
2281
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2109
2282
  console.log(`\n🏁 [Streaming] OpenAI native streaming completed (Round ${currentRound})`);
2110
2283
  }
@@ -2121,7 +2294,7 @@ class Graphlit {
2121
2294
  await this.streamWithAnthropic(specification, anthropicMessages, system, tools, uiAdapter, (message, calls) => {
2122
2295
  roundMessage = message;
2123
2296
  toolCalls = calls;
2124
- });
2297
+ }, abortSignal);
2125
2298
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2126
2299
  console.log(`\n🏁 [Streaming] Anthropic native streaming completed (Round ${currentRound})`);
2127
2300
  }
@@ -2140,7 +2313,7 @@ class Graphlit {
2140
2313
  tools, uiAdapter, (message, calls) => {
2141
2314
  roundMessage = message;
2142
2315
  toolCalls = calls;
2143
- });
2316
+ }, abortSignal);
2144
2317
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2145
2318
  console.log(`\n🏁 [Streaming] Google native streaming completed (Round ${currentRound})`);
2146
2319
  }
@@ -2157,7 +2330,7 @@ class Graphlit {
2157
2330
  await this.streamWithGroq(specification, groqMessages, tools, uiAdapter, (message, calls) => {
2158
2331
  roundMessage = message;
2159
2332
  toolCalls = calls;
2160
- });
2333
+ }, abortSignal);
2161
2334
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2162
2335
  console.log(`\n🏁 [Streaming] Groq native streaming completed (Round ${currentRound})`);
2163
2336
  }
@@ -2174,24 +2347,24 @@ class Graphlit {
2174
2347
  await this.streamWithCerebras(specification, cerebrasMessages, tools, uiAdapter, (message, calls) => {
2175
2348
  roundMessage = message;
2176
2349
  toolCalls = calls;
2177
- });
2350
+ }, abortSignal);
2178
2351
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2179
2352
  console.log(`\n🏁 [Streaming] Cerebras native streaming completed (Round ${currentRound})`);
2180
2353
  }
2181
2354
  }
2182
2355
  else if (serviceType === Types.ModelServiceTypes.Cohere &&
2183
- (CohereClient || this.cohereClient)) {
2356
+ (CohereClient || CohereClientV2 || this.cohereClient)) {
2184
2357
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2185
2358
  console.log(`\n✅ [Streaming] Using Cohere native streaming (Round ${currentRound})`);
2186
2359
  }
2187
- const cohereMessages = formatMessagesForCohere(messages);
2360
+ // V2 API uses raw messages, not formatted
2188
2361
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2189
- console.log(`🔍 [Cohere] Sending ${cohereMessages.length} messages to LLM: ${JSON.stringify(cohereMessages)}`);
2362
+ console.log(`🔍 [Cohere] Sending ${messages.length} messages to LLM`);
2190
2363
  }
2191
- await this.streamWithCohere(specification, cohereMessages, tools, uiAdapter, (message, calls) => {
2364
+ await this.streamWithCohere(specification, messages, tools, uiAdapter, (message, calls) => {
2192
2365
  roundMessage = message;
2193
2366
  toolCalls = calls;
2194
- });
2367
+ }, abortSignal);
2195
2368
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2196
2369
  console.log(`\n🏁 [Streaming] Cohere native streaming completed (Round ${currentRound})`);
2197
2370
  }
@@ -2202,13 +2375,26 @@ class Graphlit {
2202
2375
  console.log(`\n✅ [Streaming] Using Mistral native streaming (Round ${currentRound})`);
2203
2376
  }
2204
2377
  const mistralMessages = formatMessagesForMistral(messages);
2205
- if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2206
- console.log(`🔍 [Mistral] Sending ${mistralMessages.length} messages to LLM: ${JSON.stringify(mistralMessages)}`);
2378
+ // ALWAYS log when there's a tool-related issue for debugging
2379
+ const hasToolCalls = mistralMessages.some((m) => m.tool_calls?.length > 0);
2380
+ const hasToolResponses = mistralMessages.some((m) => m.role === "tool");
2381
+ if (hasToolCalls ||
2382
+ hasToolResponses ||
2383
+ process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2384
+ console.log(`🔍 [Mistral] Sending ${mistralMessages.length} messages to LLM:`);
2385
+ console.log(JSON.stringify(mistralMessages, null, 2));
2386
+ // Count tool calls and responses
2387
+ const toolCallCount = mistralMessages.reduce((count, m) => count + (m.tool_calls?.length || 0), 0);
2388
+ const toolResponseCount = mistralMessages.filter((m) => m.role === "tool").length;
2389
+ console.log(`🔍 [Mistral] Tool calls: ${toolCallCount}, Tool responses: ${toolResponseCount}`);
2390
+ if (toolResponseCount > 0) {
2391
+ console.log(`🔍 [Mistral] IMPORTANT: We have tool responses, should we still pass tools?`);
2392
+ }
2207
2393
  }
2208
2394
  await this.streamWithMistral(specification, mistralMessages, tools, uiAdapter, (message, calls) => {
2209
2395
  roundMessage = message;
2210
2396
  toolCalls = calls;
2211
- });
2397
+ }, abortSignal);
2212
2398
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2213
2399
  console.log(`\n🏁 [Streaming] Mistral native streaming completed (Round ${currentRound})`);
2214
2400
  }
@@ -2225,7 +2411,7 @@ class Graphlit {
2225
2411
  await this.streamWithBedrock(specification, bedrockMessages, system, tools, uiAdapter, (message, calls) => {
2226
2412
  roundMessage = message;
2227
2413
  toolCalls = calls;
2228
- });
2414
+ }, abortSignal);
2229
2415
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2230
2416
  console.log(`\n🏁 [Streaming] Bedrock native streaming completed (Round ${currentRound})`);
2231
2417
  }
@@ -2242,7 +2428,7 @@ class Graphlit {
2242
2428
  await this.streamWithDeepseek(specification, deepseekMessages, tools, uiAdapter, (message, calls) => {
2243
2429
  roundMessage = message;
2244
2430
  toolCalls = calls;
2245
- });
2431
+ }, abortSignal);
2246
2432
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2247
2433
  console.log(`\n🏁 [Streaming] Deepseek native streaming completed (Round ${currentRound})`);
2248
2434
  }
@@ -2380,13 +2566,16 @@ class Graphlit {
2380
2566
  result: result,
2381
2567
  });
2382
2568
  // Add tool response to messages
2383
- messages.push({
2569
+ const toolMessage = {
2384
2570
  __typename: "ConversationMessage",
2385
2571
  role: Types.ConversationRoleTypes.Tool,
2386
2572
  message: typeof result === "string" ? result : JSON.stringify(result),
2387
2573
  toolCallId: toolCall.id,
2388
2574
  timestamp: new Date().toISOString(),
2389
- });
2575
+ };
2576
+ // Add tool name for Mistral compatibility
2577
+ toolMessage.toolName = toolCall.name;
2578
+ messages.push(toolMessage);
2390
2579
  }
2391
2580
  catch (error) {
2392
2581
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
@@ -2402,13 +2591,16 @@ class Graphlit {
2402
2591
  error: errorMessage,
2403
2592
  });
2404
2593
  // Add error response
2405
- messages.push({
2594
+ const errorToolMessage = {
2406
2595
  __typename: "ConversationMessage",
2407
2596
  role: Types.ConversationRoleTypes.Tool,
2408
2597
  message: `Error: ${errorMessage}`,
2409
2598
  toolCallId: toolCall.id,
2410
2599
  timestamp: new Date().toISOString(),
2411
- });
2600
+ };
2601
+ // Add tool name for Mistral compatibility
2602
+ errorToolMessage.toolName = toolCall.name;
2603
+ messages.push(errorToolMessage);
2412
2604
  }
2413
2605
  }
2414
2606
  }
@@ -2422,7 +2614,14 @@ class Graphlit {
2422
2614
  const completionTime = uiAdapter.getCompletionTime(); // Total time in milliseconds
2423
2615
  const ttft = uiAdapter.getTTFT(); // Time to first token in milliseconds
2424
2616
  const throughput = uiAdapter.getThroughput(); // Tokens per second
2425
- const completeResponse = await this.completeConversation(trimmedMessage, conversationId, completionTime, ttft, throughput, correlationId);
2617
+ // Convert milliseconds to ISO 8601 duration format (e.g., "PT1.5S")
2618
+ const millisecondsToTimeSpan = (ms) => {
2619
+ if (ms === undefined)
2620
+ return undefined;
2621
+ const seconds = ms / 1000;
2622
+ return `PT${seconds}S`;
2623
+ };
2624
+ const completeResponse = await this.completeConversation(trimmedMessage, conversationId, millisecondsToTimeSpan(completionTime), millisecondsToTimeSpan(ttft), throughput, correlationId);
2426
2625
  // Extract token count from the response
2427
2626
  finalTokens =
2428
2627
  completeResponse.completeConversation?.message?.tokens ?? undefined;
@@ -2576,7 +2775,7 @@ class Graphlit {
2576
2775
  /**
2577
2776
  * Stream with OpenAI client
2578
2777
  */
2579
- async streamWithOpenAI(specification, messages, tools, uiAdapter, onComplete) {
2778
+ async streamWithOpenAI(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
2580
2779
  // Check if we have either the OpenAI module or a provided client
2581
2780
  if (!OpenAI && !this.openaiClient) {
2582
2781
  throw new Error("OpenAI client not available");
@@ -2593,12 +2792,12 @@ class Graphlit {
2593
2792
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2594
2793
  console.log(`🚀 [Graphlit SDK] Routing to OpenAI streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2595
2794
  }
2596
- await streamWithOpenAI(specification, messages, tools, openaiClient, (event) => uiAdapter.handleEvent(event), onComplete);
2795
+ await streamWithOpenAI(specification, messages, tools, openaiClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2597
2796
  }
2598
2797
  /**
2599
2798
  * Stream with Anthropic client
2600
2799
  */
2601
- async streamWithAnthropic(specification, messages, systemPrompt, tools, uiAdapter, onComplete) {
2800
+ async streamWithAnthropic(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
2602
2801
  // Check if we have either the Anthropic module or a provided client
2603
2802
  if (!Anthropic && !this.anthropicClient) {
2604
2803
  throw new Error("Anthropic client not available");
@@ -2615,12 +2814,43 @@ class Graphlit {
2615
2814
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2616
2815
  console.log(`🚀 [Graphlit SDK] Routing to Anthropic streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0} | SystemPrompt: ${systemPrompt ? "Yes" : "No"}`);
2617
2816
  }
2618
- await streamWithAnthropic(specification, messages, systemPrompt, tools, anthropicClient, (event) => uiAdapter.handleEvent(event), onComplete);
2817
+ // Get thinking configuration from specification
2818
+ const thinkingConfig = this.getThinkingConfig(specification);
2819
+ if (thinkingConfig && process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2820
+ console.log(`🧠 [Graphlit SDK] Anthropic thinking enabled | Budget: ${thinkingConfig.budget_tokens} tokens`);
2821
+ }
2822
+ await streamWithAnthropic(specification, messages, systemPrompt, tools, anthropicClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, thinkingConfig);
2823
+ }
2824
+ /**
2825
+ * Extract thinking configuration from specification
2826
+ */
2827
+ getThinkingConfig(specification) {
2828
+ // Check Anthropic specifications
2829
+ if (specification.serviceType === Types.ModelServiceTypes.Anthropic) {
2830
+ const anthropic = specification.anthropic;
2831
+ if (anthropic?.enableThinking) {
2832
+ return {
2833
+ type: "enabled",
2834
+ budget_tokens: anthropic.thinkingTokenLimit || 10000,
2835
+ };
2836
+ }
2837
+ }
2838
+ // Check Google specifications (also supports thinking)
2839
+ if (specification.serviceType === Types.ModelServiceTypes.Google) {
2840
+ const google = specification.google;
2841
+ if (google?.enableThinking) {
2842
+ return {
2843
+ type: "enabled",
2844
+ budget_tokens: google.thinkingTokenLimit || 10000,
2845
+ };
2846
+ }
2847
+ }
2848
+ return undefined;
2619
2849
  }
2620
2850
  /**
2621
2851
  * Stream with Google client
2622
2852
  */
2623
- async streamWithGoogle(specification, messages, systemPrompt, tools, uiAdapter, onComplete) {
2853
+ async streamWithGoogle(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
2624
2854
  // Check if we have either the Google module or a provided client
2625
2855
  if (!GoogleGenerativeAI && !this.googleClient) {
2626
2856
  throw new Error("Google GenerativeAI client not available");
@@ -2635,12 +2865,12 @@ class Graphlit {
2635
2865
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2636
2866
  console.log(`🚀 [Graphlit SDK] Routing to Google streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0} | SystemPrompt: ${systemPrompt ? "Yes" : "No"}`);
2637
2867
  }
2638
- await streamWithGoogle(specification, messages, systemPrompt, tools, googleClient, (event) => uiAdapter.handleEvent(event), onComplete);
2868
+ await streamWithGoogle(specification, messages, systemPrompt, tools, googleClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2639
2869
  }
2640
2870
  /**
2641
2871
  * Stream with Groq client (OpenAI-compatible)
2642
2872
  */
2643
- async streamWithGroq(specification, messages, tools, uiAdapter, onComplete) {
2873
+ async streamWithGroq(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
2644
2874
  // Check if we have either the Groq module or a provided client
2645
2875
  if (!Groq && !this.groqClient) {
2646
2876
  throw new Error("Groq client not available");
@@ -2655,12 +2885,12 @@ class Graphlit {
2655
2885
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2656
2886
  console.log(`🚀 [Graphlit SDK] Routing to Groq streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2657
2887
  }
2658
- await streamWithGroq(specification, messages, tools, groqClient, (event) => uiAdapter.handleEvent(event), onComplete);
2888
+ await streamWithGroq(specification, messages, tools, groqClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2659
2889
  }
2660
2890
  /**
2661
2891
  * Stream with Cerebras client (OpenAI-compatible)
2662
2892
  */
2663
- async streamWithCerebras(specification, messages, tools, uiAdapter, onComplete) {
2893
+ async streamWithCerebras(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
2664
2894
  // Check if we have either the OpenAI module or a provided client
2665
2895
  if (!OpenAI && !this.cerebrasClient) {
2666
2896
  throw new Error("Cerebras client not available");
@@ -2678,32 +2908,34 @@ class Graphlit {
2678
2908
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2679
2909
  console.log(`🚀 [Graphlit SDK] Routing to Cerebras streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2680
2910
  }
2681
- await streamWithCerebras(specification, messages, tools, cerebrasClient, (event) => uiAdapter.handleEvent(event), onComplete);
2911
+ await streamWithCerebras(specification, messages, tools, cerebrasClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2682
2912
  }
2683
2913
  /**
2684
2914
  * Stream with Cohere client
2685
2915
  */
2686
- async streamWithCohere(specification, messages, tools, uiAdapter, onComplete) {
2916
+ async streamWithCohere(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
2687
2917
  // Check if we have either the Cohere module or a provided client
2688
- if (!CohereClient && !this.cohereClient) {
2918
+ if (!CohereClient && !CohereClientV2 && !this.cohereClient) {
2689
2919
  throw new Error("Cohere client not available");
2690
2920
  }
2691
- // Use provided client or create a new one
2921
+ // Use provided client or create a new one - prefer v2
2692
2922
  const cohereClient = this.cohereClient ||
2693
- (CohereClient
2694
- ? new CohereClient({ token: process.env.COHERE_API_KEY || "" })
2695
- : (() => {
2696
- throw new Error("Cohere module not available");
2697
- })());
2923
+ (CohereClientV2
2924
+ ? new CohereClientV2({ token: process.env.COHERE_API_KEY || "" })
2925
+ : CohereClient
2926
+ ? new CohereClient({ token: process.env.COHERE_API_KEY || "" })
2927
+ : (() => {
2928
+ throw new Error("Cohere module not available");
2929
+ })());
2698
2930
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2699
2931
  console.log(`🚀 [Graphlit SDK] Routing to Cohere streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2700
2932
  }
2701
- await streamWithCohere(specification, messages, tools, cohereClient, (event) => uiAdapter.handleEvent(event), onComplete);
2933
+ await streamWithCohere(specification, messages, tools, cohereClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2702
2934
  }
2703
2935
  /**
2704
2936
  * Stream with Mistral client
2705
2937
  */
2706
- async streamWithMistral(specification, messages, tools, uiAdapter, onComplete) {
2938
+ async streamWithMistral(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
2707
2939
  // Check if we have either the Mistral module or a provided client
2708
2940
  if (!Mistral && !this.mistralClient) {
2709
2941
  throw new Error("Mistral client not available");
@@ -2711,19 +2943,25 @@ class Graphlit {
2711
2943
  // Use provided client or create a new one
2712
2944
  const mistralClient = this.mistralClient ||
2713
2945
  (Mistral
2714
- ? new Mistral({ apiKey: process.env.MISTRAL_API_KEY || "" })
2946
+ ? (() => {
2947
+ const apiKey = process.env.MISTRAL_API_KEY;
2948
+ if (!apiKey) {
2949
+ throw new Error("MISTRAL_API_KEY environment variable is required for Mistral streaming");
2950
+ }
2951
+ return new Mistral({ apiKey });
2952
+ })()
2715
2953
  : (() => {
2716
2954
  throw new Error("Mistral module not available");
2717
2955
  })());
2718
2956
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2719
2957
  console.log(`🚀 [Graphlit SDK] Routing to Mistral streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2720
2958
  }
2721
- await streamWithMistral(specification, messages, tools, mistralClient, (event) => uiAdapter.handleEvent(event), onComplete);
2959
+ await streamWithMistral(specification, messages, tools, mistralClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2722
2960
  }
2723
2961
  /**
2724
2962
  * Stream with Bedrock client
2725
2963
  */
2726
- async streamWithBedrock(specification, messages, systemPrompt, tools, uiAdapter, onComplete) {
2964
+ async streamWithBedrock(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
2727
2965
  // Check if we have either the Bedrock module or a provided client
2728
2966
  if (!BedrockRuntimeClient && !this.bedrockClient) {
2729
2967
  throw new Error("Bedrock client not available");
@@ -2740,12 +2978,12 @@ class Graphlit {
2740
2978
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2741
2979
  console.log(`🚀 [Graphlit SDK] Routing to Bedrock streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0} | SystemPrompt: ${systemPrompt ? "Yes" : "No"}`);
2742
2980
  }
2743
- await streamWithBedrock(specification, messages, systemPrompt, tools, bedrockClient, (event) => uiAdapter.handleEvent(event), onComplete);
2981
+ await streamWithBedrock(specification, messages, systemPrompt, tools, bedrockClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2744
2982
  }
2745
2983
  /**
2746
2984
  * Stream with Deepseek client
2747
2985
  */
2748
- async streamWithDeepseek(specification, messages, tools, uiAdapter, onComplete) {
2986
+ async streamWithDeepseek(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
2749
2987
  // Check if we have either the OpenAI module or a provided Deepseek client
2750
2988
  if (!OpenAI && !this.deepseekClient) {
2751
2989
  throw new Error("Deepseek client not available (requires OpenAI SDK)");
@@ -2764,7 +3002,7 @@ class Graphlit {
2764
3002
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2765
3003
  console.log(`🚀 [Graphlit SDK] Routing to Deepseek streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2766
3004
  }
2767
- await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete);
3005
+ await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2768
3006
  }
2769
3007
  // Helper method to execute tools for promptAgent
2770
3008
  async executeToolsForPromptAgent(toolCalls, toolHandlers, allToolCalls, signal) {