smoltalk 0.17.0 → 0.18.0
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/classes/message/BaseMessage.d.ts +5 -1
- package/dist/classes/message/BaseMessage.js +9 -3
- package/dist/classes/message/ToolMessage.d.ts +2 -3
- package/dist/classes/message/ToolMessage.js +7 -13
- package/dist/classes/message/index.d.ts +1 -1
- package/dist/clients/google.js +4 -1
- package/dist/embed/ollama.js +1 -1
- package/dist/model.js +21 -1
- package/package.json +1 -1
|
@@ -2,8 +2,12 @@ import { Content } from "@google/genai";
|
|
|
2
2
|
import { Message } from "ollama";
|
|
3
3
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
4
4
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
5
|
+
/** The text a provider sees for a message's content: a string as is, any
|
|
6
|
+
* other value as its JSON text, nothing for null. Exported so a consumer
|
|
7
|
+
* that compares saved messages can apply the same rule. */
|
|
8
|
+
export declare function contentToString(content: unknown): string;
|
|
5
9
|
export declare class BaseMessage {
|
|
6
|
-
protected contentToString(content:
|
|
10
|
+
protected contentToString(content: unknown): string;
|
|
7
11
|
}
|
|
8
12
|
export interface MessageClass {
|
|
9
13
|
get content(): string;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
/** The text a provider sees for a message's content: a string as is, any
|
|
2
|
+
* other value as its JSON text, nothing for null. Exported so a consumer
|
|
3
|
+
* that compares saved messages can apply the same rule. */
|
|
4
|
+
export function contentToString(content) {
|
|
5
|
+
if (content === null || content === undefined)
|
|
6
|
+
return "";
|
|
7
|
+
return typeof content === "string" ? content : JSON.stringify(content);
|
|
8
|
+
}
|
|
1
9
|
export class BaseMessage {
|
|
2
10
|
contentToString(content) {
|
|
3
|
-
|
|
4
|
-
return "";
|
|
5
|
-
return typeof content === "string" ? content : JSON.stringify(content);
|
|
11
|
+
return contentToString(content);
|
|
6
12
|
}
|
|
7
13
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BaseMessage, MessageClass } from "./BaseMessage.js";
|
|
3
|
-
import { TextPart } from "../../types.js";
|
|
4
3
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
5
4
|
import { Content } from "@google/genai";
|
|
6
5
|
import { Message } from "ollama";
|
|
@@ -21,11 +20,11 @@ export type ToolMessageJSON = {
|
|
|
21
20
|
};
|
|
22
21
|
export declare class ToolMessage extends BaseMessage implements MessageClass {
|
|
23
22
|
_role: "tool";
|
|
24
|
-
_content:
|
|
23
|
+
_content: unknown;
|
|
25
24
|
_tool_call_id: string;
|
|
26
25
|
_rawData?: any;
|
|
27
26
|
_name: string;
|
|
28
|
-
constructor(content:
|
|
27
|
+
constructor(content: unknown, options: {
|
|
29
28
|
tool_call_id: string;
|
|
30
29
|
rawData?: any;
|
|
31
30
|
name: string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BaseMessage } from "./BaseMessage.js";
|
|
3
|
-
import { TextPartSchema } from "../../types.js";
|
|
4
3
|
import { getLogger } from "../../util/logger.js";
|
|
5
4
|
export const ToolMessageJSONSchema = z.object({
|
|
6
5
|
role: z.literal("tool"),
|
|
@@ -12,6 +11,9 @@ export const ToolMessageJSONSchema = z.object({
|
|
|
12
11
|
});
|
|
13
12
|
export class ToolMessage extends BaseMessage {
|
|
14
13
|
_role = "tool";
|
|
14
|
+
// A tool result is whatever the tool returned: text, text parts, or a
|
|
15
|
+
// plain value such as an array of records. Every provider conversion
|
|
16
|
+
// reads it through the `content` getter, which turns any value into text.
|
|
15
17
|
_content;
|
|
16
18
|
_tool_call_id;
|
|
17
19
|
_rawData;
|
|
@@ -59,18 +61,10 @@ export class ToolMessage extends BaseMessage {
|
|
|
59
61
|
logger.debug("ToolMessage payload that failed to parse:", JSON.stringify(json, null, 2));
|
|
60
62
|
throw new Error("Failed to parse ToolMessage");
|
|
61
63
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
else if (typeof result.data.content === "string") {
|
|
68
|
-
// do nothing, it's already a string
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
getLogger().debug("ToolMessage content is neither a string nor an array of TextParts. Converting to string using JSON.stringify.");
|
|
72
|
-
result.data.content = JSON.stringify(result.data.content);
|
|
73
|
-
}
|
|
64
|
+
// Content is kept exactly as saved. Rebuilding a non-text value as its
|
|
65
|
+
// JSON text here would make a saved-and-rebuilt thread differ from one
|
|
66
|
+
// that was never saved, while what a provider sees is the same either
|
|
67
|
+
// way (the `content` getter stringifies both).
|
|
74
68
|
return new ToolMessage(result.data.content, {
|
|
75
69
|
tool_call_id: result.data.tool_call_id,
|
|
76
70
|
name: result.data.name,
|
|
@@ -51,7 +51,7 @@ export declare function systemMessage(content: string | Array<TextPart>, options
|
|
|
51
51
|
name?: string;
|
|
52
52
|
rawData?: any;
|
|
53
53
|
}): SystemMessage;
|
|
54
|
-
export declare function toolMessage(content:
|
|
54
|
+
export declare function toolMessage(content: unknown, options: {
|
|
55
55
|
tool_call_id: string;
|
|
56
56
|
rawData?: any;
|
|
57
57
|
name: string;
|
package/dist/clients/google.js
CHANGED
|
@@ -223,9 +223,12 @@ export class SmolGoogle extends BaseClient {
|
|
|
223
223
|
let cost;
|
|
224
224
|
if (usageMetadata) {
|
|
225
225
|
const cached = usageMetadata.cachedContentTokenCount ?? 0;
|
|
226
|
+
// Thinking is reported in thoughtsTokenCount, separate from
|
|
227
|
+
// candidatesTokenCount, and billed at the output rate.
|
|
228
|
+
const thoughts = usageMetadata.thoughtsTokenCount ?? 0;
|
|
226
229
|
usage = {
|
|
227
230
|
inputTokens: Math.max(0, (usageMetadata.promptTokenCount || 0) - cached),
|
|
228
|
-
outputTokens: usageMetadata.candidatesTokenCount || 0,
|
|
231
|
+
outputTokens: (usageMetadata.candidatesTokenCount || 0) + thoughts,
|
|
229
232
|
totalTokens: usageMetadata.totalTokenCount,
|
|
230
233
|
};
|
|
231
234
|
if (cached > 0) {
|
package/dist/embed/ollama.js
CHANGED
package/dist/model.js
CHANGED
|
@@ -43,7 +43,27 @@ export class Model {
|
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
45
45
|
// BaseModel token-rate fields, read structurally across the model union.
|
|
46
|
-
const
|
|
46
|
+
const baseRates = model;
|
|
47
|
+
const rates = { ...baseRates };
|
|
48
|
+
// A prompt over the long-context threshold is billed at the long-context
|
|
49
|
+
// rates for the whole request, input and output alike. The prompt size
|
|
50
|
+
// counts every input bucket, cached ones included.
|
|
51
|
+
const promptTokens = usage.inputTokens +
|
|
52
|
+
(usage.cachedInputTokens ?? 0) +
|
|
53
|
+
(usage.cacheCreationInputTokens ?? 0) +
|
|
54
|
+
(usage.inputAudioTokens ?? 0);
|
|
55
|
+
const longContext = baseRates.longContext;
|
|
56
|
+
if (longContext !== undefined && promptTokens > longContext.thresholdTokens) {
|
|
57
|
+
if (longContext.inputTokenCost !== undefined) {
|
|
58
|
+
rates.inputTokenCost = longContext.inputTokenCost;
|
|
59
|
+
}
|
|
60
|
+
if (longContext.outputTokenCost !== undefined) {
|
|
61
|
+
rates.outputTokenCost = longContext.outputTokenCost;
|
|
62
|
+
}
|
|
63
|
+
if (longContext.cachedInputTokenCost !== undefined) {
|
|
64
|
+
rates.cachedInputTokenCost = longContext.cachedInputTokenCost;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
47
67
|
// Price only models that carry at least one token rate; those without
|
|
48
68
|
// (per-minute STT, per-char TTS) return null so their dedicated helpers apply.
|
|
49
69
|
if (rates.inputTokenCost === undefined &&
|