graphlit-client 1.0.20250924003 → 1.0.20250924005
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/streaming/providers.js +77 -6
- package/package.json +1 -1
|
@@ -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,14 +987,25 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
984
987
|
maxOutputTokens: streamConfig.max_tokens,
|
|
985
988
|
};
|
|
986
989
|
if (thinkingConfig) {
|
|
987
|
-
// Google Gemini
|
|
988
|
-
//
|
|
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
|
|
994
|
+
generationConfig.thinkingConfig = {
|
|
995
|
+
thinkingBudget: budget,
|
|
996
|
+
includeThoughts: budget !== 0, // Include thoughts unless explicitly disabled
|
|
997
|
+
};
|
|
989
998
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
990
|
-
|
|
999
|
+
const mode = budget === -1 ? "dynamic" : budget === 0 ? "disabled" : `${budget} tokens`;
|
|
1000
|
+
console.log(`🧠 [Google] Thinking mode: ${mode} | Include thoughts: ${budget !== 0}`);
|
|
991
1001
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
//
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
// Explicitly disable thinking when not configured
|
|
1005
|
+
generationConfig.thinkingConfig = {
|
|
1006
|
+
thinkingBudget: 0, // Disable thinking by setting budget to 0
|
|
1007
|
+
includeThoughts: false,
|
|
1008
|
+
};
|
|
995
1009
|
}
|
|
996
1010
|
const model = googleClient.getGenerativeModel({
|
|
997
1011
|
model: modelName,
|
|
@@ -1004,6 +1018,23 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1004
1018
|
const chat = model.startChat({ history });
|
|
1005
1019
|
const result = await chat.sendMessageStream(prompt);
|
|
1006
1020
|
for await (const chunk of result.stream) {
|
|
1021
|
+
// Check for thought parts in streaming chunks first (Google's thinking API)
|
|
1022
|
+
if (thinkingConfig && chunk.candidates?.[0]?.content?.parts) {
|
|
1023
|
+
for (const part of chunk.candidates[0].content.parts) {
|
|
1024
|
+
if (part.thought && part.text) {
|
|
1025
|
+
// Emit thinking content as reasoning events
|
|
1026
|
+
if (!hasEmittedThinkingStart) {
|
|
1027
|
+
onEvent({ type: "reasoning_start", format: "markdown" });
|
|
1028
|
+
hasEmittedThinkingStart = true;
|
|
1029
|
+
allThinkingContent = "";
|
|
1030
|
+
}
|
|
1031
|
+
allThinkingContent += part.text + "\n";
|
|
1032
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1033
|
+
console.log(`[Google] Streaming thought part: ${part.text.length} chars`);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1007
1038
|
const text = chunk.text();
|
|
1008
1039
|
if (text) {
|
|
1009
1040
|
fullMessage += text;
|
|
@@ -1126,7 +1157,47 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1126
1157
|
console.log(`[Google] Processing final response with ${candidate.content.parts.length} parts`);
|
|
1127
1158
|
}
|
|
1128
1159
|
if (candidate?.content?.parts) {
|
|
1160
|
+
let collectedThoughts = "";
|
|
1161
|
+
let hasThoughts = false;
|
|
1162
|
+
// First pass: collect all thought parts from final response
|
|
1129
1163
|
for (const part of candidate.content.parts) {
|
|
1164
|
+
// Check for thinking/thought parts (Google's thinking API)
|
|
1165
|
+
if (part.thought && thinkingConfig) {
|
|
1166
|
+
hasThoughts = true;
|
|
1167
|
+
collectedThoughts += (part.text || "") + "\n";
|
|
1168
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1169
|
+
console.log(`[Google] Found thought part in final response: ${part.text?.length || 0} chars`);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
// Emit thinking events if we found thoughts
|
|
1174
|
+
if (hasThoughts && collectedThoughts) {
|
|
1175
|
+
if (!hasEmittedThinkingStart) {
|
|
1176
|
+
onEvent({ type: "reasoning_start", format: "markdown" });
|
|
1177
|
+
}
|
|
1178
|
+
// Combine with any streaming thoughts
|
|
1179
|
+
const finalThoughts = allThinkingContent + collectedThoughts;
|
|
1180
|
+
onEvent({
|
|
1181
|
+
type: "reasoning_end",
|
|
1182
|
+
fullContent: finalThoughts.trim(),
|
|
1183
|
+
});
|
|
1184
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
1185
|
+
console.log(`[Google] Emitted complete thinking: ${finalThoughts.length} chars`);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
else if (hasEmittedThinkingStart && allThinkingContent) {
|
|
1189
|
+
// Close thinking from streaming if no final thoughts
|
|
1190
|
+
onEvent({
|
|
1191
|
+
type: "reasoning_end",
|
|
1192
|
+
fullContent: allThinkingContent.trim(),
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
// Second pass: handle regular text parts
|
|
1196
|
+
for (const part of candidate.content.parts) {
|
|
1197
|
+
// Skip thought parts - we already handled them
|
|
1198
|
+
if (part.thought) {
|
|
1199
|
+
continue;
|
|
1200
|
+
}
|
|
1130
1201
|
// Check for any final text we might have missed
|
|
1131
1202
|
if (part.text) {
|
|
1132
1203
|
const finalText = part.text;
|