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/README.md +235 -5
- package/dist/client.d.ts +26 -1
- package/dist/client.js +293 -55
- package/dist/generated/graphql-documents.d.ts +21 -0
- package/dist/generated/graphql-documents.js +1378 -0
- package/dist/generated/graphql-types.d.ts +2660 -53
- package/dist/generated/graphql-types.js +119 -0
- package/dist/streaming/llm-formatters.js +68 -5
- package/dist/streaming/providers.d.ts +18 -13
- package/dist/streaming/providers.js +690 -167
- package/dist/streaming/ui-event-adapter.d.ts +7 -0
- package/dist/streaming/ui-event-adapter.js +55 -0
- package/dist/types/internal.d.ts +11 -0
- package/dist/types/ui-events.d.ts +9 -0
- package/package.json +1 -1
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,
|
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 ||
|
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
|
-
|
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 ||
|
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
|
-
|
2360
|
+
// V2 API uses raw messages, not formatted
|
2188
2361
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
|
2189
|
-
console.log(`🔍 [Cohere] Sending ${
|
2362
|
+
console.log(`🔍 [Cohere] Sending ${messages.length} messages to LLM`);
|
2190
2363
|
}
|
2191
|
-
await this.streamWithCohere(specification,
|
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
|
-
|
2206
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
(
|
2694
|
-
? new
|
2695
|
-
:
|
2696
|
-
|
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
|
-
?
|
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) {
|