graphlit-client 1.0.20250613009 → 1.0.20250615001

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
@@ -1,13 +1,15 @@
1
1
  import jwt from "jsonwebtoken";
2
2
  // Apollo core (React-free) - ESM import
3
3
  import { ApolloClient, InMemoryCache, createHttpLink, ApolloLink, ApolloError, } from "@apollo/client/core/index.js";
4
+ // Apollo retry link for resilient error handling
5
+ import { RetryLink } from "@apollo/client/link/retry/index.js";
4
6
  import * as Types from "./generated/graphql-types.js";
5
7
  import * as Documents from "./generated/graphql-documents.js";
6
8
  import * as dotenv from "dotenv";
7
9
  import { getServiceType, getModelName } from "./model-mapping.js";
8
10
  import { UIEventAdapter } from "./streaming/ui-event-adapter.js";
9
- import { formatMessagesForOpenAI, formatMessagesForAnthropic, formatMessagesForGoogle, } from "./streaming/llm-formatters.js";
10
- import { streamWithOpenAI, streamWithAnthropic, streamWithGoogle, } from "./streaming/providers.js";
11
+ import { formatMessagesForOpenAI, formatMessagesForAnthropic, formatMessagesForGoogle, formatMessagesForCohere, formatMessagesForMistral, formatMessagesForBedrock, } from "./streaming/llm-formatters.js";
12
+ import { streamWithOpenAI, streamWithAnthropic, streamWithGoogle, streamWithGroq, streamWithCerebras, streamWithCohere, streamWithMistral, streamWithBedrock, streamWithDeepseek, } from "./streaming/providers.js";
11
13
  // Optional imports for streaming LLM clients
12
14
  // These are peer dependencies and may not be installed
13
15
  // We need to use createRequire for optional dependencies to avoid build errors
@@ -16,6 +18,10 @@ const optionalRequire = createRequire(import.meta.url);
16
18
  let OpenAI;
17
19
  let Anthropic;
18
20
  let GoogleGenerativeAI;
21
+ let Groq;
22
+ let CohereClient;
23
+ let Mistral;
24
+ let BedrockRuntimeClient;
19
25
  try {
20
26
  OpenAI = optionalRequire("openai").default || optionalRequire("openai");
21
27
  if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
@@ -54,6 +60,54 @@ catch (e) {
54
60
  console.log("[SDK Loading] Google Generative AI SDK not found:", e.message);
55
61
  }
56
62
  }
63
+ try {
64
+ Groq = optionalRequire("groq-sdk").default || optionalRequire("groq-sdk");
65
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
66
+ console.log("[SDK Loading] Groq SDK loaded successfully");
67
+ }
68
+ }
69
+ catch (e) {
70
+ // Groq SDK not installed
71
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
72
+ console.log("[SDK Loading] Groq SDK not found:", e.message);
73
+ }
74
+ }
75
+ try {
76
+ CohereClient = optionalRequire("cohere-ai").CohereClient;
77
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
78
+ console.log("[SDK Loading] Cohere SDK loaded successfully");
79
+ }
80
+ }
81
+ catch (e) {
82
+ // Cohere SDK not installed
83
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
84
+ console.log("[SDK Loading] Cohere SDK not found:", e.message);
85
+ }
86
+ }
87
+ try {
88
+ Mistral = optionalRequire("@mistralai/mistralai").Mistral;
89
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
90
+ console.log("[SDK Loading] Mistral SDK loaded successfully");
91
+ }
92
+ }
93
+ catch (e) {
94
+ // Mistral SDK not installed
95
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
96
+ console.log("[SDK Loading] Mistral SDK not found:", e.message);
97
+ }
98
+ }
99
+ try {
100
+ BedrockRuntimeClient = optionalRequire("@aws-sdk/client-bedrock-runtime").BedrockRuntimeClient;
101
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
102
+ console.log("[SDK Loading] Bedrock SDK loaded successfully");
103
+ }
104
+ }
105
+ catch (e) {
106
+ // Bedrock SDK not installed
107
+ if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
108
+ console.log("[SDK Loading] Bedrock SDK not found:", e.message);
109
+ }
110
+ }
57
111
  const DEFAULT_MAX_TOOL_ROUNDS = 1000;
