smoltalk 0.0.50 → 0.0.52

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.
@@ -157,6 +157,7 @@ export class BaseClient {
157
157
  this.statelogClient?.debug("Request aborted or timed out", {
158
158
  reason: message,
159
159
  timeBudgetMs,
160
+ promptConfig,
160
161
  });
161
162
  return { success: false, error: message };
162
163
  }
@@ -270,6 +271,11 @@ export class BaseClient {
270
271
  async textWithRetry(promptConfig, retries) {
271
272
  const result = await this._textSync(promptConfig);
272
273
  if (result.success) {
274
+ // If there are tool calls, return them immediately — format validation
275
+ // only applies to the final text output, not intermediate tool-call turns.
276
+ if (result.value.toolCalls.length > 0) {
277
+ return result;
278
+ }
273
279
  if (!promptConfig.responseFormat ||
274
280
  !promptConfig.responseFormatOptions?.strict) {
275
281
  return result;
@@ -380,6 +386,7 @@ export class BaseClient {
380
386
  this.statelogClient?.debug("Streaming request aborted or timed out", {
381
387
  reason: message,
382
388
  timeBudgetMs,
389
+ newPromptConfig,
383
390
  });
384
391
  yield { type: "timeout", error: message };
385
392
  }
@@ -174,9 +174,12 @@ export class SmolGoogle extends BaseClient {
174
174
  const result = await this.client.models.generateContent(request);
175
175
  this.logger.debug("Response from Google Gemini:", JSON.stringify(result, null, 2));
176
176
  this.statelogClient?.promptResponse(result);
177
- const output = result.text || null;
178
177
  const toolCalls = [];
179
178
  const thinkingBlocks = [];
179
+ let textContent = "";
180
+ // Extract text, tool calls, and thinking blocks manually from parts
181
+ // instead of using result.text, which logs a noisy console.warn when
182
+ // non-text parts (like functionCall) are present in the response.
180
183
  result.candidates?.forEach((candidate) => {
181
184
  if (candidate.content && candidate.content.parts) {
182
185
  candidate.content.parts.forEach((part) => {
@@ -184,16 +187,20 @@ export class SmolGoogle extends BaseClient {
184
187
  const functionCall = part.functionCall;
185
188
  toolCalls.push(new ToolCall("", functionCall.name, functionCall.args));
186
189
  }
187
- // Capture thought parts (thought: true indicates a thinking part)
188
- if (part.thoughtSignature) {
190
+ else if (part.thoughtSignature) {
191
+ // Capture thought parts (thought: true indicates a thinking part)
189
192
  thinkingBlocks.push({
190
193
  text: part.text || "",
191
194
  signature: part.thoughtSignature,
192
195
  });
193
196
  }
197
+ else if (typeof part.text === "string" && !part.thought) {
198
+ textContent += part.text;
199
+ }
194
200
  });
195
201
  }
196
202
  });
203
+ const output = textContent || null;
197
204
  // Extract usage and calculate cost
198
205
  const { usage, cost } = this.calculateUsageAndCost(result.usageMetadata);
199
206
  // Return the response, updating the chat history
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoltalk",
3
- "version": "0.0.50",
3
+ "version": "0.0.52",
4
4
  "description": "A common interface for LLM APIs",
5
5
  "homepage": "https://github.com/egonSchiele/smoltalk",
6
6
  "scripts": {