smoltalk 0.0.52 → 0.0.54
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/README.md +2 -2
- package/dist/classes/ToolCall.d.ts +8 -6
- package/dist/classes/ToolCall.js +9 -1
- package/dist/classes/message/AssistantMessage.d.ts +37 -13
- package/dist/classes/message/AssistantMessage.js +27 -19
- package/dist/classes/message/BaseMessage.d.ts +1 -0
- package/dist/classes/message/BaseMessage.js +5 -0
- package/dist/classes/message/DeveloperMessage.d.ts +12 -6
- package/dist/classes/message/DeveloperMessage.js +13 -6
- package/dist/classes/message/SystemMessage.d.ts +12 -6
- package/dist/classes/message/SystemMessage.js +13 -6
- package/dist/classes/message/ToolMessage.d.ts +13 -7
- package/dist/classes/message/ToolMessage.js +15 -7
- package/dist/classes/message/UserMessage.d.ts +9 -6
- package/dist/classes/message/UserMessage.js +11 -3
- package/dist/classes/message/index.js +1 -1
- package/dist/client.d.ts +4 -7
- package/dist/client.js +29 -17
- package/dist/clients/baseClient.d.ts +4 -5
- package/dist/clients/baseClient.js +26 -26
- package/dist/clients/google.js +2 -1
- package/dist/clients/ollama.js +78 -72
- package/dist/clients/openai.js +5 -3
- package/dist/clients/openaiResponses.js +2 -3
- package/dist/functions.d.ts +6 -2
- package/dist/functions.js +11 -32
- package/dist/model.d.ts +14 -12
- package/dist/model.js +40 -14
- package/dist/models.d.ts +19 -4
- package/dist/models.js +22 -1
- package/dist/statelogClient.d.ts +3 -4
- package/dist/statelogClient.js +6 -4
- package/dist/strategies/baseStrategy.js +2 -2
- package/dist/strategies/fallbackStrategy.d.ts +6 -7
- package/dist/strategies/fallbackStrategy.js +61 -48
- package/dist/strategies/idStrategy.d.ts +5 -3
- package/dist/strategies/idStrategy.js +44 -10
- package/dist/strategies/index.d.ts +3 -3
- package/dist/strategies/index.js +20 -22
- package/dist/strategies/raceStrategy.d.ts +3 -2
- package/dist/strategies/raceStrategy.js +8 -1
- package/dist/strategies/types.d.ts +68 -13
- package/dist/strategies/types.js +57 -1
- package/dist/types.d.ts +121 -13
- package/dist/types.js +32 -0
- package/dist/util/tool.js +4 -0
- package/dist/util.d.ts +10 -0
- package/dist/util.js +34 -0
- package/package.json +4 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smoltalk
|
|
2
2
|
|
|
3
|
-
Smoltalk
|
|
3
|
+
Smoltalk exposes a common API to different LLM providers. There are other packages that do this, but Smoltalk allows you to build strategies on top of it. Here is a simple example. Hello world, this is functionality that other packages allow.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ Smoltalk is a package that exposes a common interface across different LLM provi
|
|
|
8
8
|
pnpm install smoltalk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Hello world example
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
import { getClient } from "smoltalk";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { FunctionCall } from "@google/genai";
|
|
2
3
|
import { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
3
|
-
export
|
|
4
|
-
id:
|
|
5
|
-
name:
|
|
6
|
-
arguments:
|
|
7
|
-
}
|
|
4
|
+
export declare const ToolCallJSONSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodDefault<z.ZodString>;
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type ToolCallJSON = z.infer<typeof ToolCallJSONSchema>;
|
|
8
10
|
export type ToolCallOptions = {};
|
|
9
11
|
export declare class ToolCall {
|
|
10
12
|
private _id;
|
|
@@ -16,7 +18,7 @@ export declare class ToolCall {
|
|
|
16
18
|
get name(): string;
|
|
17
19
|
get arguments(): Record<string, any>;
|
|
18
20
|
toJSON(): ToolCallJSON;
|
|
19
|
-
static fromJSON(json:
|
|
21
|
+
static fromJSON(json: unknown): ToolCall;
|
|
20
22
|
toOpenAI(): any;
|
|
21
23
|
toGoogle(): {
|
|
22
24
|
functionCall: FunctionCall;
|
package/dist/classes/ToolCall.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { getLogger } from "../logger.js";
|
|
3
|
+
export const ToolCallJSONSchema = z.object({
|
|
4
|
+
id: z.string().default(""),
|
|
5
|
+
name: z.string(),
|
|
6
|
+
arguments: z.record(z.string(), z.any()).default({}),
|
|
7
|
+
});
|
|
2
8
|
export class ToolCall {
|
|
3
9
|
_id;
|
|
4
10
|
_name;
|
|
@@ -14,6 +20,7 @@ export class ToolCall {
|
|
|
14
20
|
}
|
|
15
21
|
catch (e) {
|
|
16
22
|
this.logger.error(`Failed to parse arguments for ToolCall ${name} with id ${id}:`, e, args);
|
|
23
|
+
this.logger.debug("Falling back to empty arguments object for ToolCall", { name, id, rawArgs: args });
|
|
17
24
|
this._arguments = {};
|
|
18
25
|
}
|
|
19
26
|
}
|
|
@@ -38,7 +45,8 @@ export class ToolCall {
|
|
|
38
45
|
};
|
|
39
46
|
}
|
|
40
47
|
static fromJSON(json) {
|
|
41
|
-
|
|
48
|
+
const parsed = ToolCallJSONSchema.parse(json);
|
|
49
|
+
return new ToolCall(parsed.id, parsed.name, parsed.arguments);
|
|
42
50
|
}
|
|
43
51
|
toOpenAI() {
|
|
44
52
|
return {
|
|
@@ -1,21 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage, MessageClass } from "./BaseMessage.js";
|
|
2
3
|
import { CostEstimate, TextPart, ThinkingBlock, TokenUsage } from "../../types.js";
|
|
3
4
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
4
5
|
import { Content } from "@google/genai";
|
|
5
|
-
import { ToolCall
|
|
6
|
+
import { ToolCall } from "../ToolCall.js";
|
|
6
7
|
import { Message } from "ollama";
|
|
7
8
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
8
|
-
export
|
|
9
|
-
role: "assistant"
|
|
10
|
-
content:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
export declare const AssistantMessageJSONSchema: z.ZodObject<{
|
|
10
|
+
role: z.ZodLiteral<"assistant">;
|
|
11
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
12
|
+
type: z.ZodLiteral<"text">;
|
|
13
|
+
text: z.ZodString;
|
|
14
|
+
}, z.core.$strip>>, z.ZodNull]>;
|
|
15
|
+
name: z.ZodOptional<z.ZodString>;
|
|
16
|
+
audio: z.ZodOptional<z.ZodAny>;
|
|
17
|
+
refusal: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
|
+
toolCalls: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
19
|
+
id: z.ZodDefault<z.ZodString>;
|
|
20
|
+
name: z.ZodString;
|
|
21
|
+
arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
22
|
+
}, z.core.$strip>>>;
|
|
23
|
+
thinkingBlocks: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
24
|
+
text: z.ZodString;
|
|
25
|
+
signature: z.ZodString;
|
|
26
|
+
}, z.core.$strip>>>;
|
|
27
|
+
rawData: z.ZodOptional<z.ZodAny>;
|
|
28
|
+
usage: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
inputTokens: z.ZodNumber;
|
|
30
|
+
outputTokens: z.ZodNumber;
|
|
31
|
+
cachedInputTokens: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
totalTokens: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
}, z.core.$strip>>;
|
|
34
|
+
cost: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
inputCost: z.ZodNumber;
|
|
36
|
+
outputCost: z.ZodNumber;
|
|
37
|
+
cachedInputCost: z.ZodOptional<z.ZodNumber>;
|
|
38
|
+
totalCost: z.ZodNumber;
|
|
39
|
+
currency: z.ZodString;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type AssistantMessageJSON = z.infer<typeof AssistantMessageJSONSchema>;
|
|
19
43
|
export declare class AssistantMessage extends BaseMessage implements MessageClass {
|
|
20
44
|
_role: "assistant";
|
|
21
45
|
_content: string | Array<TextPart> | null;
|
|
@@ -49,7 +73,7 @@ export declare class AssistantMessage extends BaseMessage implements MessageClas
|
|
|
49
73
|
get usage(): TokenUsage | undefined;
|
|
50
74
|
get cost(): CostEstimate | undefined;
|
|
51
75
|
toJSON(): AssistantMessageJSON;
|
|
52
|
-
static fromJSON(json:
|
|
76
|
+
static fromJSON(json: unknown): AssistantMessage;
|
|
53
77
|
toOpenAIMessage(): ChatCompletionMessageParam;
|
|
54
78
|
toOpenAIResponseInputItem(): ResponseInputItem | ResponseInputItem[];
|
|
55
79
|
toGoogleMessage(): Content;
|
|
@@ -1,5 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage } from "./BaseMessage.js";
|
|
2
|
-
import {
|
|
3
|
+
import { CostEstimateSchema, TextPartSchema, ThinkingBlockSchema, TokenUsageSchema, } from "../../types.js";
|
|
4
|
+
import { ToolCall, ToolCallJSONSchema } from "../ToolCall.js";
|
|
5
|
+
export const AssistantMessageJSONSchema = z.object({
|
|
6
|
+
role: z.literal("assistant"),
|
|
7
|
+
content: z.union([z.string(), z.array(TextPartSchema), z.null()]),
|
|
8
|
+
name: z.string().optional(),
|
|
9
|
+
audio: z.any().optional(),
|
|
10
|
+
refusal: z.string().nullable().optional(),
|
|
11
|
+
toolCalls: z.array(ToolCallJSONSchema).optional(),
|
|
12
|
+
thinkingBlocks: z.array(ThinkingBlockSchema).optional(),
|
|
13
|
+
rawData: z.any().optional(),
|
|
14
|
+
usage: TokenUsageSchema.optional(),
|
|
15
|
+
cost: CostEstimateSchema.optional(),
|
|
16
|
+
});
|
|
3
17
|
export class AssistantMessage extends BaseMessage {
|
|
4
18
|
_role = "assistant";
|
|
5
19
|
_content;
|
|
@@ -24,12 +38,7 @@ export class AssistantMessage extends BaseMessage {
|
|
|
24
38
|
this._cost = options.cost;
|
|
25
39
|
}
|
|
26
40
|
get content() {
|
|
27
|
-
|
|
28
|
-
return "";
|
|
29
|
-
}
|
|
30
|
-
return typeof this._content === "string"
|
|
31
|
-
? this._content
|
|
32
|
-
: JSON.stringify(this._content);
|
|
41
|
+
return this.contentToString(this._content);
|
|
33
42
|
}
|
|
34
43
|
set content(value) {
|
|
35
44
|
this._content = value;
|
|
@@ -75,17 +84,16 @@ export class AssistantMessage extends BaseMessage {
|
|
|
75
84
|
};
|
|
76
85
|
}
|
|
77
86
|
static fromJSON(json) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
cost: json.cost,
|
|
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,
|
|
89
97
|
});
|
|
90
98
|
}
|
|
91
99
|
toOpenAIMessage() {
|
|
@@ -154,7 +162,7 @@ export class AssistantMessage extends BaseMessage {
|
|
|
154
162
|
const blocks = [];
|
|
155
163
|
// Thinking blocks must come first (Anthropic requires this ordering)
|
|
156
164
|
if (hasThinking) {
|
|
157
|
-
for (const block of this._thinkingBlocks) {
|
|
165
|
+
for (const block of this._thinkingBlocks ?? []) {
|
|
158
166
|
blocks.push({ type: "thinking", thinking: block.text, signature: block.signature });
|
|
159
167
|
}
|
|
160
168
|
}
|
|
@@ -3,6 +3,7 @@ import { Message } from "ollama";
|
|
|
3
3
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
4
4
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
5
5
|
export declare class BaseMessage {
|
|
6
|
+
protected contentToString(content: string | unknown[] | null | undefined): string;
|
|
6
7
|
}
|
|
7
8
|
export interface MessageClass {
|
|
8
9
|
get content(): string;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage, MessageClass } from "./BaseMessage.js";
|
|
2
3
|
import { TextPart } from "../../types.js";
|
|
3
4
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
4
5
|
import { Content } from "@google/genai";
|
|
5
6
|
import { Message } from "ollama";
|
|
6
7
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
7
|
-
export
|
|
8
|
-
role: "developer"
|
|
9
|
-
content:
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export declare const DeveloperMessageJSONSchema: z.ZodObject<{
|
|
9
|
+
role: z.ZodLiteral<"developer">;
|
|
10
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"text">;
|
|
12
|
+
text: z.ZodString;
|
|
13
|
+
}, z.core.$strip>>]>;
|
|
14
|
+
name: z.ZodOptional<z.ZodString>;
|
|
15
|
+
rawData: z.ZodOptional<z.ZodAny>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export type DeveloperMessageJSON = z.infer<typeof DeveloperMessageJSONSchema>;
|
|
12
18
|
export declare class DeveloperMessage extends BaseMessage implements MessageClass {
|
|
13
19
|
_role: "developer";
|
|
14
20
|
_content: string | Array<TextPart>;
|
|
@@ -24,7 +30,7 @@ export declare class DeveloperMessage extends BaseMessage implements MessageClas
|
|
|
24
30
|
get name(): string | undefined;
|
|
25
31
|
get rawData(): any;
|
|
26
32
|
toJSON(): DeveloperMessageJSON;
|
|
27
|
-
static fromJSON(json:
|
|
33
|
+
static fromJSON(json: unknown): DeveloperMessage;
|
|
28
34
|
toOpenAIMessage(): ChatCompletionMessageParam;
|
|
29
35
|
toOpenAIResponseInputItem(): ResponseInputItem;
|
|
30
36
|
toGoogleMessage(): Content;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage } from "./BaseMessage.js";
|
|
3
|
+
import { TextPartSchema } from "../../types.js";
|
|
4
|
+
export const DeveloperMessageJSONSchema = z.object({
|
|
5
|
+
role: z.literal("developer"),
|
|
6
|
+
content: z.union([z.string(), z.array(TextPartSchema)]),
|
|
7
|
+
name: z.string().optional(),
|
|
8
|
+
rawData: z.any().optional(),
|
|
9
|
+
});
|
|
2
10
|
export class DeveloperMessage extends BaseMessage {
|
|
3
11
|
_role = "developer";
|
|
4
12
|
_content;
|
|
@@ -11,9 +19,7 @@ export class DeveloperMessage extends BaseMessage {
|
|
|
11
19
|
this._rawData = options.rawData;
|
|
12
20
|
}
|
|
13
21
|
get content() {
|
|
14
|
-
return
|
|
15
|
-
? this._content
|
|
16
|
-
: JSON.stringify(this._content);
|
|
22
|
+
return this.contentToString(this._content);
|
|
17
23
|
}
|
|
18
24
|
set content(value) {
|
|
19
25
|
this._content = value;
|
|
@@ -35,9 +41,10 @@ export class DeveloperMessage extends BaseMessage {
|
|
|
35
41
|
};
|
|
36
42
|
}
|
|
37
43
|
static fromJSON(json) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
const parsed = DeveloperMessageJSONSchema.parse(json);
|
|
45
|
+
return new DeveloperMessage(parsed.content, {
|
|
46
|
+
name: parsed.name,
|
|
47
|
+
rawData: parsed.rawData,
|
|
41
48
|
});
|
|
42
49
|
}
|
|
43
50
|
toOpenAIMessage() {
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage, MessageClass } from "./BaseMessage.js";
|
|
2
3
|
import { TextPart } from "../../types.js";
|
|
3
4
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
4
5
|
import { Content } from "@google/genai";
|
|
5
6
|
import { Message } from "ollama";
|
|
6
7
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
7
|
-
export
|
|
8
|
-
role: "system"
|
|
9
|
-
content:
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export declare const SystemMessageJSONSchema: z.ZodObject<{
|
|
9
|
+
role: z.ZodLiteral<"system">;
|
|
10
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"text">;
|
|
12
|
+
text: z.ZodString;
|
|
13
|
+
}, z.core.$strip>>]>;
|
|
14
|
+
name: z.ZodOptional<z.ZodString>;
|
|
15
|
+
rawData: z.ZodOptional<z.ZodAny>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export type SystemMessageJSON = z.infer<typeof SystemMessageJSONSchema>;
|
|
12
18
|
export declare class SystemMessage extends BaseMessage implements MessageClass {
|
|
13
19
|
_role: "system";
|
|
14
20
|
_content: string | Array<TextPart>;
|
|
@@ -24,7 +30,7 @@ export declare class SystemMessage extends BaseMessage implements MessageClass {
|
|
|
24
30
|
get name(): string | undefined;
|
|
25
31
|
get rawData(): any;
|
|
26
32
|
toJSON(): SystemMessageJSON;
|
|
27
|
-
static fromJSON(json:
|
|
33
|
+
static fromJSON(json: unknown): SystemMessage;
|
|
28
34
|
toOpenAIMessage(): ChatCompletionMessageParam;
|
|
29
35
|
toOpenAIResponseInputItem(): ResponseInputItem;
|
|
30
36
|
toGoogleMessage(): Content;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage } from "./BaseMessage.js";
|
|
3
|
+
import { TextPartSchema } from "../../types.js";
|
|
4
|
+
export const SystemMessageJSONSchema = z.object({
|
|
5
|
+
role: z.literal("system"),
|
|
6
|
+
content: z.union([z.string(), z.array(TextPartSchema)]),
|
|
7
|
+
name: z.string().optional(),
|
|
8
|
+
rawData: z.any().optional(),
|
|
9
|
+
});
|
|
2
10
|
export class SystemMessage extends BaseMessage {
|
|
3
11
|
_role = "system";
|
|
4
12
|
_content;
|
|
@@ -11,9 +19,7 @@ export class SystemMessage extends BaseMessage {
|
|
|
11
19
|
this._rawData = options.rawData;
|
|
12
20
|
}
|
|
13
21
|
get content() {
|
|
14
|
-
return
|
|
15
|
-
? this._content
|
|
16
|
-
: JSON.stringify(this._content);
|
|
22
|
+
return this.contentToString(this._content);
|
|
17
23
|
}
|
|
18
24
|
set content(value) {
|
|
19
25
|
this._content = value;
|
|
@@ -35,9 +41,10 @@ export class SystemMessage extends BaseMessage {
|
|
|
35
41
|
};
|
|
36
42
|
}
|
|
37
43
|
static fromJSON(json) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
const parsed = SystemMessageJSONSchema.parse(json);
|
|
45
|
+
return new SystemMessage(parsed.content, {
|
|
46
|
+
name: parsed.name,
|
|
47
|
+
rawData: parsed.rawData,
|
|
41
48
|
});
|
|
42
49
|
}
|
|
43
50
|
toOpenAIMessage() {
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage, MessageClass } from "./BaseMessage.js";
|
|
2
3
|
import { TextPart } from "../../types.js";
|
|
3
4
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
4
5
|
import { Content } from "@google/genai";
|
|
5
6
|
import { Message } from "ollama";
|
|
6
7
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
7
|
-
export
|
|
8
|
-
role: "tool"
|
|
9
|
-
content:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
8
|
+
export declare const ToolMessageJSONSchema: z.ZodObject<{
|
|
9
|
+
role: z.ZodLiteral<"tool">;
|
|
10
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"text">;
|
|
12
|
+
text: z.ZodString;
|
|
13
|
+
}, z.core.$strip>>]>;
|
|
14
|
+
name: z.ZodString;
|
|
15
|
+
tool_call_id: z.ZodDefault<z.ZodString>;
|
|
16
|
+
rawData: z.ZodOptional<z.ZodAny>;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type ToolMessageJSON = z.infer<typeof ToolMessageJSONSchema>;
|
|
13
19
|
export declare class ToolMessage extends BaseMessage implements MessageClass {
|
|
14
20
|
_role: "tool";
|
|
15
21
|
_content: string | Array<TextPart>;
|
|
@@ -28,7 +34,7 @@ export declare class ToolMessage extends BaseMessage implements MessageClass {
|
|
|
28
34
|
get tool_call_id(): string;
|
|
29
35
|
get rawData(): any;
|
|
30
36
|
toJSON(): ToolMessageJSON;
|
|
31
|
-
static fromJSON(json:
|
|
37
|
+
static fromJSON(json: unknown): ToolMessage;
|
|
32
38
|
toOpenAIMessage(): ChatCompletionMessageParam;
|
|
33
39
|
toOpenAIResponseInputItem(): ResponseInputItem;
|
|
34
40
|
toGoogleMessage(): Content;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage } from "./BaseMessage.js";
|
|
3
|
+
import { TextPartSchema } from "../../types.js";
|
|
4
|
+
export const ToolMessageJSONSchema = z.object({
|
|
5
|
+
role: z.literal("tool"),
|
|
6
|
+
content: z.union([z.string(), z.array(TextPartSchema)]),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
tool_call_id: z.string().default(""),
|
|
9
|
+
rawData: z.any().optional(),
|
|
10
|
+
});
|
|
2
11
|
export class ToolMessage extends BaseMessage {
|
|
3
12
|
_role = "tool";
|
|
4
13
|
_content;
|
|
@@ -13,9 +22,7 @@ export class ToolMessage extends BaseMessage {
|
|
|
13
22
|
this._name = options.name;
|
|
14
23
|
}
|
|
15
24
|
get content() {
|
|
16
|
-
return
|
|
17
|
-
? this._content
|
|
18
|
-
: JSON.stringify(this._content);
|
|
25
|
+
return this.contentToString(this._content);
|
|
19
26
|
}
|
|
20
27
|
set content(value) {
|
|
21
28
|
this._content = value;
|
|
@@ -41,10 +48,11 @@ export class ToolMessage extends BaseMessage {
|
|
|
41
48
|
};
|
|
42
49
|
}
|
|
43
50
|
static fromJSON(json) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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,
|
|
48
56
|
});
|
|
49
57
|
}
|
|
50
58
|
toOpenAIMessage() {
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage, MessageClass } from "./BaseMessage.js";
|
|
2
3
|
import { ChatCompletionMessageParam } from "openai/resources";
|
|
3
4
|
import { Content } from "@google/genai";
|
|
4
5
|
import { Message } from "ollama";
|
|
5
6
|
import type { ResponseInputItem } from "openai/resources/responses/responses.js";
|
|
6
|
-
export
|
|
7
|
-
role: "user"
|
|
8
|
-
content:
|
|
9
|
-
name:
|
|
10
|
-
|
|
7
|
+
export declare const UserMessageJSONSchema: z.ZodObject<{
|
|
8
|
+
role: z.ZodLiteral<"user">;
|
|
9
|
+
content: z.ZodString;
|
|
10
|
+
name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
rawData: z.ZodOptional<z.ZodAny>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export type UserMessageJSON = z.infer<typeof UserMessageJSONSchema>;
|
|
11
14
|
export declare class UserMessage extends BaseMessage implements MessageClass {
|
|
12
15
|
_role: "user";
|
|
13
16
|
_content: string;
|
|
@@ -23,7 +26,7 @@ export declare class UserMessage extends BaseMessage implements MessageClass {
|
|
|
23
26
|
get name(): string | undefined;
|
|
24
27
|
get rawData(): any;
|
|
25
28
|
toJSON(): UserMessageJSON;
|
|
26
|
-
static fromJSON(json:
|
|
29
|
+
static fromJSON(json: unknown): UserMessage;
|
|
27
30
|
toOpenAIMessage(): ChatCompletionMessageParam;
|
|
28
31
|
toOpenAIResponseInputItem(): ResponseInputItem;
|
|
29
32
|
toGoogleMessage(): Content;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { BaseMessage } from "./BaseMessage.js";
|
|
3
|
+
export const UserMessageJSONSchema = z.object({
|
|
4
|
+
role: z.literal("user"),
|
|
5
|
+
content: z.string(),
|
|
6
|
+
name: z.string().optional(),
|
|
7
|
+
rawData: z.any().optional(),
|
|
8
|
+
});
|
|
2
9
|
export class UserMessage extends BaseMessage {
|
|
3
10
|
_role = "user";
|
|
4
11
|
_content;
|
|
@@ -33,9 +40,10 @@ export class UserMessage extends BaseMessage {
|
|
|
33
40
|
};
|
|
34
41
|
}
|
|
35
42
|
static fromJSON(json) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
const parsed = UserMessageJSONSchema.parse(json);
|
|
44
|
+
return new UserMessage(parsed.content, {
|
|
45
|
+
name: parsed.name,
|
|
46
|
+
rawData: parsed.rawData,
|
|
39
47
|
});
|
|
40
48
|
}
|
|
41
49
|
toOpenAIMessage() {
|
|
@@ -22,7 +22,7 @@ export function messageFromJSON(json) {
|
|
|
22
22
|
case "tool":
|
|
23
23
|
return ToolMessage.fromJSON(json);
|
|
24
24
|
default:
|
|
25
|
-
throw new Error(`Unknown message: ${
|
|
25
|
+
throw new Error(`Unknown message role: ${json?.role}`);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
export function userMessage(content, options = {}) {
|
package/dist/client.d.ts
CHANGED
|
@@ -2,10 +2,7 @@ export * from "./clients/anthropic.js";
|
|
|
2
2
|
export * from "./clients/google.js";
|
|
3
3
|
export * from "./clients/openai.js";
|
|
4
4
|
export * from "./clients/openaiResponses.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { SmolConfig } from "./types.js";
|
|
10
|
-
import { SmolOllama } from "./clients/ollama.js";
|
|
11
|
-
export declare function getClient(config: SmolConfig): SmolAnthropic | SmolGoogle | SmolOpenAi | SmolOpenAiResponses | SmolOllama;
|
|
5
|
+
import { BaseClient } from "./clients/baseClient.js";
|
|
6
|
+
import { ResolvedSmolConfig } from "./types.js";
|
|
7
|
+
export declare function registerProvider(providerName: string, clientClass: typeof BaseClient): void;
|
|
8
|
+
export declare function getClient(config: ResolvedSmolConfig): BaseClient;
|
package/dist/client.js
CHANGED
|
@@ -4,19 +4,18 @@ export * from "./clients/openai.js";
|
|
|
4
4
|
export * from "./clients/openaiResponses.js";
|
|
5
5
|
import { SmolAnthropic } from "./clients/anthropic.js";
|
|
6
6
|
import { SmolGoogle } from "./clients/google.js";
|
|
7
|
+
import { SmolOllama } from "./clients/ollama.js";
|
|
7
8
|
import { SmolOpenAi } from "./clients/openai.js";
|
|
8
9
|
import { SmolOpenAiResponses } from "./clients/openaiResponses.js";
|
|
9
10
|
import { getModel, isTextModel } from "./models.js";
|
|
10
11
|
import { SmolError } from "./smolError.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const registeredProviders = {};
|
|
13
|
+
export function registerProvider(providerName, clientClass) {
|
|
14
|
+
registeredProviders[providerName] = clientClass;
|
|
15
|
+
}
|
|
14
16
|
export function getClient(config) {
|
|
15
|
-
// Initialize logger singleton with desired log level
|
|
16
|
-
const logger = getLogger(config.logLevel);
|
|
17
|
-
// Resolve ModelConfig to a concrete model name
|
|
18
|
-
const modelName = new Model(config.model).getResolvedModel();
|
|
19
17
|
let provider = config.provider;
|
|
18
|
+
const modelName = config.model;
|
|
20
19
|
if (!provider) {
|
|
21
20
|
const model = getModel(modelName);
|
|
22
21
|
if (model === undefined) {
|
|
@@ -27,34 +26,47 @@ export function getClient(config) {
|
|
|
27
26
|
}
|
|
28
27
|
provider = model.provider;
|
|
29
28
|
}
|
|
30
|
-
const
|
|
29
|
+
const resolvedKeys = {
|
|
30
|
+
openAiApiKey: config.openAiApiKey || process.env.OPENAI_API_KEY,
|
|
31
|
+
googleApiKey: config.googleApiKey || process.env.GEMINI_API_KEY,
|
|
32
|
+
anthropicApiKey: config.anthropicApiKey || process.env.ANTHROPIC_API_KEY,
|
|
33
|
+
};
|
|
34
|
+
const clientConfig = {
|
|
35
|
+
...config,
|
|
36
|
+
...resolvedKeys,
|
|
37
|
+
model: modelName,
|
|
38
|
+
};
|
|
31
39
|
switch (provider) {
|
|
32
40
|
case "anthropic":
|
|
33
|
-
if (!
|
|
34
|
-
throw new SmolError("No Anthropic API key provided. Please provide an Anthropic API key in the config using anthropicApiKey.");
|
|
41
|
+
if (!resolvedKeys.anthropicApiKey) {
|
|
42
|
+
throw new SmolError("No Anthropic API key provided. Please provide an Anthropic API key in the config using anthropicApiKey, or set the ANTHROPIC_API_KEY environment variable.");
|
|
35
43
|
}
|
|
36
44
|
return new SmolAnthropic({
|
|
37
45
|
...clientConfig,
|
|
38
|
-
anthropicApiKey:
|
|
46
|
+
anthropicApiKey: resolvedKeys.anthropicApiKey,
|
|
39
47
|
});
|
|
40
48
|
case "openai":
|
|
41
|
-
if (!
|
|
42
|
-
throw new SmolError("No OpenAI API key provided. Please provide an OpenAI API key in the config using openAiApiKey.");
|
|
49
|
+
if (!resolvedKeys.openAiApiKey) {
|
|
50
|
+
throw new SmolError("No OpenAI API key provided. Please provide an OpenAI API key in the config using openAiApiKey, or set the OPENAI_API_KEY environment variable.");
|
|
43
51
|
}
|
|
44
52
|
return new SmolOpenAi(clientConfig);
|
|
45
53
|
case "openai-responses":
|
|
46
|
-
if (!
|
|
47
|
-
throw new SmolError("No OpenAI API key provided. Please provide an OpenAI API key in the config using openAiApiKey.");
|
|
54
|
+
if (!resolvedKeys.openAiApiKey) {
|
|
55
|
+
throw new SmolError("No OpenAI API key provided. Please provide an OpenAI API key in the config using openAiApiKey, or set the OPENAI_API_KEY environment variable.");
|
|
48
56
|
}
|
|
49
57
|
return new SmolOpenAiResponses(clientConfig);
|
|
50
58
|
case "google":
|
|
51
|
-
if (!
|
|
52
|
-
throw new SmolError("No Google API key provided. Please provide a Google API key in the config using googleApiKey.");
|
|
59
|
+
if (!resolvedKeys.googleApiKey) {
|
|
60
|
+
throw new SmolError("No Google API key provided. Please provide a Google API key in the config using googleApiKey, or set the GEMINI_API_KEY environment variable.");
|
|
53
61
|
}
|
|
54
62
|
return new SmolGoogle(clientConfig);
|
|
55
63
|
case "ollama":
|
|
56
64
|
return new SmolOllama(clientConfig);
|
|
57
65
|
default:
|
|
66
|
+
if (provider in registeredProviders) {
|
|
67
|
+
const ClientClass = registeredProviders[provider];
|
|
68
|
+
return new ClientClass(clientConfig);
|
|
69
|
+
}
|
|
58
70
|
throw new SmolError(`Model provider ${provider} is not supported.`);
|
|
59
71
|
}
|
|
60
72
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { StatelogClient } from "../statelogClient.js";
|
|
2
|
-
import { PromptConfig, PromptResult, Result, SmolClient,
|
|
2
|
+
import { PromptConfig, PromptResult, ResolvedSmolConfig, Result, SmolClient, StreamChunk } from "../types.js";
|
|
3
3
|
export declare class BaseClient implements SmolClient {
|
|
4
|
-
protected config:
|
|
4
|
+
protected config: ResolvedSmolConfig;
|
|
5
5
|
protected statelogClient?: StatelogClient;
|
|
6
|
-
constructor(config:
|
|
6
|
+
constructor(config: ResolvedSmolConfig);
|
|
7
7
|
protected getAbortSignal(promptConfig: PromptConfig): AbortSignal | undefined;
|
|
8
8
|
protected isAbortError(err: unknown): boolean;
|
|
9
9
|
text(promptConfig: Omit<PromptConfig, "stream">): Promise<Result<PromptResult>>;
|
|
@@ -24,10 +24,9 @@ export declare class BaseClient implements SmolClient {
|
|
|
24
24
|
continue: boolean;
|
|
25
25
|
newPromptConfig: PromptConfig;
|
|
26
26
|
};
|
|
27
|
-
extractResponse(promptConfig: PromptConfig, rawValue: any, schema: any): any;
|
|
27
|
+
extractResponse(promptConfig: PromptConfig, rawValue: any, schema: any, depth?: number): any;
|
|
28
28
|
textWithRetry(promptConfig: PromptConfig, retries: number): Promise<Result<PromptResult>>;
|
|
29
29
|
_textSync(promptConfig: PromptConfig): Promise<Result<PromptResult>>;
|
|
30
|
-
prompt(text: string, promptConfig?: PromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
31
30
|
textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
32
31
|
_textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
33
32
|
}
|