58
112
  // Define the Graphlit class
59
113
  class Graphlit {
@@ -65,13 +119,37 @@ class Graphlit {
65
119
  ownerId;
66
120
  userId;
67
121
  jwtSecret;
122
+ retryConfig;
68
123
  // Streaming client instances (optional - can be provided by user)
69
124
  openaiClient;
70
125
  anthropicClient;
71
126
  googleClient;
72
- constructor(organizationId, environmentId, jwtSecret, ownerId, userId, apiUri) {
127
+ groqClient;
128
+ cerebrasClient;
129
+ cohereClient;
130
+ mistralClient;
131
+ bedrockClient;
132
+ deepseekClient;
133
+ constructor(organizationIdOrOptions, environmentId, jwtSecret, ownerId, userId, apiUri) {
134
+ // Handle both old constructor signature and new options object
135
+ let options;
136
+ if (typeof organizationIdOrOptions === 'object' && organizationIdOrOptions !== null) {
137
+ // New constructor with options object
138
+ options = organizationIdOrOptions;
139
+ }
140
+ else {
141
+ // Legacy constructor with individual parameters
142
+ options = {
143
+ organizationId: organizationIdOrOptions,
144
+ environmentId,
145
+ jwtSecret,
146
+ ownerId,
147
+ userId,
148
+ apiUri
149
+ };
150
+ }
73
151
  this.apiUri =
74
- apiUri ||
152
+ options.apiUri ||
75
153
  (typeof process !== "undefined"
76
154
  ? process.env.GRAPHLIT_API_URL
77
155
  : undefined) ||
@@ -79,21 +157,30 @@ class Graphlit {
79
157
  if (typeof process !== "undefined") {
80
158
  dotenv.config();
81
159
  this.organizationId =
82
- organizationId || process.env.GRAPHLIT_ORGANIZATION_ID;
83
- this.environmentId = environmentId || process.env.GRAPHLIT_ENVIRONMENT_ID;
84
- this.jwtSecret = jwtSecret || process.env.GRAPHLIT_JWT_SECRET;
160
+ options.organizationId || process.env.GRAPHLIT_ORGANIZATION_ID;
161
+ this.environmentId = options.environmentId || process.env.GRAPHLIT_ENVIRONMENT_ID;
162
+ this.jwtSecret = options.jwtSecret || process.env.GRAPHLIT_JWT_SECRET;
85
163
  // optional: for multi-tenant support
86
- this.ownerId = ownerId || process.env.GRAPHLIT_OWNER_ID;
87
- this.userId = userId || process.env.GRAPHLIT_USER_ID;
164
+ this.ownerId = options.ownerId || process.env.GRAPHLIT_OWNER_ID;
165
+ this.userId = options.userId || process.env.GRAPHLIT_USER_ID;
88
166
  }
89
167
  else {
90
- this.organizationId = organizationId;
91
- this.environmentId = environmentId;
92
- this.jwtSecret = jwtSecret;
168
+ this.organizationId = options.organizationId;
169
+ this.environmentId = options.environmentId;
170
+ this.jwtSecret = options.jwtSecret;
93
171
  // optional: for multi-tenant support
94
- this.ownerId = ownerId;
95
- this.userId = userId;
172
+ this.ownerId = options.ownerId;
173
+ this.userId = options.userId;
96
174
  }
175
+ // Set default retry configuration
176
+ this.retryConfig = {
177
+ maxAttempts: 5,
178
+ initialDelay: 300,
179
+ maxDelay: 30000,
180
+ retryableStatusCodes: [429, 502, 503, 504],
181
+ jitter: true,
182
+ ...options.retryConfig
183
+ };
97
184
  if (!this.organizationId) {
98
185
  throw new Error("Graphlit organization identifier is required.");
99
186
  }
@@ -111,6 +198,42 @@ class Graphlit {
111
198
  const httpLink = createHttpLink({
112
199
  uri: this.apiUri,
113
200
  });
201
+ // Create retry link with configuration
202
+ const retryLink = new RetryLink({
203
+ delay: {
204
+ initial: this.retryConfig.initialDelay || 300,
205
+ max: this.retryConfig.maxDelay || 30000,
206
+ jitter: this.retryConfig.jitter !== false,
207
+ },
208
+ attempts: {
209
+ max: this.retryConfig.maxAttempts || 5,
210
+ retryIf: (error, _operation) => {
211
+ // Check if we should retry this error
212
+ if (!error)
213
+ return false;
214
+ // Check for network errors
215
+ const hasNetworkError = !!error.networkError;
216
+ if (!hasNetworkError)
217
+ return false;
218
+ // Get status code from different possible locations
219
+ const statusCode = error.networkError?.statusCode ||
220
+ error.networkError?.response?.status ||
221
+ error.statusCode;
222
+ // Check if status code is retryable
223
+ if (statusCode && this.retryConfig.retryableStatusCodes) {
224
+ const shouldRetry = this.retryConfig.retryableStatusCodes.includes(statusCode);
225
+ // Call onRetry callback if provided
226
+ if (shouldRetry && this.retryConfig.onRetry && _operation.getContext().retryCount !== undefined) {
227
+ const attempt = _operation.getContext().retryCount + 1;
228
+ this.retryConfig.onRetry(attempt, error, _operation);
229
+ }
230
+ return shouldRetry;
231
+ }
232
+ // Default: retry on network errors without specific status codes
233
+ return true;
234
+ },
235
+ },
236
+ });
114
237
  const authLink = new ApolloLink((operation, forward) => {
115
238
  operation.setContext({
116
239
  headers: {
@@ -119,8 +242,9 @@ class Graphlit {
119
242
  });
120
243
  return forward(operation);
121
244
  });
245
+ // Chain links: retry -> auth -> http
122
246
  this.client = new ApolloClient({
123
- link: authLink.concat(httpLink),
247
+ link: ApolloLink.from([retryLink, authLink, httpLink]),
124
248
  cache: new InMemoryCache(),
125
249
  defaultOptions: {
126
250
  watchQuery: {
@@ -159,6 +283,60 @@ class Graphlit {
159
283
  setGoogleClient(client) {
160
284
  this.googleClient = client;
161
285
  }
286
+ /**
287
+ * Set a custom Groq client instance for streaming
288
+ * @param client - Groq client instance (e.g., new Groq({ apiKey: "..." }))
289
+ */
290
+ setGroqClient(client) {
291
+ this.groqClient = client;
292
+ }
293
+ /**
294
+ * Set a custom Cerebras client instance for streaming (OpenAI-compatible)
295
+ * @param client - OpenAI client instance configured for Cerebras (e.g., new OpenAI({ apiKey: "...", baseURL: "https://api.cerebras.ai/v1" }))
296
+ */
297
+ setCerebrasClient(client) {
298
+ this.cerebrasClient = client;
299
+ }
300
+ /**
301
+ * Set a custom Cohere client instance for streaming
302
+ * @param client - Cohere client instance (e.g., new CohereClient({ token: "..." }))
303
+ */
304
+ setCohereClient(client) {
305
+ this.cohereClient = client;
306
+ }
307
+ /**
308
+ * Set a custom Mistral client instance for streaming
309
+ * @param client - Mistral client instance (e.g., new Mistral({ apiKey: "..." }))
310
+ */
311
+ setMistralClient(client) {
312
+ this.mistralClient = client;
313
+ }
314
+ /**
315
+ * Set a custom Bedrock client instance for streaming
316
+ * @param client - BedrockRuntimeClient instance (e.g., new BedrockRuntimeClient({ region: "us-east-2" }))
317
+ */
318
+ setBedrockClient(client) {
319
+ this.bedrockClient = client;
320
+ }
321
+ /**
322
+ * Set a custom Deepseek client instance for streaming
323
+ * @param client - OpenAI client instance configured for Deepseek (e.g., new OpenAI({ baseURL: "https://api.deepseek.com", apiKey: "..." }))
324
+ */
325
+ setDeepseekClient(client) {
326
+ this.deepseekClient = client;
327
+ }
328
+ /**
329
+ * Update retry configuration and refresh the Apollo client
330
+ * @param retryConfig - New retry configuration
331
+ */
332
+ setRetryConfig(retryConfig) {
333
+ this.retryConfig = {
334
+ ...this.retryConfig,
335
+ ...retryConfig
336
+ };
337
+ // Refresh client to apply new retry configuration
338
+ this.refreshClient();
339
+ }
162
340
  generateToken() {
163
341
  if (!this.jwtSecret) {
164
342
  throw new Error("Graphlit environment JWT secret is required.");
@@ -1438,6 +1616,19 @@ class Graphlit {
1438
1616
  return Anthropic !== undefined || this.anthropicClient !== undefined;
1439
1617
  case Types.ModelServiceTypes.Google:
1440
1618
  return (GoogleGenerativeAI !== undefined || this.googleClient !== undefined);
1619
+ case Types.ModelServiceTypes.Groq:
1620
+ return Groq !== undefined || this.groqClient !== undefined;
1621
+ case Types.ModelServiceTypes.Cerebras:
1622
+ return OpenAI !== undefined || this.cerebrasClient !== undefined;
1623
+ case Types.ModelServiceTypes.Cohere:
1624
+ return CohereClient !== undefined || this.cohereClient !== undefined;
1625
+ case Types.ModelServiceTypes.Mistral:
1626
+ return Mistral !== undefined || this.mistralClient !== undefined;
1627
+ case Types.ModelServiceTypes.Bedrock:
1628
+ return (BedrockRuntimeClient !== undefined ||
1629
+ this.bedrockClient !== undefined);
1630
+ case Types.ModelServiceTypes.Deepseek:
1631
+ return OpenAI !== undefined || this.deepseekClient !== undefined;
1441
1632
  default:
1442
1633
  return false;
1443
1634
  }
@@ -1447,7 +1638,19 @@ class Graphlit {
1447
1638
  const hasOpenAI = OpenAI !== undefined || this.openaiClient !== undefined;
1448
1639
  const hasAnthropic = Anthropic !== undefined || this.anthropicClient !== undefined;
1449
1640
  const hasGoogle = GoogleGenerativeAI !== undefined || this.googleClient !== undefined;
1450
- return hasOpenAI || hasAnthropic || hasGoogle;
1641
+ const hasGroq = Groq !== undefined || this.groqClient !== undefined;
1642
+ const hasCerebras = OpenAI !== undefined || this.cerebrasClient !== undefined;
1643
+ const hasCohere = CohereClient !== undefined || this.cohereClient !== undefined;
1644
+ const hasMistral = Mistral !== undefined || this.mistralClient !== undefined;
1645
+ const hasBedrock = BedrockRuntimeClient !== undefined || this.bedrockClient !== undefined;
1646
+ return (hasOpenAI ||
1647
+ hasAnthropic ||
1648
+ hasGoogle ||
1649
+ hasGroq ||
1650
+ hasCerebras ||
1651
+ hasCohere ||
1652
+ hasMistral ||
1653
+ hasBedrock);
1451
1654
  }
1452
1655
  /**
1453
1656
  * Execute an agent with non-streaming response
@@ -1534,16 +1737,20 @@ class Graphlit {
1534
1737
  rounds,
1535
1738
  };
1536
1739
  // Build usage info if we have token data
1537
- const usage = totalTokens > 0 ? {
1538
- promptTokens: 0, // We don't have this breakdown from the API
1539
- completionTokens: totalTokens,
1540
- totalTokens: totalTokens,
1541
- model: currentMessage?.model || undefined,
1542
- } : undefined;
1740
+ const usage = totalTokens > 0
1741
+ ? {
1742
+ promptTokens: 0, // We don't have this breakdown from the API
1743
+ completionTokens: totalTokens,
1744
+ totalTokens: totalTokens,
1745
+ model: currentMessage?.model || undefined,
1746
+ }
1747
+ : undefined;
1543
1748
  return {
1544
1749
  message: currentMessage?.message || "",
1545
1750
  conversationId: actualConversationId,
1546
- conversationMessage: currentMessage ? currentMessage : undefined,
1751
+ conversationMessage: currentMessage
1752
+ ? currentMessage
1753
+ : undefined,
1547
1754
  toolCalls: currentMessage?.toolCalls?.filter((tc) => tc !== null),
1548
1755
  toolResults: allToolCalls,
1549
1756
  metrics,
@@ -1607,6 +1814,17 @@ class Graphlit {
1607
1814
  ? (await this.getSpecification(specification.id))
1608
1815
  .specification
1609
1816
  : undefined;
1817
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING && fullSpec) {
1818
+ console.log(`🔍 [streamAgent] Retrieved full specification:`, {
1819
+ id: fullSpec.id,
1820
+ name: fullSpec.name,
1821
+ serviceType: fullSpec.serviceType,
1822
+ hasDeepseek: !!fullSpec.deepseek,
1823
+ deepseekModel: fullSpec.deepseek?.model,
1824
+ deepseekModelName: fullSpec.deepseek?.modelName,
1825
+ deepseekTemperature: fullSpec.deepseek?.temperature,
1826
+ });
1827
+ }
1610
1828
  // Ensure conversation exists first (before streaming check)
1611
1829
  let actualConversationId = conversationId;
1612
1830
  if (!actualConversationId) {
@@ -1723,7 +1941,7 @@ class Graphlit {
1723
1941
  if (!formattedMessage?.message) {
1724
1942
  throw new Error("Failed to format conversation");
1725
1943
  }
1726
- if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1944
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_FORMAT) {
1727
1945
  console.log("\n📋 [formatConversation] Full response:", JSON.stringify(formatResponse, null, 2));
1728
1946
  console.log("\n📋 [formatConversation] Response - current message:", formattedMessage.message);
1729
1947
  console.log(`📋 [formatConversation] Conversation history: ${conversationHistory?.length || 0} messages`);
@@ -1864,6 +2082,108 @@ class Graphlit {
1864
2082
  console.log(`\n🏁 [Streaming] Google native streaming completed (Round ${currentRound})`);
1865
2083
  }
1866
2084
  }
2085
+ else if (serviceType === Types.ModelServiceTypes.Groq &&
2086
+ (Groq || this.groqClient)) {
2087
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2088
+ console.log(`\n✅ [Streaming] Using Groq native streaming (Round ${currentRound})`);
2089
+ }
2090
+ const groqMessages = formatMessagesForOpenAI(messages); // Groq uses OpenAI format
2091
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2092
+ console.log(`🔍 [Groq] Sending ${groqMessages.length} messages to LLM: ${JSON.stringify(groqMessages)}`);
2093
+ }
2094
+ await this.streamWithGroq(specification, groqMessages, tools, uiAdapter, (message, calls) => {
2095
+ roundMessage = message;
2096
+ toolCalls = calls;
2097
+ });
2098
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2099
+ console.log(`\n🏁 [Streaming] Groq native streaming completed (Round ${currentRound})`);
2100
+ }
2101
+ }
2102
+ else if (serviceType === Types.ModelServiceTypes.Cerebras &&
2103
+ (OpenAI || this.cerebrasClient)) {
2104
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2105
+ console.log(`\n✅ [Streaming] Using Cerebras native streaming (Round ${currentRound})`);
2106
+ }
2107
+ const cerebrasMessages = formatMessagesForOpenAI(messages); // Cerebras uses OpenAI format
2108
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2109
+ console.log(`🔍 [Cerebras] Sending ${cerebrasMessages.length} messages to LLM: ${JSON.stringify(cerebrasMessages)}`);
2110
+ }
2111
+ await this.streamWithCerebras(specification, cerebrasMessages, tools, uiAdapter, (message, calls) => {
2112
+ roundMessage = message;
2113
+ toolCalls = calls;
2114
+ });
2115
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2116
+ console.log(`\n🏁 [Streaming] Cerebras native streaming completed (Round ${currentRound})`);
2117
+ }
2118
+ }
2119
+ else if (serviceType === Types.ModelServiceTypes.Cohere &&
2120
+ (CohereClient || this.cohereClient)) {
2121
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2122
+ console.log(`\n✅ [Streaming] Using Cohere native streaming (Round ${currentRound})`);
2123
+ }
2124
+ const cohereMessages = formatMessagesForCohere(messages);
2125
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2126
+ console.log(`🔍 [Cohere] Sending ${cohereMessages.length} messages to LLM: ${JSON.stringify(cohereMessages)}`);
2127
+ }
2128
+ await this.streamWithCohere(specification, cohereMessages, tools, uiAdapter, (message, calls) => {
2129
+ roundMessage = message;
2130
+ toolCalls = calls;
2131
+ });
2132
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2133
+ console.log(`\n🏁 [Streaming] Cohere native streaming completed (Round ${currentRound})`);
2134
+ }
2135
+ }
2136
+ else if (serviceType === Types.ModelServiceTypes.Mistral &&
2137
+ (Mistral || this.mistralClient)) {
2138
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2139
+ console.log(`\n✅ [Streaming] Using Mistral native streaming (Round ${currentRound})`);
2140
+ }
2141
+ const mistralMessages = formatMessagesForMistral(messages);
2142
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2143
+ console.log(`🔍 [Mistral] Sending ${mistralMessages.length} messages to LLM: ${JSON.stringify(mistralMessages)}`);
2144
+ }
2145
+ await this.streamWithMistral(specification, mistralMessages, tools, uiAdapter, (message, calls) => {
2146
+ roundMessage = message;
2147
+ toolCalls = calls;
2148
+ });
2149
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2150
+ console.log(`\n🏁 [Streaming] Mistral native streaming completed (Round ${currentRound})`);
2151
+ }
2152
+ }
2153
+ else if (serviceType === Types.ModelServiceTypes.Bedrock &&
2154
+ (BedrockRuntimeClient || this.bedrockClient)) {
2155
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2156
+ console.log(`\n✅ [Streaming] Using Bedrock native streaming (Round ${currentRound})`);
2157
+ }
2158
+ const { system, messages: bedrockMessages } = formatMessagesForBedrock(messages);
2159
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2160
+ console.log(`🔍 [Bedrock] Sending ${bedrockMessages.length} messages to LLM (system: ${system ? "yes" : "no"}): ${JSON.stringify(bedrockMessages)}`);
2161
+ }
2162
+ await this.streamWithBedrock(specification, bedrockMessages, system, tools, uiAdapter, (message, calls) => {
2163
+ roundMessage = message;
2164
+ toolCalls = calls;
2165
+ });
2166
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2167
+ console.log(`\n🏁 [Streaming] Bedrock native streaming completed (Round ${currentRound})`);
2168
+ }
2169
+ }
2170
+ else if (serviceType === Types.ModelServiceTypes.Deepseek &&
2171
+ (OpenAI || this.deepseekClient)) {
2172
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2173
+ console.log(`\n✅ [Streaming] Using Deepseek native streaming (Round ${currentRound})`);
2174
+ }
2175
+ const deepseekMessages = formatMessagesForOpenAI(messages); // Deepseek uses OpenAI format
2176
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2177
+ console.log(`🔍 [Deepseek] Sending ${deepseekMessages.length} messages to LLM: ${JSON.stringify(deepseekMessages)}`);
2178
+ }
2179
+ await this.streamWithDeepseek(specification, deepseekMessages, tools, uiAdapter, (message, calls) => {
2180
+ roundMessage = message;
2181
+ toolCalls = calls;
2182
+ });
2183
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2184
+ console.log(`\n🏁 [Streaming] Deepseek native streaming completed (Round ${currentRound})`);
2185
+ }
2186
+ }
1867
2187
  else {
1868
2188
  // Fallback to non-streaming
1869
2189
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -2249,6 +2569,135 @@ class Graphlit {
2249
2569
  }
2250
2570
  await streamWithGoogle(specification, messages, systemPrompt, tools, googleClient, (event) => uiAdapter.handleEvent(event), onComplete);
2251
2571
  }
2572
+ /**
2573
+ * Stream with Groq client (OpenAI-compatible)
2574
+ */
2575
+ async streamWithGroq(specification, messages, tools, uiAdapter, onComplete) {
2576
+ // Check if we have either the Groq module or a provided client
2577
+ if (!Groq && !this.groqClient) {
2578
+ throw new Error("Groq client not available");
2579
+ }
2580
+ // Use provided client or create a new one
2581
+ const groqClient = this.groqClient ||
2582
+ (Groq
2583
+ ? new Groq({ apiKey: process.env.GROQ_API_KEY || "" })
2584
+ : (() => {
2585
+ throw new Error("Groq module not available");
2586
+ })());
2587
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2588
+ console.log(`🚀 [Graphlit SDK] Routing to Groq streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2589
+ }
2590
+ await streamWithGroq(specification, messages, tools, groqClient, (event) => uiAdapter.handleEvent(event), onComplete);
2591
+ }
2592
+ /**
2593
+ * Stream with Cerebras client (OpenAI-compatible)
2594
+ */
2595
+ async streamWithCerebras(specification, messages, tools, uiAdapter, onComplete) {
2596
+ // Check if we have either the OpenAI module or a provided client
2597
+ if (!OpenAI && !this.cerebrasClient) {
2598
+ throw new Error("Cerebras client not available");
2599
+ }
2600
+ // Use provided client or create a new one configured for Cerebras
2601
+ const cerebrasClient = this.cerebrasClient ||
2602
+ (OpenAI
2603
+ ? new OpenAI({
2604
+ apiKey: process.env.CEREBRAS_API_KEY || "",
2605
+ baseURL: "https://api.cerebras.ai/v1",
2606
+ })
2607
+ : (() => {
2608
+ throw new Error("OpenAI module not available for Cerebras");
2609
+ })());
2610
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2611
+ console.log(`🚀 [Graphlit SDK] Routing to Cerebras streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2612
+ }
2613
+ await streamWithCerebras(specification, messages, tools, cerebrasClient, (event) => uiAdapter.handleEvent(event), onComplete);
2614
+ }
2615
+ /**
2616
+ * Stream with Cohere client
2617
+ */
2618
+ async streamWithCohere(specification, messages, tools, uiAdapter, onComplete) {
2619
+ // Check if we have either the Cohere module or a provided client
2620
+ if (!CohereClient && !this.cohereClient) {
2621
+ throw new Error("Cohere client not available");
2622
+ }
2623
+ // Use provided client or create a new one
2624
+ const cohereClient = this.cohereClient ||
2625
+ (CohereClient
2626
+ ? new CohereClient({ token: process.env.COHERE_API_KEY || "" })
2627
+ : (() => {
2628
+ throw new Error("Cohere module not available");
2629
+ })());
2630
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2631
+ console.log(`🚀 [Graphlit SDK] Routing to Cohere streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2632
+ }
2633
+ await streamWithCohere(specification, messages, tools, cohereClient, (event) => uiAdapter.handleEvent(event), onComplete);
2634
+ }
2635
+ /**
2636
+ * Stream with Mistral client
2637
+ */
2638
+ async streamWithMistral(specification, messages, tools, uiAdapter, onComplete) {
2639
+ // Check if we have either the Mistral module or a provided client
2640
+ if (!Mistral && !this.mistralClient) {
2641
+ throw new Error("Mistral client not available");
2642
+ }
2643
+ // Use provided client or create a new one
2644
+ const mistralClient = this.mistralClient ||
2645
+ (Mistral
2646
+ ? new Mistral({ apiKey: process.env.MISTRAL_API_KEY || "" })
2647
+ : (() => {
2648
+ throw new Error("Mistral module not available");
2649
+ })());
2650
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2651
+ console.log(`🚀 [Graphlit SDK] Routing to Mistral streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2652
+ }
2653
+ await streamWithMistral(specification, messages, tools, mistralClient, (event) => uiAdapter.handleEvent(event), onComplete);
2654
+ }
2655
+ /**
2656
+ * Stream with Bedrock client
2657
+ */
2658
+ async streamWithBedrock(specification, messages, systemPrompt, tools, uiAdapter, onComplete) {
2659
+ // Check if we have either the Bedrock module or a provided client
2660
+ if (!BedrockRuntimeClient && !this.bedrockClient) {
2661
+ throw new Error("Bedrock client not available");
2662
+ }
2663
+ // Use provided client or create a new one
2664
+ const bedrockClient = this.bedrockClient ||
2665
+ (BedrockRuntimeClient
2666
+ ? new BedrockRuntimeClient({
2667
+ region: process.env.AWS_REGION || "us-east-2",
2668
+ })
2669
+ : (() => {
2670
+ throw new Error("Bedrock module not available");
2671
+ })());
2672
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2673
+ 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"}`);
2674
+ }
2675
+ await streamWithBedrock(specification, messages, systemPrompt, tools, bedrockClient, (event) => uiAdapter.handleEvent(event), onComplete);
2676
+ }
2677
+ /**
2678
+ * Stream with Deepseek client
2679
+ */
2680
+ async streamWithDeepseek(specification, messages, tools, uiAdapter, onComplete) {
2681
+ // Check if we have either the OpenAI module or a provided Deepseek client
2682
+ if (!OpenAI && !this.deepseekClient) {
2683
+ throw new Error("Deepseek client not available (requires OpenAI SDK)");
2684
+ }
2685
+ // Use provided client or create a new one with Deepseek base URL
2686
+ const deepseekClient = this.deepseekClient ||
2687
+ (OpenAI
2688
+ ? new OpenAI({
2689
+ baseURL: "https://api.deepseek.com",
2690
+ apiKey: process.env.DEEPSEEK_API_KEY || "",
2691
+ })
2692
+ : null);
2693
+ if (!deepseekClient) {
2694
+ throw new Error("Failed to create Deepseek client");
2695
+ }
2696
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2697
+ console.log(`🚀 [Graphlit SDK] Routing to Deepseek streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2698
+ }
2699
+ await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete);
2700
+ }
2252
2701
  // Helper method to execute tools for promptAgent
2253
2702
  async executeToolsForPromptAgent(toolCalls, toolHandlers, allToolCalls, signal) {
2254
2703
  const responses = [];
@@ -973,6 +973,7 @@ export const GetContent = gql `
973
973
  mimeType
974
974
  format
975
975
  formatName
976
+ fileExtension
976
977
  fileName
977
978
  fileSize
978
979
  masterUri
@@ -988,6 +989,7 @@ export const GetContent = gql `
988
989
  posts
989
990
  chapters
990
991
  questions
992
+ quotes
991
993
  video {
992
994
  width
993
995
  height
@@ -1642,6 +1644,7 @@ export const LookupContents = gql `
1642
1644
  mimeType
1643
1645
  format
1644
1646
  formatName
1647
+ fileExtension
1645
1648
  fileName
1646
1649
  fileSize
1647
1650
  masterUri
@@ -1657,6 +1660,7 @@ export const LookupContents = gql `
1657
1660
  posts
1658
1661
  chapters
1659
1662
  questions
1663
+ quotes
1660
1664
  video {
1661
1665
  width
1662
1666
  height
@@ -2156,6 +2160,9 @@ export const QueryContents = gql `
2156
2160
  type
2157
2161
  fileType
2158
2162
  mimeType
2163
+ format
2164
+ formatName
2165
+ fileExtension
2159
2166
  fileName
2160
2167
  fileSize
2161
2168
  masterUri