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/README.md +121 -21
- package/dist/client.d.ts +91 -1
- package/dist/client.js +473 -24
- package/dist/generated/graphql-documents.js +7 -0
- package/dist/generated/graphql-types.d.ts +7 -0
- package/dist/model-mapping.js +96 -1
- package/dist/streaming/llm-formatters.d.ts +57 -0
- package/dist/streaming/llm-formatters.js +172 -0
- package/dist/streaming/providers.d.ts +31 -1
- package/dist/streaming/providers.js +621 -1
- package/package.json +17 -1
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
|
-
|
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:
|
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
|
-
|
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
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
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
|
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.
|
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
|