smoltalk 0.0.61 → 0.0.63

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.
@@ -45,8 +45,14 @@ export class ToolCall {
45
45
  };
46
46
  }
47
47
  static fromJSON(json) {
48
- const parsed = ToolCallJSONSchema.parse(json);
49
- return new ToolCall(parsed.id, parsed.name, parsed.arguments);
48
+ const result = ToolCallJSONSchema.safeParse(json);
49
+ if (!result.success) {
50
+ console.error("Failed to parse ToolCall");
51
+ console.error(JSON.stringify(json, null, 2));
52
+ console.error(z.prettifyError(result.error));
53
+ throw new Error("Failed to parse ToolCall");
54
+ }
55
+ return new ToolCall(result.data.id, result.data.name, result.data.arguments);
50
56
  }
51
57
  toOpenAI() {
52
58
  return {
@@ -84,16 +84,22 @@ export class AssistantMessage extends BaseMessage {
84
84
  };
85
85
  }
86
86
  static fromJSON(json) {
87
- const parsed = AssistantMessageJSONSchema.parse(json);
88
- return new AssistantMessage(parsed.content, {
89
- name: parsed.name,
90
- audio: parsed.audio,
91
- refusal: parsed.refusal,
92
- toolCalls: parsed.toolCalls?.map((tc) => ToolCall.fromJSON(tc)),
93
- thinkingBlocks: parsed.thinkingBlocks,
94
- rawData: parsed.rawData,
95
- usage: parsed.usage,
96
- cost: parsed.cost,
87
+ const result = AssistantMessageJSONSchema.safeParse(json);
88
+ if (!result.success) {
89
+ console.error("Failed to parse AssistantMessage");
90
+ console.error(JSON.stringify(json, null, 2));
91
+ console.error(z.prettifyError(result.error));
92
+ throw new Error("Failed to parse AssistantMessage");
93
+ }
94
+ return new AssistantMessage(result.data.content, {
95
+ name: result.data.name,
96
+ audio: result.data.audio,
97
+ refusal: result.data.refusal,
98
+ toolCalls: result.data.toolCalls?.map((tc) => ToolCall.fromJSON(tc)),
99
+ thinkingBlocks: result.data.thinkingBlocks,
100
+ rawData: result.data.rawData,
101
+ usage: result.data.usage,
102
+ cost: result.data.cost,
97
103
  });
98
104
  }
99
105
  toOpenAIMessage() {
@@ -41,10 +41,16 @@ export class DeveloperMessage extends BaseMessage {
41
41
  };
42
42
  }
43
43
  static fromJSON(json) {
44
- const parsed = DeveloperMessageJSONSchema.parse(json);
45
- return new DeveloperMessage(parsed.content, {
46
- name: parsed.name,
47
- rawData: parsed.rawData,
44
+ const result = DeveloperMessageJSONSchema.safeParse(json);
45
+ if (!result.success) {
46
+ console.error("Failed to parse DeveloperMessage");
47
+ console.error(JSON.stringify(json, null, 2));
48
+ console.error(z.prettifyError(result.error));
49
+ throw new Error("Failed to parse DeveloperMessage");
50
+ }
51
+ return new DeveloperMessage(result.data.content, {
52
+ name: result.data.name,
53
+ rawData: result.data.rawData,
48
54
  });
49
55
  }
50
56
  toOpenAIMessage() {
@@ -41,10 +41,16 @@ export class SystemMessage extends BaseMessage {
41
41
  };
42
42
  }
43
43
  static fromJSON(json) {
44
- const parsed = SystemMessageJSONSchema.parse(json);
45
- return new SystemMessage(parsed.content, {
46
- name: parsed.name,
47
- rawData: parsed.rawData,
44
+ const result = SystemMessageJSONSchema.safeParse(json);
45
+ if (!result.success) {
46
+ console.error("Failed to parse SystemMessage");
47
+ console.error(JSON.stringify(json, null, 2));
48
+ console.error(z.prettifyError(result.error));
49
+ throw new Error("Failed to parse SystemMessage");
50
+ }
51
+ return new SystemMessage(result.data.content, {
52
+ name: result.data.name,
53
+ rawData: result.data.rawData,
48
54
  });
49
55
  }
50
56
  toOpenAIMessage() {
@@ -48,11 +48,17 @@ export class ToolMessage extends BaseMessage {
48
48
  };
49
49
  }
50
50
  static fromJSON(json) {
51
- const parsed = ToolMessageJSONSchema.parse(json);
52
- return new ToolMessage(parsed.content, {
53
- tool_call_id: parsed.tool_call_id,
54
- name: parsed.name,
55
- rawData: parsed.rawData,
51
+ const result = ToolMessageJSONSchema.safeParse(json);
52
+ if (!result.success) {
53
+ console.error("Failed to parse ToolMessage");
54
+ console.error(JSON.stringify(json, null, 2));
55
+ console.error(z.prettifyError(result.error));
56
+ throw new Error("Failed to parse ToolMessage");
57
+ }
58
+ return new ToolMessage(result.data.content, {
59
+ tool_call_id: result.data.tool_call_id,
60
+ name: result.data.name,
61
+ rawData: result.data.rawData,
56
62
  });
57
63
  }
58
64
  toOpenAIMessage() {
@@ -40,10 +40,16 @@ export class UserMessage extends BaseMessage {
40
40
  };
41
41
  }
42
42
  static fromJSON(json) {
43
- const parsed = UserMessageJSONSchema.parse(json);
44
- return new UserMessage(parsed.content, {
45
- name: parsed.name,
46
- rawData: parsed.rawData,
43
+ const result = UserMessageJSONSchema.safeParse(json);
44
+ if (!result.success) {
45
+ console.error("Failed to parse UserMessage");
46
+ console.error(JSON.stringify(json, null, 2));
47
+ console.error(z.prettifyError(result.error));
48
+ throw new Error("Failed to parse UserMessage");
49
+ }
50
+ return new UserMessage(result.data.content, {
51
+ name: result.data.name,
52
+ rawData: result.data.rawData,
47
53
  });
48
54
  }
49
55
  toOpenAIMessage() {
@@ -1,4 +1,4 @@
1
- import { userMessage, assistantMessage, } from "../classes/message/index.js";
1
+ import { userMessage, assistantMessage } from "../classes/message/index.js";
2
2
  import { latencyTracker } from "../latencyTracker.js";
3
3
  import { getLogger } from "../util/logger.js";
4
4
  import { SmolStructuredOutputError } from "../smolError.js";
@@ -149,6 +149,10 @@ export class BaseClient {
149
149
  return rawValue;
150
150
  }
151
151
  }
152
+ // 1.5 Look for { type: "object", properties: { response: { ... } } } pattern
153
+ if (rawValue && typeof rawValue === "object" && rawValue.type === "object" && rawValue.properties) {
154
+ return this.extractResponse(promptConfig, rawValue.properties, schema, depth + 1);
155
+ }
152
156
  // 2. String → try JSON.parse, then recurse
153
157
  if (typeof rawValue === "string") {
154
158
  const stripped = rawValue
@@ -109,7 +109,7 @@ export class SmolGoogle extends BaseClient {
109
109
  this.statelogClient?.debug("Detected both tool calls and structured response in call to Google Gemini. Making separate request to Google Gemini for tool calls.", {
110
110
  contents: request.contents,
111
111
  tools: config.tools,
112
- responseFormat: config.responseFormat,
112
+ responseFormat: config.responseFormat?.toJSONSchema(),
113
113
  });
114
114
  const toolRequest = {
115
115
  ...request,
package/dist/functions.js CHANGED
@@ -1,6 +1,8 @@
1
+ import { BaseMessage, messageFromJSON, } from "./classes/message/index.js";
1
2
  import { Model } from "./model.js";
2
3
  import { BaseStrategy } from "./strategies/baseStrategy.js";
3
4
  import { fromJSON } from "./strategies/index.js";
5
+ import { getLogger } from "./util/logger.js";
4
6
  function getStrategy(model) {
5
7
  if (model instanceof BaseStrategy)
6
8
  return model;
@@ -28,15 +30,27 @@ export function splitConfig(config) {
28
30
  promptConfig,
29
31
  };
30
32
  }
33
+ function fixMessagesIfNecessary(messages) {
34
+ if (messages && messages.length > 0) {
35
+ if (!(messages[0] instanceof BaseMessage)) {
36
+ getLogger().warn("Messages are not instances of smoltalk.BaseMessage");
37
+ return messages.map((m) => messageFromJSON(m));
38
+ }
39
+ }
40
+ return messages;
41
+ }
31
42
  export function text(config) {
32
43
  const strategy = getStrategy(config.model);
44
+ config.messages = fixMessagesIfNecessary(config.messages);
33
45
  return strategy.text(config);
34
46
  }
35
47
  export function textSync(config) {
36
48
  const strategy = getStrategy(config.model);
49
+ config.messages = fixMessagesIfNecessary(config.messages);
37
50
  return strategy.textSync(config);
38
51
  }
39
52
  export function textStream(config) {
40
53
  const strategy = getStrategy(config.model);
54
+ config.messages = fixMessagesIfNecessary(config.messages);
41
55
  return strategy.textStream(config);
42
56
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { SmolContentPolicyError, SmolContextWindowExceededError, SmolStructuredOutputError, SmolTimeoutError, } from "../smolError.js";
2
3
  import { success, } from "../types.js";
3
4
  import { BaseStrategy } from "./baseStrategy.js";
@@ -108,8 +109,14 @@ export class FallbackStrategy extends BaseStrategy {
108
109
  };
109
110
  }
110
111
  static fromJSON(json) {
111
- const parsed = FallbackStrategyJSONSchema.parse(json);
112
- const primaryStrategy = fromJSON(parsed.params.primaryStrategy);
113
- return new FallbackStrategy(primaryStrategy, parsed.params.config);
112
+ const result = FallbackStrategyJSONSchema.safeParse(json);
113
+ if (!result.success) {
114
+ console.error("Failed to parse FallbackStrategy");
115
+ console.error(JSON.stringify(json, null, 2));
116
+ console.error(z.prettifyError(result.error));
117
+ throw new Error("Failed to parse FallbackStrategy");
118
+ }
119
+ const primaryStrategy = fromJSON(result.data.params.primaryStrategy);
120
+ return new FallbackStrategy(primaryStrategy, result.data.params.config);
114
121
  }
115
122
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { latencyTracker } from "../latencyTracker.js";
2
3
  import { getLogger } from "../util/logger.js";
3
4
  import { Model } from "../model.js";
@@ -94,8 +95,14 @@ export class FastestStrategy extends BaseStrategy {
94
95
  };
95
96
  }
96
97
  static fromJSON(json) {
97
- const parsed = FastestStrategyJSONSchema.parse(json);
98
- const models = parsed.params.models;
98
+ const result = FastestStrategyJSONSchema.safeParse(json);
99
+ if (!result.success) {
100
+ console.error("Failed to parse FastestStrategy");
101
+ console.error(JSON.stringify(json, null, 2));
102
+ console.error(z.prettifyError(result.error));
103
+ throw new Error("Failed to parse FastestStrategy");
104
+ }
105
+ const models = result.data.params.models;
99
106
  return new FastestStrategy(models);
100
107
  }
101
108
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { getLogger } from "../util/logger.js";
2
3
  import { BaseStrategy } from "./baseStrategy.js";
3
4
  import { fromJSON, IDStrategy } from "./index.js";
@@ -58,8 +59,14 @@ export class RaceStrategy extends BaseStrategy {
58
59
  };
59
60
  }
60
61
  static fromJSON(json) {
61
- const parsed = RaceStrategyJSONSchema.parse(json);
62
- const strategies = parsed.params.strategies.map((s) => fromJSON(s));
62
+ const result = RaceStrategyJSONSchema.safeParse(json);
63
+ if (!result.success) {
64
+ console.error("Failed to parse RaceStrategy");
65
+ console.error(JSON.stringify(json, null, 2));
66
+ console.error(z.prettifyError(result.error));
67
+ throw new Error("Failed to parse RaceStrategy");
68
+ }
69
+ const strategies = result.data.params.strategies.map((s) => fromJSON(s));
63
70
  return new RaceStrategy(strategies);
64
71
  }
65
72
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { BaseStrategy } from "./baseStrategy.js";
2
3
  import { IDStrategy } from "./idStrategy.js";
3
4
  import { fromJSON } from "./index.js";
@@ -40,8 +41,14 @@ export class RandomStrategy extends BaseStrategy {
40
41
  };
41
42
  }
42
43
  static fromJSON(json) {
43
- const parsed = RandomStrategyJSONSchema.parse(json);
44
- const strategies = parsed.params.strategies.map((s) => fromJSON(s));
44
+ const result = RandomStrategyJSONSchema.safeParse(json);
45
+ if (!result.success) {
46
+ console.error("Failed to parse RandomStrategy");
47
+ console.error(JSON.stringify(json, null, 2));
48
+ console.error(z.prettifyError(result.error));
49
+ throw new Error("Failed to parse RandomStrategy");
50
+ }
51
+ const strategies = result.data.params.strategies.map((s) => fromJSON(s));
45
52
  return new RandomStrategy(...strategies);
46
53
  }
47
54
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { SmolTimeoutError } from "../smolError.js";
2
3
  import { BaseStrategy } from "./baseStrategy.js";
3
4
  import { IDStrategy } from "./idStrategy.js";
@@ -51,8 +52,14 @@ export class TimeoutStrategy extends BaseStrategy {
51
52
  };
52
53
  }
53
54
  static fromJSON(json) {
54
- const parsed = TimeoutStrategyJSONSchema.parse(json);
55
- const strategy = fromJSON(parsed.params.strategy);
56
- return new TimeoutStrategy(strategy, parsed.params.timeoutMs);
55
+ const result = TimeoutStrategyJSONSchema.safeParse(json);
56
+ if (!result.success) {
57
+ console.error("Failed to parse TimeoutStrategy");
58
+ console.error(JSON.stringify(json, null, 2));
59
+ console.error(z.prettifyError(result.error));
60
+ throw new Error("Failed to parse TimeoutStrategy");
61
+ }
62
+ const strategy = fromJSON(result.data.params.strategy);
63
+ return new TimeoutStrategy(strategy, result.data.params.timeoutMs);
57
64
  }
58
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoltalk",
3
- "version": "0.0.61",
3
+ "version": "0.0.63",
4
4
  "description": "A common interface for LLM APIs",
5
5
  "homepage": "https://github.com/egonSchiele/smoltalk",
6
6
  "scripts": {