graphlit-client 1.0.20250924004 → 1.0.20250925001
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 +59 -2
- package/dist/client.d.ts +1 -1
- package/dist/client.js +14 -14
- package/dist/streaming/providers.js +101 -85
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -16,6 +16,13 @@ Graphlit is a cloud platform that handles the complex parts of building AI appli
|
|
|
16
16
|
|
|
17
17
|
## ✨ What's New
|
|
18
18
|
|
|
19
|
+
### v1.3.0 - Google SDK Migration 🔄
|
|
20
|
+
|
|
21
|
+
- **BREAKING CHANGE**: Migrated from deprecated `@google/generative-ai` to new `@google/genai` SDK
|
|
22
|
+
- **Improved Thinking Support** - Better detection of Google Gemini thinking/reasoning with proper `part.thought` API
|
|
23
|
+
- **Enhanced Streaming** - More reliable streaming with the new Google SDK
|
|
24
|
+
- **Migration Required** - See [Migration Guide](#migrating-from-google-generative-ai) below
|
|
25
|
+
|
|
19
26
|
### v1.2.0 - Reasoning & Cancellation Support 🧠
|
|
20
27
|
|
|
21
28
|
- **Reasoning/Thinking Detection** - See how AI models think through problems (Bedrock Nova, Deepseek, Anthropic)
|
|
@@ -35,6 +42,7 @@ Graphlit is a cloud platform that handles the complex parts of building AI appli
|
|
|
35
42
|
- [Quick Start](#quick-start)
|
|
36
43
|
- [Installation](#installation)
|
|
37
44
|
- [Setting Up](#setting-up)
|
|
45
|
+
- [Migrating from @google/generative-ai](#migrating-from-google-generative-ai) 🔄
|
|
38
46
|
- [Reasoning Support (New!)](#reasoning-support-new) 🧠
|
|
39
47
|
- [Stream Cancellation (New!)](#stream-cancellation-new) 🛑
|
|
40
48
|
- [Network Resilience](#network-resilience)
|
|
@@ -107,7 +115,7 @@ npm install openai
|
|
|
107
115
|
npm install @anthropic-ai/sdk
|
|
108
116
|
|
|
109
117
|
# For Google streaming
|
|
110
|
-
npm install @google/
|
|
118
|
+
npm install @google/genai
|
|
111
119
|
|
|
112
120
|
# For Groq streaming (OpenAI-compatible)
|
|
113
121
|
npm install groq-sdk
|
|
@@ -155,6 +163,55 @@ AWS_ACCESS_KEY_ID=your_key
|
|
|
155
163
|
AWS_SECRET_ACCESS_KEY=your_secret
|
|
156
164
|
```
|
|
157
165
|
|
|
166
|
+
## Migrating from @google/generative-ai
|
|
167
|
+
|
|
168
|
+
### ⚠️ Breaking Change in v1.3.0
|
|
169
|
+
|
|
170
|
+
The deprecated `@google/generative-ai` SDK has been replaced with the new `@google/genai` SDK. This change provides better thinking/reasoning support and improved streaming reliability.
|
|
171
|
+
|
|
172
|
+
### Migration Steps
|
|
173
|
+
|
|
174
|
+
1. **Update your dependencies:**
|
|
175
|
+
```bash
|
|
176
|
+
# Remove old SDK
|
|
177
|
+
npm uninstall @google/generative-ai
|
|
178
|
+
|
|
179
|
+
# Install new SDK
|
|
180
|
+
npm install @google/genai
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
2. **Update your client initialization:**
|
|
184
|
+
```typescript
|
|
185
|
+
// Old (deprecated)
|
|
186
|
+
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
187
|
+
const googleClient = new GoogleGenerativeAI(apiKey);
|
|
188
|
+
client.setGoogleClient(googleClient);
|
|
189
|
+
|
|
190
|
+
// New
|
|
191
|
+
import { GoogleGenAI } from "@google/genai";
|
|
192
|
+
const googleClient = new GoogleGenAI({ apiKey });
|
|
193
|
+
client.setGoogleClient(googleClient);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
3. **No other code changes required!**
|
|
197
|
+
- The Graphlit SDK handles all the API differences internally
|
|
198
|
+
- Your existing specifications and conversations will continue to work
|
|
199
|
+
- Thinking/reasoning detection is now more reliable with proper `part.thought` support
|
|
200
|
+
|
|
201
|
+
### Why the Migration?
|
|
202
|
+
|
|
203
|
+
- The `@google/generative-ai` SDK is deprecated by Google
|
|
204
|
+
- New SDK provides better support for Gemini 2.x features including thinking mode
|
|
205
|
+
- Improved streaming performance and reliability
|
|
206
|
+
- Proper detection of thought parts without markdown parsing hacks
|
|
207
|
+
|
|
208
|
+
### Benefits
|
|
209
|
+
|
|
210
|
+
- **Better Thinking Detection**: Properly detects and separates thinking content using Google's official API
|
|
211
|
+
- **Improved Performance**: More efficient streaming with the new SDK architecture
|
|
212
|
+
- **Future-Proof**: Ensures compatibility with upcoming Gemini models and features
|
|
213
|
+
- **Cleaner API**: Simplified configuration and better TypeScript types
|
|
214
|
+
|
|
158
215
|
## Reasoning Support (New!) 🧠
|
|
159
216
|
|
|
160
217
|
The SDK can detect and expose AI reasoning processes, showing you how models "think" through problems. This feature works with models that support reasoning output.
|
|
@@ -380,7 +437,7 @@ The Graphlit SDK supports real-time streaming responses from 9 different LLM pro
|
|
|
380
437
|
| --------------- | --------------------------------------------- | --------------------------------- | ------------------- |
|
|
381
438
|
| **OpenAI** | GPT-4, GPT-4o, GPT-4.1, O1, O3, O4 | `openai` | `OPENAI_API_KEY` |
|
|
382
439
|
| **Anthropic** | Claude 3, Claude 3.5, Claude 3.7, Claude 4 | `@anthropic-ai/sdk` | `ANTHROPIC_API_KEY` |
|
|
383
|
-
| **Google** | Gemini 1.5, Gemini 2.0, Gemini 2.5 | `@google/
|
|
440
|
+
| **Google** | Gemini 1.5, Gemini 2.0, Gemini 2.5 | `@google/genai` | `GOOGLE_API_KEY` |
|
|
384
441
|
| **Groq** | Llama 4, Llama 3.3, Mixtral, Deepseek R1 | `groq-sdk` | `GROQ_API_KEY` |
|
|
385
442
|
| **Cerebras** | Llama 3.3, Llama 3.1 | `openai` | `CEREBRAS_API_KEY` |
|
|
386
443
|
| **Cohere** | Command R+, Command R, Command R7B, Command A | `cohere-ai` | `COHERE_API_KEY` |
|
package/dist/client.d.ts
CHANGED
|
@@ -63,7 +63,7 @@ declare class Graphlit {
|
|
|
63
63
|
setAnthropicClient(client: any): void;
|
|
64
64
|
/**
|
|
65
65
|
* Set a custom Google Generative AI client instance for streaming
|
|
66
|
-
* @param client - Google
|
|
66
|
+
* @param client - Google GenAI client instance (e.g., new GoogleGenAI({apiKey}))
|
|
67
67
|
*/
|
|
68
68
|
setGoogleClient(client: any): void;
|
|
69
69
|
/**
|
package/dist/client.js
CHANGED
|
@@ -17,7 +17,7 @@ import { createRequire } from "node:module";
|
|
|
17
17
|
const optionalRequire = createRequire(import.meta.url);
|
|
18
18
|
let OpenAI;
|
|
19
19
|
let Anthropic;
|
|
20
|
-
let
|
|
20
|
+
let GoogleGenAI;
|
|
21
21
|
let Groq;
|
|
22
22
|
let CohereClient;
|
|
23
23
|
let CohereClientV2;
|
|
@@ -51,15 +51,15 @@ catch (e) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
|
-
|
|
54
|
+
GoogleGenAI = optionalRequire("@google/genai").GoogleGenAI;
|
|
55
55
|
if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
|
|
56
|
-
console.log("[SDK Loading] Google
|
|
56
|
+
console.log("[SDK Loading] Google Gen AI SDK loaded successfully");
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
catch (e) {
|
|
60
|
-
// Google
|
|
60
|
+
// Google Gen AI not installed
|
|
61
61
|
if (process.env.DEBUG_GRAPHLIT_SDK_INITIALIZATION) {
|
|
62
|
-
console.log("[SDK Loading] Google
|
|
62
|
+
console.log("[SDK Loading] Google Gen AI SDK not found:", e.message);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
try {
|
|
@@ -321,7 +321,7 @@ class Graphlit {
|
|
|
321
321
|
}
|
|
322
322
|
/**
|
|
323
323
|
* Set a custom Google Generative AI client instance for streaming
|
|
324
|
-
* @param client - Google
|
|
324
|
+
* @param client - Google GenAI client instance (e.g., new GoogleGenAI({apiKey}))
|
|
325
325
|
*/
|
|
326
326
|
setGoogleClient(client) {
|
|
327
327
|
this.googleClient = client;
|
|
@@ -1832,7 +1832,7 @@ class Graphlit {
|
|
|
1832
1832
|
instanceOpenAI: this.openaiClient !== undefined,
|
|
1833
1833
|
moduleAnthropic: Anthropic !== undefined,
|
|
1834
1834
|
instanceAnthropic: this.anthropicClient !== undefined,
|
|
1835
|
-
moduleGoogle:
|
|
1835
|
+
moduleGoogle: GoogleGenAI !== undefined,
|
|
1836
1836
|
instanceGoogle: this.googleClient !== undefined,
|
|
1837
1837
|
});
|
|
1838
1838
|
}
|
|
@@ -1842,7 +1842,7 @@ class Graphlit {
|
|
|
1842
1842
|
case Types.ModelServiceTypes.Anthropic:
|
|
1843
1843
|
return Anthropic !== undefined || this.anthropicClient !== undefined;
|
|
1844
1844
|
case Types.ModelServiceTypes.Google:
|
|
1845
|
-
return (
|
|
1845
|
+
return (GoogleGenAI !== undefined || this.googleClient !== undefined);
|
|
1846
1846
|
case Types.ModelServiceTypes.Groq:
|
|
1847
1847
|
return Groq !== undefined || this.groqClient !== undefined;
|
|
1848
1848
|
case Types.ModelServiceTypes.Cerebras:
|
|
@@ -1880,7 +1880,7 @@ class Graphlit {
|
|
|
1880
1880
|
// Check both module-level SDKs and instance-level clients
|
|
1881
1881
|
const hasOpenAI = OpenAI !== undefined || this.openaiClient !== undefined;
|
|
1882
1882
|
const hasAnthropic = Anthropic !== undefined || this.anthropicClient !== undefined;
|
|
1883
|
-
const hasGoogle =
|
|
1883
|
+
const hasGoogle = GoogleGenAI !== undefined || this.googleClient !== undefined;
|
|
1884
1884
|
const hasGroq = Groq !== undefined || this.groqClient !== undefined;
|
|
1885
1885
|
const hasCerebras = Cerebras !== undefined || this.cerebrasClient !== undefined;
|
|
1886
1886
|
const hasCohere = CohereClient !== undefined ||
|
|
@@ -2338,7 +2338,7 @@ class Graphlit {
|
|
|
2338
2338
|
console.log(`\n🔀 [Streaming Decision] Service: ${serviceType}, Round: ${currentRound}`);
|
|
2339
2339
|
console.log(` OpenAI available: ${!!(OpenAI || this.openaiClient)}`);
|
|
2340
2340
|
console.log(` Anthropic available: ${!!(Anthropic || this.anthropicClient)}`);
|
|
2341
|
-
console.log(` Google available: ${!!(
|
|
2341
|
+
console.log(` Google available: ${!!(GoogleGenAI || this.googleClient)}`);
|
|
2342
2342
|
}
|
|
2343
2343
|
if (serviceType === Types.ModelServiceTypes.OpenAi &&
|
|
2344
2344
|
(OpenAI || this.openaiClient)) {
|
|
@@ -2381,7 +2381,7 @@ class Graphlit {
|
|
|
2381
2381
|
}
|
|
2382
2382
|
}
|
|
2383
2383
|
else if (serviceType === Types.ModelServiceTypes.Google &&
|
|
2384
|
-
(
|
|
2384
|
+
(GoogleGenAI || this.googleClient)) {
|
|
2385
2385
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
2386
2386
|
console.log(`\n✅ [Streaming] Using Google native streaming (Round ${currentRound})`);
|
|
2387
2387
|
}
|
|
@@ -2959,13 +2959,13 @@ class Graphlit {
|
|
|
2959
2959
|
*/
|
|
2960
2960
|
async streamWithGoogle(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
|
|
2961
2961
|
// Check if we have either the Google module or a provided client
|
|
2962
|
-
if (!
|
|
2962
|
+
if (!GoogleGenAI && !this.googleClient) {
|
|
2963
2963
|
throw new Error("Google GenerativeAI client not available");
|
|
2964
2964
|
}
|
|
2965
2965
|
// Use provided client or create a new one
|
|
2966
2966
|
const googleClient = this.googleClient ||
|
|
2967
|
-
(
|
|
2968
|
-
? new
|
|
2967
|
+
(GoogleGenAI
|
|
2968
|
+
? new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY || "" })
|
|
2969
2969
|
: (() => {
|
|
2970
2970
|
throw new Error("Google GenerativeAI module not available");
|
|
2971
2971
|
})());
|
|
@@ -914,6 +914,9 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
914
914
|
let toolArgumentTokens = 0;
|
|
915
915
|
let lastEventTime = 0;
|
|
916
916
|
const interTokenDelays = [];
|
|
917
|
+
// Thinking content detection state for Google
|
|
918
|
+
let hasEmittedThinkingStart = false;
|
|
919
|
+
let allThinkingContent = "";
|
|
917
920
|
// Tool calling metrics
|
|
918
921
|
const toolMetrics = {
|
|
919
922
|
totalTools: 0,
|
|
@@ -984,13 +987,17 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
984
987
|
maxOutputTokens: streamConfig.max_tokens,
|
|
985
988
|
};
|
|
986
989
|
if (thinkingConfig) {
|
|
987
|
-
// Google Gemini 2.5
|
|
990
|
+
// Google Gemini 2.5 supports thinking mode
|
|
991
|
+
// -1 = dynamic thinking (model decides), 0 = disabled, >0 = specific budget
|
|
992
|
+
const budget = thinkingConfig.budget_tokens === 0 ? 0 :
|
|
993
|
+
thinkingConfig.budget_tokens || -1; // Default to dynamic if not specified
|
|
988
994
|
generationConfig.thinkingConfig = {
|
|
989
|
-
thinkingBudget:
|
|
990
|
-
includeThoughts:
|
|
995
|
+
thinkingBudget: budget,
|
|
996
|
+
includeThoughts: budget !== 0, // Include thoughts unless explicitly disabled
|
|
991
997
|
};
|
|
992
998
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
993
|
-
|
|
999
|
+
const mode = budget === -1 ? "dynamic" : budget === 0 ? "disabled" : `${budget} tokens`;
|
|
1000
|
+
console.log(`🧠 [Google] Thinking mode: ${mode} | Include thoughts: ${budget !== 0}`);
|
|
994
1001
|
}
|
|
995
1002
|
}
|
|
996
1003
|
else {
|
|
@@ -1000,19 +1007,85 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1000
1007
|
includeThoughts: false,
|
|
1001
1008
|
};
|
|
1002
1009
|
}
|
|
1003
|
-
|
|
1010
|
+
// Convert messages to Google format for the new SDK
|
|
1011
|
+
// The new SDK expects contents as an array of message objects with role and parts
|
|
1012
|
+
const contents = messages.map((msg) => ({
|
|
1013
|
+
role: msg.role,
|
|
1014
|
+
parts: msg.parts,
|
|
1015
|
+
}));
|
|
1016
|
+
// Build the config object for the new SDK
|
|
1017
|
+
const config = {
|
|
1018
|
+
...generationConfig,
|
|
1019
|
+
};
|
|
1020
|
+
// Add tools to config if provided
|
|
1021
|
+
if (googleTools) {
|
|
1022
|
+
config.tools = googleTools;
|
|
1023
|
+
}
|
|
1024
|
+
// Call generateContentStream with conversation history
|
|
1025
|
+
const streamResponse = await googleClient.models.generateContentStream({
|
|
1004
1026
|
model: modelName,
|
|
1005
|
-
|
|
1006
|
-
|
|
1027
|
+
contents: contents, // Full conversation history
|
|
1028
|
+
config: config,
|
|
1007
1029
|
});
|
|
1008
|
-
//
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1030
|
+
// Track last chunk for usage metadata
|
|
1031
|
+
let lastChunk = null;
|
|
1032
|
+
// Process streaming chunks
|
|
1033
|
+
for await (const chunk of streamResponse) {
|
|
1034
|
+
lastChunk = chunk; // Keep track for usage metadata
|
|
1035
|
+
// Process parts separately to handle thought vs regular text
|
|
1036
|
+
let regularText = "";
|
|
1037
|
+
if (chunk.candidates?.[0]?.content?.parts) {
|
|
1038
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1039
|
+
console.log(`[Google] Chunk has ${chunk.candidates[0].content.parts.length} parts during streaming`);
|
|
1040
|
+
// Log details about each part
|
|
1041
|
+
for (let i = 0; i < chunk.candidates[0].content.parts.length; i++) {
|
|
1042
|
+
const part = chunk.candidates[0].content.parts[i];
|
|
1043
|
+
console.log(`[Google] Part ${i}: thought=${!!part.thought}, text length=${part.text?.length || 0}`);
|
|
1044
|
+
if (part.thought && part.text) {
|
|
1045
|
+
console.log(`[Google] THOUGHT CONTENT: "${part.text.substring(0, 100)}${part.text.length > 100 ? '...' : ''}"`);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
for (const part of chunk.candidates[0].content.parts) {
|
|
1050
|
+
if (part.thought && part.text && thinkingConfig) {
|
|
1051
|
+
// This is a thought part - emit as reasoning only
|
|
1052
|
+
if (!hasEmittedThinkingStart) {
|
|
1053
|
+
onEvent({ type: "reasoning_start", format: "markdown" });
|
|
1054
|
+
hasEmittedThinkingStart = true;
|
|
1055
|
+
allThinkingContent = "";
|
|
1056
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1057
|
+
console.log(`[Google] Started reasoning from thought part`);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
allThinkingContent += part.text + "\n";
|
|
1061
|
+
// Emit delta for streaming
|
|
1062
|
+
onEvent({
|
|
1063
|
+
type: "reasoning_delta",
|
|
1064
|
+
content: part.text,
|
|
1065
|
+
format: "markdown",
|
|
1066
|
+
});
|
|
1067
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1068
|
+
console.log(`[Google] Emitted reasoning delta from thought part: ${part.text.length} chars`);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
else if (!part.thought && part.text) {
|
|
1072
|
+
// Regular text part - add to message content
|
|
1073
|
+
regularText += part.text;
|
|
1074
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1075
|
+
console.log(`[Google] Regular text part (NOT thought): "${part.text.substring(0, 100)}${part.text.length > 100 ? '...' : ''}"`);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
// Use regularText to avoid including thought parts
|
|
1081
|
+
const text = regularText; // Only use text from non-thought parts
|
|
1082
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING && text) {
|
|
1083
|
+
console.log(`[Google] Text to add (excluding thoughts): "${text.substring(0, 100)}${text.length > 100 ? '...' : ''}" (${text.length} chars)`);
|
|
1084
|
+
}
|
|
1015
1085
|
if (text) {
|
|
1086
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1087
|
+
console.log(`[Google] Adding to fullMessage: "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}" (${text.length} chars)`);
|
|
1088
|
+
}
|
|
1016
1089
|
fullMessage += text;
|
|
1017
1090
|
tokenCount++;
|
|
1018
1091
|
const currentTime = Date.now();
|
|
@@ -1124,72 +1197,14 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1124
1197
|
}
|
|
1125
1198
|
}
|
|
1126
1199
|
}
|
|
1127
|
-
//
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
console.log(`[Google] Processing final response with ${candidate.content.parts.length} parts`);
|
|
1134
|
-
}
|
|
1135
|
-
if (candidate?.content?.parts) {
|
|
1136
|
-
for (const part of candidate.content.parts) {
|
|
1137
|
-
// Check for any final text we might have missed
|
|
1138
|
-
if (part.text) {
|
|
1139
|
-
const finalText = part.text;
|
|
1140
|
-
// Skip if this is just the complete message we already have
|
|
1141
|
-
if (finalText === fullMessage) {
|
|
1142
|
-
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1143
|
-
console.log(`[Google] Skipping duplicate final text (matches fullMessage exactly)`);
|
|
1144
|
-
}
|
|
1145
|
-
continue;
|
|
1146
|
-
}
|
|
1147
|
-
// Only add if it's not already included in fullMessage
|
|
1148
|
-
if (!fullMessage.includes(finalText) &&
|
|
1149
|
-
!fullMessage.endsWith(finalText)) {
|
|
1150
|
-
fullMessage += finalText;
|
|
1151
|
-
onEvent({
|
|
1152
|
-
type: "token",
|
|
1153
|
-
token: finalText,
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
// Check for function calls
|
|
1158
|
-
if (part.functionCall &&
|
|
1159
|
-
!toolCalls.some((tc) => tc.name === part.functionCall.name)) {
|
|
1160
|
-
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1161
|
-
console.log(`[Google] Found function call in final response: ${part.functionCall.name}`);
|
|
1162
|
-
}
|
|
1163
|
-
const toolCall = {
|
|
1164
|
-
id: `google_tool_${Date.now()}_${toolCalls.length}`,
|
|
1165
|
-
name: part.functionCall.name,
|
|
1166
|
-
arguments: JSON.stringify(part.functionCall.args || {}),
|
|
1167
|
-
};
|
|
1168
|
-
toolCalls.push(toolCall);
|
|
1169
|
-
// Emit events for function calls found in final response
|
|
1170
|
-
onEvent({
|
|
1171
|
-
type: "tool_call_start",
|
|
1172
|
-
toolCall: {
|
|
1173
|
-
id: toolCall.id,
|
|
1174
|
-
name: toolCall.name,
|
|
1175
|
-
},
|
|
1176
|
-
});
|
|
1177
|
-
onEvent({
|
|
1178
|
-
type: "tool_call_parsed",
|
|
1179
|
-
toolCall: {
|
|
1180
|
-
id: toolCall.id,
|
|
1181
|
-
name: toolCall.name,
|
|
1182
|
-
arguments: toolCall.arguments,
|
|
1183
|
-
},
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
catch (error) {
|
|
1190
|
-
// Log parsing errors when debugging
|
|
1200
|
+
// After streaming is complete, emit reasoning end if needed
|
|
1201
|
+
if (hasEmittedThinkingStart && allThinkingContent) {
|
|
1202
|
+
onEvent({
|
|
1203
|
+
type: "reasoning_end",
|
|
1204
|
+
fullContent: allThinkingContent.trim(),
|
|
1205
|
+
});
|
|
1191
1206
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1192
|
-
console.
|
|
1207
|
+
console.log(`[Google] Emitted reasoning_end with ${allThinkingContent.length} chars of thinking`);
|
|
1193
1208
|
}
|
|
1194
1209
|
}
|
|
1195
1210
|
// Final summary logging
|
|
@@ -1263,14 +1278,15 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1263
1278
|
}
|
|
1264
1279
|
console.log(`✅ [Google] Final message (${fullMessage.length} chars): "${fullMessage}"`);
|
|
1265
1280
|
}
|
|
1266
|
-
//
|
|
1281
|
+
// Usage data collection - new SDK may provide this differently
|
|
1282
|
+
// Check last chunk for usage metadata
|
|
1267
1283
|
try {
|
|
1268
|
-
|
|
1269
|
-
if (
|
|
1284
|
+
// Check if last chunk has usage metadata
|
|
1285
|
+
if (lastChunk?.usageMetadata) {
|
|
1270
1286
|
usageData = {
|
|
1271
|
-
prompt_tokens:
|
|
1272
|
-
completion_tokens:
|
|
1273
|
-
total_tokens:
|
|
1287
|
+
prompt_tokens: lastChunk.usageMetadata.promptTokenCount,
|
|
1288
|
+
completion_tokens: lastChunk.usageMetadata.candidatesTokenCount,
|
|
1289
|
+
total_tokens: lastChunk.usageMetadata.totalTokenCount,
|
|
1274
1290
|
};
|
|
1275
1291
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1276
1292
|
console.log(`[Google] Usage data captured:`, usageData);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphlit-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20250925001",
|
|
4
4
|
"description": "Graphlit API Client for TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/client.js",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@apollo/client": "^3.13.8",
|
|
48
48
|
"@cerebras/cerebras_cloud_sdk": "^1.35.0",
|
|
49
|
+
"@google/genai": "^1.20.0",
|
|
49
50
|
"@graphql-codegen/cli": "^5.0.7",
|
|
50
51
|
"@graphql-codegen/typescript": "^4.1.6",
|
|
51
52
|
"@graphql-codegen/typescript-operations": "^4.6.1",
|
|
@@ -60,9 +61,6 @@
|
|
|
60
61
|
"@anthropic-ai/sdk": {
|
|
61
62
|
"optional": true
|
|
62
63
|
},
|
|
63
|
-
"@google/generative-ai": {
|
|
64
|
-
"optional": true
|
|
65
|
-
},
|
|
66
64
|
"groq-sdk": {
|
|
67
65
|
"optional": true
|
|
68
66
|
},
|
|
@@ -79,7 +77,6 @@
|
|
|
79
77
|
"optionalDependencies": {
|
|
80
78
|
"@anthropic-ai/sdk": "^0.53.0",
|
|
81
79
|
"@aws-sdk/client-bedrock-runtime": "^3.828.0",
|
|
82
|
-
"@google/generative-ai": "^0.24.1",
|
|
83
80
|
"@mistralai/mistralai": "^1.7.2",
|
|
84
81
|
"cohere-ai": "^7.17.1",
|
|
85
82
|
"groq-sdk": "^0.25.0",
|