smoltalk 0.0.30 → 0.0.32
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/AssistantMessage.d.ts +12 -0
- package/dist/classes/message/AssistantMessage.js +24 -0
- package/dist/classes/message/DeveloperMessage.d.ts +1 -0
- package/dist/classes/message/DeveloperMessage.js +5 -0
- package/dist/classes/message/SystemMessage.d.ts +1 -0
- package/dist/classes/message/SystemMessage.js +5 -0
- package/dist/classes/message/ToolMessage.d.ts +8 -0
- package/dist/classes/message/ToolMessage.js +7 -0
- package/dist/classes/message/UserMessage.d.ts +4 -0
- package/dist/classes/message/UserMessage.js +3 -0
- package/dist/client.d.ts +3 -1
- package/dist/client.js +11 -1
- package/dist/clients/anthropic.d.ts +16 -0
- package/dist/clients/anthropic.js +188 -0
- package/dist/clients/baseClient.js +6 -0
- package/dist/functions.js +2 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models.d.ts +62 -4
- package/dist/models.js +34 -2
- package/dist/types.d.ts +1 -0
- package/dist/util/tool.d.ts +12 -0
- package/dist/util/tool.js +24 -0
- package/package.json +2 -1
|
@@ -42,4 +42,16 @@ export declare class AssistantMessage extends BaseMessage implements MessageClas
|
|
|
42
42
|
toOpenAIResponseInputItem(): ResponseInputItem | ResponseInputItem[];
|
|
43
43
|
toGoogleMessage(): Content;
|
|
44
44
|
toOllamaMessage(): Message;
|
|
45
|
+
toAnthropicMessage(): {
|
|
46
|
+
role: "assistant";
|
|
47
|
+
content: string | Array<{
|
|
48
|
+
type: "text";
|
|
49
|
+
text: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: "tool_use";
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
input: Record<string, any>;
|
|
55
|
+
}>;
|
|
56
|
+
};
|
|
45
57
|
}
|
|
@@ -112,4 +112,28 @@ export class AssistantMessage extends BaseMessage {
|
|
|
112
112
|
tool_calls: this.toolCalls?.map((tc) => tc.toOpenAI()),
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
+
toAnthropicMessage() {
|
|
116
|
+
const hasText = this._content !== null &&
|
|
117
|
+
this._content !== undefined &&
|
|
118
|
+
(typeof this._content === "string"
|
|
119
|
+
? this._content.length > 0
|
|
120
|
+
: this._content.length > 0);
|
|
121
|
+
const hasToolCalls = this._toolCalls && this._toolCalls.length > 0;
|
|
122
|
+
if (!hasToolCalls) {
|
|
123
|
+
return { role: "assistant", content: this.content };
|
|
124
|
+
}
|
|
125
|
+
const blocks = [];
|
|
126
|
+
if (hasText) {
|
|
127
|
+
const text = typeof this._content === "string"
|
|
128
|
+
? this._content
|
|
129
|
+
: this._content.map((p) => p.text).join("");
|
|
130
|
+
if (text) {
|
|
131
|
+
blocks.push({ type: "text", text });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
for (const tc of this._toolCalls) {
|
|
135
|
+
blocks.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.arguments });
|
|
136
|
+
}
|
|
137
|
+
return { role: "assistant", content: blocks };
|
|
138
|
+
}
|
|
115
139
|
}
|
|
@@ -56,4 +56,9 @@ export class DeveloperMessage extends BaseMessage {
|
|
|
56
56
|
toOllamaMessage() {
|
|
57
57
|
return { role: this.role, content: this.content };
|
|
58
58
|
}
|
|
59
|
+
// Developer messages are treated like system messages in Anthropic's API.
|
|
60
|
+
// Returns null to signal they should be collected into the `system` param.
|
|
61
|
+
toAnthropicMessage() {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
59
64
|
}
|
|
@@ -56,4 +56,9 @@ export class SystemMessage extends BaseMessage {
|
|
|
56
56
|
toOllamaMessage() {
|
|
57
57
|
return { role: this.role, content: this.content };
|
|
58
58
|
}
|
|
59
|
+
// System messages are passed as the top-level `system` param in Anthropic's API,
|
|
60
|
+
// not as entries in the messages array. Returns null to signal this.
|
|
61
|
+
toAnthropicMessage() {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
59
64
|
}
|
|
@@ -33,4 +33,12 @@ export declare class ToolMessage extends BaseMessage implements MessageClass {
|
|
|
33
33
|
toOpenAIResponseInputItem(): ResponseInputItem;
|
|
34
34
|
toGoogleMessage(): Content;
|
|
35
35
|
toOllamaMessage(): Message;
|
|
36
|
+
toAnthropicMessage(): {
|
|
37
|
+
role: "user";
|
|
38
|
+
content: Array<{
|
|
39
|
+
type: "tool_result";
|
|
40
|
+
tool_use_id: string;
|
|
41
|
+
content: string;
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
36
44
|
}
|
|
@@ -83,4 +83,11 @@ export class ToolMessage extends BaseMessage {
|
|
|
83
83
|
content: this.content,
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
|
+
// In Anthropic's API, tool results are user-role messages containing tool_result blocks.
|
|
87
|
+
toAnthropicMessage() {
|
|
88
|
+
return {
|
|
89
|
+
role: "user",
|
|
90
|
+
content: [{ type: "tool_result", tool_use_id: this.tool_call_id, content: this.content }],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
86
93
|
}
|
|
@@ -28,4 +28,8 @@ export declare class UserMessage extends BaseMessage implements MessageClass {
|
|
|
28
28
|
toOpenAIResponseInputItem(): ResponseInputItem;
|
|
29
29
|
toGoogleMessage(): Content;
|
|
30
30
|
toOllamaMessage(): Message;
|
|
31
|
+
toAnthropicMessage(): {
|
|
32
|
+
role: "user";
|
|
33
|
+
content: string;
|
|
34
|
+
};
|
|
31
35
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
export * from "./clients/anthropic.js";
|
|
1
2
|
export * from "./clients/google.js";
|
|
2
3
|
export * from "./clients/openai.js";
|
|
3
4
|
export * from "./clients/openaiResponses.js";
|
|
5
|
+
import { SmolAnthropic } from "./clients/anthropic.js";
|
|
4
6
|
import { SmolGoogle } from "./clients/google.js";
|
|
5
7
|
import { SmolOpenAi } from "./clients/openai.js";
|
|
6
8
|
import { SmolOpenAiResponses } from "./clients/openaiResponses.js";
|
|
7
9
|
import { SmolConfig } from "./types.js";
|
|
8
10
|
import { SmolOllama } from "./clients/ollama.js";
|
|
9
|
-
export declare function getClient(config: SmolConfig): SmolGoogle | SmolOpenAi | SmolOpenAiResponses | SmolOllama;
|
|
11
|
+
export declare function getClient(config: SmolConfig): SmolAnthropic | SmolGoogle | SmolOpenAi | SmolOpenAiResponses | SmolOllama;
|
package/dist/client.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
export * from "./clients/anthropic.js";
|
|
1
2
|
export * from "./clients/google.js";
|
|
2
3
|
export * from "./clients/openai.js";
|
|
3
4
|
export * from "./clients/openaiResponses.js";
|
|
5
|
+
import { SmolAnthropic } from "./clients/anthropic.js";
|
|
4
6
|
import { SmolGoogle } from "./clients/google.js";
|
|
5
7
|
import { SmolOpenAi } from "./clients/openai.js";
|
|
6
8
|
import { SmolOpenAiResponses } from "./clients/openaiResponses.js";
|
|
7
|
-
import { getModel, isModelConfig, isTextModel, pickModel } from "./models.js";
|
|
9
|
+
import { getModel, isModelConfig, isTextModel, pickModel, } from "./models.js";
|
|
8
10
|
import { SmolError } from "./smolError.js";
|
|
9
11
|
import { getLogger } from "./logger.js";
|
|
10
12
|
import { SmolOllama } from "./clients/ollama.js";
|
|
@@ -28,6 +30,14 @@ export function getClient(config) {
|
|
|
28
30
|
}
|
|
29
31
|
const clientConfig = { ...config, model: modelName };
|
|
30
32
|
switch (provider) {
|
|
33
|
+
case "anthropic":
|
|
34
|
+
if (!config.anthropicApiKey) {
|
|
35
|
+
throw new SmolError("No Anthropic API key provided. Please provide an Anthropic API key in the config using anthropicApiKey.");
|
|
36
|
+
}
|
|
37
|
+
return new SmolAnthropic({
|
|
38
|
+
...clientConfig,
|
|
39
|
+
anthropicApiKey: config.anthropicApiKey,
|
|
40
|
+
});
|
|
31
41
|
case "openai":
|
|
32
42
|
if (!config.openAiApiKey) {
|
|
33
43
|
throw new SmolError("No OpenAI API key provided. Please provide an OpenAI API key in the config using openAiApiKey.");
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseClientConfig, PromptConfig, PromptResult, Result, SmolClient, StreamChunk } from "../types.js";
|
|
2
|
+
import { BaseClient } from "./baseClient.js";
|
|
3
|
+
export type SmolAnthropicConfig = BaseClientConfig & {
|
|
4
|
+
anthropicApiKey: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class SmolAnthropic extends BaseClient implements SmolClient {
|
|
7
|
+
private client;
|
|
8
|
+
private logger;
|
|
9
|
+
private model;
|
|
10
|
+
constructor(config: SmolAnthropicConfig);
|
|
11
|
+
getModel(): string;
|
|
12
|
+
private calculateUsageAndCost;
|
|
13
|
+
private buildRequest;
|
|
14
|
+
_textSync(config: PromptConfig): Promise<Result<PromptResult>>;
|
|
15
|
+
_textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import { ToolCall } from "../classes/ToolCall.js";
|
|
3
|
+
import { SystemMessage, DeveloperMessage, } from "../classes/message/index.js";
|
|
4
|
+
import { getLogger } from "../logger.js";
|
|
5
|
+
import { success, } from "../types.js";
|
|
6
|
+
import { zodToAnthropicTool } from "../util/tool.js";
|
|
7
|
+
import { BaseClient } from "./baseClient.js";
|
|
8
|
+
import { calculateCost } from "../models.js";
|
|
9
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
10
|
+
export class SmolAnthropic extends BaseClient {
|
|
11
|
+
client;
|
|
12
|
+
logger;
|
|
13
|
+
model;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
super(config);
|
|
16
|
+
this.client = new Anthropic({ apiKey: config.anthropicApiKey });
|
|
17
|
+
this.logger = getLogger();
|
|
18
|
+
this.model = config.model;
|
|
19
|
+
}
|
|
20
|
+
getModel() {
|
|
21
|
+
return this.model;
|
|
22
|
+
}
|
|
23
|
+
calculateUsageAndCost(usageData) {
|
|
24
|
+
const usage = {
|
|
25
|
+
inputTokens: usageData.input_tokens,
|
|
26
|
+
outputTokens: usageData.output_tokens,
|
|
27
|
+
totalTokens: usageData.input_tokens + usageData.output_tokens,
|
|
28
|
+
};
|
|
29
|
+
const cost = calculateCost(this.model, usage) ?? undefined;
|
|
30
|
+
return { usage, cost };
|
|
31
|
+
}
|
|
32
|
+
buildRequest(config) {
|
|
33
|
+
// Split system/developer messages out into the top-level `system` param
|
|
34
|
+
const systemParts = config.messages
|
|
35
|
+
.filter((m) => m instanceof SystemMessage || m instanceof DeveloperMessage)
|
|
36
|
+
.map((m) => m.content);
|
|
37
|
+
const system = systemParts.length > 0 ? systemParts.join("\n") : undefined;
|
|
38
|
+
// Convert remaining messages, merging consecutive tool_result user messages
|
|
39
|
+
const anthropicMessages = [];
|
|
40
|
+
for (const msg of config.messages) {
|
|
41
|
+
if (msg instanceof SystemMessage || msg instanceof DeveloperMessage) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const converted = msg.toAnthropicMessage();
|
|
45
|
+
if (converted === null)
|
|
46
|
+
continue;
|
|
47
|
+
// Merge consecutive tool_result user messages into one (required by Anthropic)
|
|
48
|
+
if (converted.role === "user" &&
|
|
49
|
+
Array.isArray(converted.content) &&
|
|
50
|
+
converted.content.every((c) => c.type === "tool_result")) {
|
|
51
|
+
const last = anthropicMessages[anthropicMessages.length - 1];
|
|
52
|
+
if (last &&
|
|
53
|
+
last.role === "user" &&
|
|
54
|
+
Array.isArray(last.content) &&
|
|
55
|
+
last.content.every((c) => c.type === "tool_result")) {
|
|
56
|
+
last.content.push(...converted.content);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
anthropicMessages.push(converted);
|
|
61
|
+
}
|
|
62
|
+
const tools = config.tools && config.tools.length > 0
|
|
63
|
+
? config.tools.map((tool) => zodToAnthropicTool(tool.name, tool.schema, {
|
|
64
|
+
description: tool.description,
|
|
65
|
+
}))
|
|
66
|
+
: undefined;
|
|
67
|
+
return { system, messages: anthropicMessages, tools };
|
|
68
|
+
}
|
|
69
|
+
async _textSync(config) {
|
|
70
|
+
const { system, messages, tools } = this.buildRequest(config);
|
|
71
|
+
this.logger.debug("Sending request to Anthropic:", {
|
|
72
|
+
model: this.model,
|
|
73
|
+
max_tokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
74
|
+
messages,
|
|
75
|
+
system,
|
|
76
|
+
tools,
|
|
77
|
+
});
|
|
78
|
+
const response = await this.client.messages.create({
|
|
79
|
+
model: this.model,
|
|
80
|
+
max_tokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
81
|
+
messages,
|
|
82
|
+
...(system && { system }),
|
|
83
|
+
...(tools && { tools }),
|
|
84
|
+
...(config.temperature !== undefined && {
|
|
85
|
+
temperature: config.temperature,
|
|
86
|
+
}),
|
|
87
|
+
...(config.rawAttributes || {}),
|
|
88
|
+
stream: false,
|
|
89
|
+
});
|
|
90
|
+
this.logger.debug("Response from Anthropic:", response);
|
|
91
|
+
let output = null;
|
|
92
|
+
const toolCalls = [];
|
|
93
|
+
for (const block of response.content) {
|
|
94
|
+
if (block.type === "text") {
|
|
95
|
+
output = (output ?? "") + block.text;
|
|
96
|
+
}
|
|
97
|
+
else if (block.type === "tool_use") {
|
|
98
|
+
toolCalls.push(new ToolCall(block.id, block.name, block.input));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const { usage, cost } = this.calculateUsageAndCost(response.usage);
|
|
102
|
+
return success({
|
|
103
|
+
output,
|
|
104
|
+
toolCalls,
|
|
105
|
+
usage,
|
|
106
|
+
cost,
|
|
107
|
+
model: this.model,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async *_textStream(config) {
|
|
111
|
+
const { system, messages, tools } = this.buildRequest(config);
|
|
112
|
+
this.logger.debug("Sending streaming request to Anthropic:", {
|
|
113
|
+
model: this.model,
|
|
114
|
+
max_tokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
115
|
+
messages,
|
|
116
|
+
system,
|
|
117
|
+
tools,
|
|
118
|
+
});
|
|
119
|
+
const stream = await this.client.messages.create({
|
|
120
|
+
model: this.model,
|
|
121
|
+
max_tokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
122
|
+
messages,
|
|
123
|
+
...(system && { system }),
|
|
124
|
+
...(tools && { tools }),
|
|
125
|
+
...(config.temperature !== undefined && {
|
|
126
|
+
temperature: config.temperature,
|
|
127
|
+
}),
|
|
128
|
+
...(config.rawAttributes || {}),
|
|
129
|
+
stream: true,
|
|
130
|
+
});
|
|
131
|
+
let content = "";
|
|
132
|
+
// Track tool blocks by index: index -> { id, name, arguments (partial JSON) }
|
|
133
|
+
const toolBlocks = new Map();
|
|
134
|
+
let inputTokens = 0;
|
|
135
|
+
let outputTokens = 0;
|
|
136
|
+
for await (const event of stream) {
|
|
137
|
+
if (event.type === "message_start") {
|
|
138
|
+
inputTokens = event.message.usage.input_tokens;
|
|
139
|
+
}
|
|
140
|
+
else if (event.type === "content_block_start" &&
|
|
141
|
+
event.content_block.type === "tool_use") {
|
|
142
|
+
toolBlocks.set(event.index, {
|
|
143
|
+
id: event.content_block.id,
|
|
144
|
+
name: event.content_block.name,
|
|
145
|
+
arguments: "",
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
else if (event.type === "content_block_delta") {
|
|
149
|
+
if (event.delta.type === "text_delta") {
|
|
150
|
+
content += event.delta.text;
|
|
151
|
+
yield { type: "text", text: event.delta.text };
|
|
152
|
+
}
|
|
153
|
+
else if (event.delta.type === "input_json_delta") {
|
|
154
|
+
const block = toolBlocks.get(event.index);
|
|
155
|
+
if (block) {
|
|
156
|
+
block.arguments += event.delta.partial_json;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (event.type === "message_delta") {
|
|
161
|
+
outputTokens = event.usage.output_tokens;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
this.logger.debug("Streaming response completed from Anthropic");
|
|
165
|
+
const toolCalls = [];
|
|
166
|
+
for (const block of toolBlocks.values()) {
|
|
167
|
+
const toolCall = new ToolCall(block.id, block.name, block.arguments);
|
|
168
|
+
toolCalls.push(toolCall);
|
|
169
|
+
yield { type: "tool_call", toolCall };
|
|
170
|
+
}
|
|
171
|
+
const usage = {
|
|
172
|
+
inputTokens,
|
|
173
|
+
outputTokens,
|
|
174
|
+
totalTokens: inputTokens + outputTokens,
|
|
175
|
+
};
|
|
176
|
+
const cost = calculateCost(this.model, usage) ?? undefined;
|
|
177
|
+
yield {
|
|
178
|
+
type: "done",
|
|
179
|
+
result: {
|
|
180
|
+
output: content || null,
|
|
181
|
+
toolCalls,
|
|
182
|
+
usage,
|
|
183
|
+
cost,
|
|
184
|
+
model: this.model,
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -131,6 +131,12 @@ export class BaseClient {
|
|
|
131
131
|
if (inner.success)
|
|
132
132
|
return inner.data;
|
|
133
133
|
}
|
|
134
|
+
// 7. Wrap object with "response" and see if that matches the schema
|
|
135
|
+
const wrapped = { response: rawValue };
|
|
136
|
+
const wrappedParse = schema.safeParse(wrapped);
|
|
137
|
+
if (wrappedParse.success) {
|
|
138
|
+
return wrappedParse.data;
|
|
139
|
+
}
|
|
134
140
|
// 8. Nothing worked — throw error
|
|
135
141
|
throw direct.error;
|
|
136
142
|
}
|
package/dist/functions.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { getClient } from "./client.js";
|
|
2
2
|
import { isModelConfig, pickModel } from "./models.js";
|
|
3
3
|
function splitConfig(config) {
|
|
4
|
-
const { openAiApiKey, googleApiKey, ollamaApiKey, ollamaHost, model: rawModel, provider, logLevel, toolLoopDetection, ...promptConfig } = config;
|
|
4
|
+
const { openAiApiKey, googleApiKey, ollamaApiKey, anthropicApiKey, ollamaHost, model: rawModel, provider, logLevel, toolLoopDetection, ...promptConfig } = config;
|
|
5
5
|
const model = isModelConfig(rawModel) ? pickModel(rawModel) : rawModel;
|
|
6
6
|
return {
|
|
7
7
|
smolConfig: {
|
|
8
8
|
openAiApiKey,
|
|
9
9
|
googleApiKey,
|
|
10
10
|
ollamaApiKey,
|
|
11
|
+
anthropicApiKey,
|
|
11
12
|
ollamaHost,
|
|
12
13
|
model,
|
|
13
14
|
provider,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/models.d.ts
CHANGED
|
@@ -303,25 +303,54 @@ export declare const textModels: readonly [{
|
|
|
303
303
|
readonly costUnit: "characters";
|
|
304
304
|
readonly disabled: true;
|
|
305
305
|
readonly provider: "google";
|
|
306
|
+
}, {
|
|
307
|
+
readonly type: "text";
|
|
308
|
+
readonly modelName: "claude-opus-4-6";
|
|
309
|
+
readonly description: "The most intelligent Claude model for building agents and coding. 200K context window, 128K max output.";
|
|
310
|
+
readonly maxInputTokens: 200000;
|
|
311
|
+
readonly maxOutputTokens: 131072;
|
|
312
|
+
readonly inputTokenCost: 5;
|
|
313
|
+
readonly outputTokenCost: 25;
|
|
314
|
+
readonly provider: "anthropic";
|
|
315
|
+
}, {
|
|
316
|
+
readonly type: "text";
|
|
317
|
+
readonly modelName: "claude-sonnet-4-6";
|
|
318
|
+
readonly description: "The best combination of speed and intelligence. 200K context window, 64K max output.";
|
|
319
|
+
readonly maxInputTokens: 200000;
|
|
320
|
+
readonly maxOutputTokens: 64000;
|
|
321
|
+
readonly inputTokenCost: 3;
|
|
322
|
+
readonly outputTokenCost: 15;
|
|
323
|
+
readonly provider: "anthropic";
|
|
324
|
+
}, {
|
|
325
|
+
readonly type: "text";
|
|
326
|
+
readonly modelName: "claude-haiku-4-5-20251001";
|
|
327
|
+
readonly description: "The fastest Claude model with near-frontier intelligence. 200K context window, 64K max output.";
|
|
328
|
+
readonly maxInputTokens: 200000;
|
|
329
|
+
readonly maxOutputTokens: 64000;
|
|
330
|
+
readonly inputTokenCost: 1;
|
|
331
|
+
readonly outputTokenCost: 5;
|
|
332
|
+
readonly provider: "anthropic";
|
|
306
333
|
}, {
|
|
307
334
|
readonly type: "text";
|
|
308
335
|
readonly modelName: "claude-3-7-sonnet-latest";
|
|
309
|
-
readonly description: "
|
|
336
|
+
readonly description: "Claude 3.7 Sonnet — legacy model. Use claude-sonnet-4-6 instead.";
|
|
310
337
|
readonly maxInputTokens: 200000;
|
|
311
338
|
readonly maxOutputTokens: 8192;
|
|
312
339
|
readonly inputTokenCost: 3;
|
|
313
340
|
readonly outputTokenCost: 15;
|
|
314
341
|
readonly outputTokensPerSecond: 78;
|
|
342
|
+
readonly disabled: true;
|
|
315
343
|
readonly provider: "anthropic";
|
|
316
344
|
}, {
|
|
317
345
|
readonly type: "text";
|
|
318
346
|
readonly modelName: "claude-3-5-haiku-latest";
|
|
319
|
-
readonly description: "
|
|
347
|
+
readonly description: "Claude 3.5 Haiku — legacy model. Use claude-haiku-4-5-20251001 instead.";
|
|
320
348
|
readonly maxInputTokens: 200000;
|
|
321
349
|
readonly maxOutputTokens: 8192;
|
|
322
350
|
readonly inputTokenCost: 0.8;
|
|
323
351
|
readonly outputTokenCost: 4;
|
|
324
352
|
readonly outputTokensPerSecond: 66;
|
|
353
|
+
readonly disabled: true;
|
|
325
354
|
readonly provider: "anthropic";
|
|
326
355
|
}, {
|
|
327
356
|
readonly type: "text";
|
|
@@ -666,25 +695,54 @@ export declare function getModel(modelName: ModelName): {
|
|
|
666
695
|
readonly costUnit: "characters";
|
|
667
696
|
readonly disabled: true;
|
|
668
697
|
readonly provider: "google";
|
|
698
|
+
} | {
|
|
699
|
+
readonly type: "text";
|
|
700
|
+
readonly modelName: "claude-opus-4-6";
|
|
701
|
+
readonly description: "The most intelligent Claude model for building agents and coding. 200K context window, 128K max output.";
|
|
702
|
+
readonly maxInputTokens: 200000;
|
|
703
|
+
readonly maxOutputTokens: 131072;
|
|
704
|
+
readonly inputTokenCost: 5;
|
|
705
|
+
readonly outputTokenCost: 25;
|
|
706
|
+
readonly provider: "anthropic";
|
|
707
|
+
} | {
|
|
708
|
+
readonly type: "text";
|
|
709
|
+
readonly modelName: "claude-sonnet-4-6";
|
|
710
|
+
readonly description: "The best combination of speed and intelligence. 200K context window, 64K max output.";
|
|
711
|
+
readonly maxInputTokens: 200000;
|
|
712
|
+
readonly maxOutputTokens: 64000;
|
|
713
|
+
readonly inputTokenCost: 3;
|
|
714
|
+
readonly outputTokenCost: 15;
|
|
715
|
+
readonly provider: "anthropic";
|
|
716
|
+
} | {
|
|
717
|
+
readonly type: "text";
|
|
718
|
+
readonly modelName: "claude-haiku-4-5-20251001";
|
|
719
|
+
readonly description: "The fastest Claude model with near-frontier intelligence. 200K context window, 64K max output.";
|
|
720
|
+
readonly maxInputTokens: 200000;
|
|
721
|
+
readonly maxOutputTokens: 64000;
|
|
722
|
+
readonly inputTokenCost: 1;
|
|
723
|
+
readonly outputTokenCost: 5;
|
|
724
|
+
readonly provider: "anthropic";
|
|
669
725
|
} | {
|
|
670
726
|
readonly type: "text";
|
|
671
727
|
readonly modelName: "claude-3-7-sonnet-latest";
|
|
672
|
-
readonly description: "
|
|
728
|
+
readonly description: "Claude 3.7 Sonnet — legacy model. Use claude-sonnet-4-6 instead.";
|
|
673
729
|
readonly maxInputTokens: 200000;
|
|
674
730
|
readonly maxOutputTokens: 8192;
|
|
675
731
|
readonly inputTokenCost: 3;
|
|
676
732
|
readonly outputTokenCost: 15;
|
|
677
733
|
readonly outputTokensPerSecond: 78;
|
|
734
|
+
readonly disabled: true;
|
|
678
735
|
readonly provider: "anthropic";
|
|
679
736
|
} | {
|
|
680
737
|
readonly type: "text";
|
|
681
738
|
readonly modelName: "claude-3-5-haiku-latest";
|
|
682
|
-
readonly description: "
|
|
739
|
+
readonly description: "Claude 3.5 Haiku — legacy model. Use claude-haiku-4-5-20251001 instead.";
|
|
683
740
|
readonly maxInputTokens: 200000;
|
|
684
741
|
readonly maxOutputTokens: 8192;
|
|
685
742
|
readonly inputTokenCost: 0.8;
|
|
686
743
|
readonly outputTokenCost: 4;
|
|
687
744
|
readonly outputTokensPerSecond: 66;
|
|
745
|
+
readonly disabled: true;
|
|
688
746
|
readonly provider: "anthropic";
|
|
689
747
|
} | {
|
|
690
748
|
readonly type: "text";
|
package/dist/models.js
CHANGED
|
@@ -307,26 +307,58 @@ export const textModels = [
|
|
|
307
307
|
disabled: true,
|
|
308
308
|
provider: "google",
|
|
309
309
|
},
|
|
310
|
+
{
|
|
311
|
+
type: "text",
|
|
312
|
+
modelName: "claude-opus-4-6",
|
|
313
|
+
description: "The most intelligent Claude model for building agents and coding. 200K context window, 128K max output.",
|
|
314
|
+
maxInputTokens: 200_000,
|
|
315
|
+
maxOutputTokens: 131_072,
|
|
316
|
+
inputTokenCost: 5,
|
|
317
|
+
outputTokenCost: 25,
|
|
318
|
+
provider: "anthropic",
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
type: "text",
|
|
322
|
+
modelName: "claude-sonnet-4-6",
|
|
323
|
+
description: "The best combination of speed and intelligence. 200K context window, 64K max output.",
|
|
324
|
+
maxInputTokens: 200_000,
|
|
325
|
+
maxOutputTokens: 64_000,
|
|
326
|
+
inputTokenCost: 3,
|
|
327
|
+
outputTokenCost: 15,
|
|
328
|
+
provider: "anthropic",
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
type: "text",
|
|
332
|
+
modelName: "claude-haiku-4-5-20251001",
|
|
333
|
+
description: "The fastest Claude model with near-frontier intelligence. 200K context window, 64K max output.",
|
|
334
|
+
maxInputTokens: 200_000,
|
|
335
|
+
maxOutputTokens: 64_000,
|
|
336
|
+
inputTokenCost: 1,
|
|
337
|
+
outputTokenCost: 5,
|
|
338
|
+
provider: "anthropic",
|
|
339
|
+
},
|
|
310
340
|
{
|
|
311
341
|
type: "text",
|
|
312
342
|
modelName: "claude-3-7-sonnet-latest",
|
|
313
|
-
description: "
|
|
343
|
+
description: "Claude 3.7 Sonnet — legacy model. Use claude-sonnet-4-6 instead.",
|
|
314
344
|
maxInputTokens: 200_000,
|
|
315
345
|
maxOutputTokens: 8192,
|
|
316
346
|
inputTokenCost: 3,
|
|
317
347
|
outputTokenCost: 15,
|
|
318
348
|
outputTokensPerSecond: 78,
|
|
349
|
+
disabled: true,
|
|
319
350
|
provider: "anthropic",
|
|
320
351
|
},
|
|
321
352
|
{
|
|
322
353
|
type: "text",
|
|
323
354
|
modelName: "claude-3-5-haiku-latest",
|
|
324
|
-
description: "
|
|
355
|
+
description: "Claude 3.5 Haiku — legacy model. Use claude-haiku-4-5-20251001 instead.",
|
|
325
356
|
maxInputTokens: 200_000,
|
|
326
357
|
maxOutputTokens: 8192,
|
|
327
358
|
inputTokenCost: 0.8,
|
|
328
359
|
outputTokenCost: 4,
|
|
329
360
|
outputTokensPerSecond: 66,
|
|
361
|
+
disabled: true,
|
|
330
362
|
provider: "anthropic",
|
|
331
363
|
},
|
|
332
364
|
/* {
|
package/dist/types.d.ts
CHANGED
package/dist/util/tool.d.ts
CHANGED
|
@@ -29,6 +29,18 @@ export declare function zodToOpenAIResponsesTool(name: string, schema: z.ZodType
|
|
|
29
29
|
description?: string;
|
|
30
30
|
strict?: boolean;
|
|
31
31
|
}>): OpenAIResponsesFunctionTool;
|
|
32
|
+
export type AnthropicTool = {
|
|
33
|
+
name: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
input_schema: {
|
|
36
|
+
type: "object";
|
|
37
|
+
properties: Record<string, any>;
|
|
38
|
+
required?: string[];
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export declare function zodToAnthropicTool(name: string, schema: z.ZodType, options?: Partial<{
|
|
42
|
+
description?: string;
|
|
43
|
+
}>): AnthropicTool;
|
|
32
44
|
/**
|
|
33
45
|
* Converts an OpenAI tool definition to a Google FunctionDeclaration format
|
|
34
46
|
*
|
package/dist/util/tool.js
CHANGED
|
@@ -62,6 +62,30 @@ export function zodToOpenAIResponsesTool(name, schema, options = {}) {
|
|
|
62
62
|
}
|
|
63
63
|
return tool;
|
|
64
64
|
}
|
|
65
|
+
export function zodToAnthropicTool(name, schema, options = {}) {
|
|
66
|
+
const jsonSchema = schema.toJSONSchema();
|
|
67
|
+
let description;
|
|
68
|
+
if (options?.description) {
|
|
69
|
+
description = options.description;
|
|
70
|
+
}
|
|
71
|
+
else if (typeof jsonSchema === "object" &&
|
|
72
|
+
"description" in jsonSchema &&
|
|
73
|
+
typeof jsonSchema.description === "string") {
|
|
74
|
+
description = jsonSchema.description;
|
|
75
|
+
}
|
|
76
|
+
const tool = {
|
|
77
|
+
name,
|
|
78
|
+
input_schema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: jsonSchema.properties || {},
|
|
81
|
+
required: jsonSchema.required || [],
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
if (description) {
|
|
85
|
+
tool.description = description;
|
|
86
|
+
}
|
|
87
|
+
return tool;
|
|
88
|
+
}
|
|
65
89
|
/**
|
|
66
90
|
* Removes properties that Google's API doesn't support from JSON schemas
|
|
67
91
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smoltalk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "A common interface for LLM APIs",
|
|
5
5
|
"homepage": "https://github.com/egonSchiele/smoltalk",
|
|
6
6
|
"scripts": {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"zod": "^4.3.5"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
+
"@anthropic-ai/sdk": "^0.78.0",
|
|
44
45
|
"@google/genai": "^1.34.0",
|
|
45
46
|
"egonlog": "^0.0.2",
|
|
46
47
|
"ollama": "^0.6.3",
|