graphlit-client 1.0.20250924004 → 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 +68 -4
- 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,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 {
|
|
@@ -1011,6 +1018,23 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1011
1018
|
const chat = model.startChat({ history });
|
|
1012
1019
|
const result = await chat.sendMessageStream(prompt);
|
|
1013
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
|
+
}
|
|
1014
1038
|
const text = chunk.text();
|
|
1015
1039
|
if (text) {
|
|
1016
1040
|
fullMessage += text;
|
|
@@ -1133,7 +1157,47 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
1133
1157
|
console.log(`[Google] Processing final response with ${candidate.content.parts.length} parts`);
|
|
1134
1158
|
}
|
|
1135
1159
|
if (candidate?.content?.parts) {
|
|
1160
|
+
let collectedThoughts = "";
|
|
1161
|
+
let hasThoughts = false;
|
|
1162
|
+
// First pass: collect all thought parts from final response
|
|
1136
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
|
+
}
|
|
1137
1201
|
// Check for any final text we might have missed
|
|
1138
1202
|
if (part.text) {
|
|
1139
1203
|
const finalText = part.text;
|