smoltalk 0.0.15 → 0.0.17
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 +1 -0
- package/dist/classes/message/AssistantMessage.js +3 -0
- package/dist/classes/message/DeveloperMessage.d.ts +1 -0
- package/dist/classes/message/DeveloperMessage.js +3 -0
- package/dist/classes/message/SystemMessage.d.ts +1 -0
- package/dist/classes/message/SystemMessage.js +3 -0
- package/dist/classes/message/ToolMessage.d.ts +1 -0
- package/dist/classes/message/ToolMessage.js +3 -0
- package/dist/classes/message/UserMessage.d.ts +1 -0
- package/dist/classes/message/UserMessage.js +3 -0
- package/dist/clients/baseClient.d.ts +14 -4
- package/dist/clients/baseClient.js +38 -5
- package/dist/clients/google.d.ts +1 -1
- package/dist/clients/google.js +3 -4
- package/dist/clients/ollama.d.ts +1 -1
- package/dist/clients/ollama.js +1 -1
- package/dist/clients/openai.d.ts +4 -2
- package/dist/clients/openai.js +58 -2
- package/dist/types.d.ts +20 -3
- package/package.json +3 -2
|
@@ -20,6 +20,7 @@ export declare class AssistantMessage extends BaseMessage implements MessageClas
|
|
|
20
20
|
rawData?: any;
|
|
21
21
|
});
|
|
22
22
|
get content(): string;
|
|
23
|
+
set content(value: string);
|
|
23
24
|
get role(): "assistant";
|
|
24
25
|
get name(): string | undefined;
|
|
25
26
|
get audio(): any | null | undefined;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { PromptConfig, PromptResult, Result, SmolClient, SmolConfig } from "../types.js";
|
|
1
|
+
import { PromptConfig, PromptResult, Result, SmolClient, SmolConfig, StreamChunk } from "../types.js";
|
|
2
2
|
export declare class BaseClient implements SmolClient {
|
|
3
3
|
protected config: SmolConfig;
|
|
4
4
|
constructor(config: SmolConfig);
|
|
5
|
-
text(promptConfig: PromptConfig): Promise<Result<PromptResult>>;
|
|
5
|
+
text(promptConfig: Omit<PromptConfig, "stream">): Promise<Result<PromptResult>>;
|
|
6
|
+
text(promptConfig: Omit<PromptConfig, "stream"> & {
|
|
7
|
+
stream: false;
|
|
8
|
+
}): Promise<Result<PromptResult>>;
|
|
9
|
+
text(promptConfig: Omit<PromptConfig, "stream"> & {
|
|
10
|
+
stream: true;
|
|
11
|
+
}): AsyncGenerator<StreamChunk>;
|
|
12
|
+
text(promptConfig: PromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
13
|
+
textSync(promptConfig: PromptConfig): Promise<Result<PromptResult>>;
|
|
6
14
|
checkForToolLoops(promptConfig: PromptConfig): {
|
|
7
15
|
continue: boolean;
|
|
8
16
|
newPromptConfig: PromptConfig;
|
|
9
17
|
};
|
|
10
18
|
textWithRetry(promptConfig: PromptConfig, retries: number): Promise<Result<PromptResult>>;
|
|
11
|
-
|
|
12
|
-
prompt(text: string, promptConfig?: PromptConfig): Promise<Result<PromptResult
|
|
19
|
+
_textSync(promptConfig: PromptConfig): Promise<Result<PromptResult>>;
|
|
20
|
+
prompt(text: string, promptConfig?: PromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
21
|
+
textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
22
|
+
_textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
13
23
|
}
|
|
@@ -6,7 +6,15 @@ export class BaseClient {
|
|
|
6
6
|
constructor(config) {
|
|
7
7
|
this.config = config || {};
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
text(promptConfig) {
|
|
10
|
+
if (promptConfig.stream) {
|
|
11
|
+
return this.textStream(promptConfig);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return this.textSync(promptConfig);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async textSync(promptConfig) {
|
|
10
18
|
const { continue: shouldContinue, newPromptConfig } = this.checkForToolLoops(promptConfig);
|
|
11
19
|
if (!shouldContinue) {
|
|
12
20
|
return { success: true, value: { output: null, toolCalls: [] } };
|
|
@@ -52,7 +60,7 @@ export class BaseClient {
|
|
|
52
60
|
return { continue: true, newPromptConfig: promptConfig };
|
|
53
61
|
}
|
|
54
62
|
async textWithRetry(promptConfig, retries) {
|
|
55
|
-
const result = await this.
|
|
63
|
+
const result = await this._textSync(promptConfig);
|
|
56
64
|
if (result.success) {
|
|
57
65
|
const { output } = result.value;
|
|
58
66
|
if (output !== null &&
|
|
@@ -72,10 +80,10 @@ export class BaseClient {
|
|
|
72
80
|
}
|
|
73
81
|
return result;
|
|
74
82
|
}
|
|
75
|
-
async
|
|
83
|
+
async _textSync(promptConfig) {
|
|
76
84
|
throw new Error("Method not implemented.");
|
|
77
85
|
}
|
|
78
|
-
|
|
86
|
+
prompt(text, promptConfig) {
|
|
79
87
|
const msg = userMessage(text);
|
|
80
88
|
const newPromptConfig = {
|
|
81
89
|
...promptConfig,
|
|
@@ -83,6 +91,31 @@ export class BaseClient {
|
|
|
83
91
|
? [...promptConfig.messages, msg]
|
|
84
92
|
: [msg],
|
|
85
93
|
};
|
|
86
|
-
return
|
|
94
|
+
return this.text(newPromptConfig);
|
|
95
|
+
}
|
|
96
|
+
async *textStream(config) {
|
|
97
|
+
const { continue: shouldContinue, newPromptConfig } = this.checkForToolLoops(config);
|
|
98
|
+
if (!shouldContinue) {
|
|
99
|
+
yield { type: "done", result: { output: null, toolCalls: [] } };
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
yield* this._textStream(newPromptConfig);
|
|
103
|
+
}
|
|
104
|
+
// default implementation of text stream just calls the non-streaming version and yields the result
|
|
105
|
+
// clients that support streaming can override this to provide a streaming implementation
|
|
106
|
+
async *_textStream(config) {
|
|
107
|
+
const result = await this._textSync(config);
|
|
108
|
+
if (result.success) {
|
|
109
|
+
if (result.value.output) {
|
|
110
|
+
yield { type: "text", text: result.value.output };
|
|
111
|
+
}
|
|
112
|
+
for (const tc of result.value.toolCalls) {
|
|
113
|
+
yield { type: "tool_call", toolCall: tc };
|
|
114
|
+
}
|
|
115
|
+
yield { type: "done", result: result.value };
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
yield { type: "error", error: result.error };
|
|
119
|
+
}
|
|
87
120
|
}
|
|
88
121
|
}
|
package/dist/clients/google.d.ts
CHANGED
|
@@ -9,5 +9,5 @@ export declare class SmolGoogle extends BaseClient implements SmolClient {
|
|
|
9
9
|
constructor(config: SmolGoogleConfig);
|
|
10
10
|
getClient(): GoogleGenAI;
|
|
11
11
|
getModel(): string;
|
|
12
|
-
|
|
12
|
+
_textSync(config: PromptConfig): Promise<Result<PromptResult>>;
|
|
13
13
|
}
|
package/dist/clients/google.js
CHANGED
|
@@ -23,7 +23,7 @@ export class SmolGoogle extends BaseClient {
|
|
|
23
23
|
getModel() {
|
|
24
24
|
return this.model;
|
|
25
25
|
}
|
|
26
|
-
async
|
|
26
|
+
async _textSync(config) {
|
|
27
27
|
const messages = config.messages.map((msg) => msg.toGoogleMessage());
|
|
28
28
|
const tools = (config.tools || []).map((tool) => {
|
|
29
29
|
return zodToGoogleTool(tool.name, tool.schema, {
|
|
@@ -42,10 +42,9 @@ export class SmolGoogle extends BaseClient {
|
|
|
42
42
|
contents: messages,
|
|
43
43
|
model: this.model,
|
|
44
44
|
config: genConfig,
|
|
45
|
+
stream: config.stream || false,
|
|
46
|
+
...(config.rawAttributes || {}),
|
|
45
47
|
};
|
|
46
|
-
if (config.rawAttributes) {
|
|
47
|
-
Object.assign(request, config.rawAttributes);
|
|
48
|
-
}
|
|
49
48
|
this.logger.debug("Sending request to Google Gemini:", JSON.stringify(request, null, 2));
|
|
50
49
|
// Send the prompt as the latest message
|
|
51
50
|
const result = await this.client.models.generateContent(request);
|
package/dist/clients/ollama.d.ts
CHANGED
|
@@ -10,5 +10,5 @@ export declare class SmolOllama extends BaseClient implements SmolClient {
|
|
|
10
10
|
constructor(config: SmolOllamaConfig);
|
|
11
11
|
getClient(): Ollama;
|
|
12
12
|
getModel(): string;
|
|
13
|
-
|
|
13
|
+
_textSync(config: PromptConfig): Promise<Result<PromptResult>>;
|
|
14
14
|
}
|
package/dist/clients/ollama.js
CHANGED
|
@@ -30,7 +30,7 @@ export class SmolOllama extends BaseClient {
|
|
|
30
30
|
getModel() {
|
|
31
31
|
return this.model;
|
|
32
32
|
}
|
|
33
|
-
async
|
|
33
|
+
async _textSync(config) {
|
|
34
34
|
const messages = config.messages.map((msg) => msg.toOpenAIMessage());
|
|
35
35
|
const tools = (config.tools || []).map((tool) => {
|
|
36
36
|
return zodToGoogleTool(tool.name, tool.schema, {
|
package/dist/clients/openai.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
|
-
import { BaseClientConfig, PromptConfig, PromptResult, Result, SmolClient } from "../types.js";
|
|
2
|
+
import { BaseClientConfig, PromptConfig, PromptResult, Result, SmolClient, StreamChunk } from "../types.js";
|
|
3
3
|
import { BaseClient } from "./baseClient.js";
|
|
4
4
|
export type SmolOpenAiConfig = BaseClientConfig;
|
|
5
5
|
export declare class SmolOpenAi extends BaseClient implements SmolClient {
|
|
@@ -9,5 +9,7 @@ export declare class SmolOpenAi extends BaseClient implements SmolClient {
|
|
|
9
9
|
constructor(config: SmolOpenAiConfig);
|
|
10
10
|
getClient(): OpenAI;
|
|
11
11
|
getModel(): string;
|
|
12
|
-
|
|
12
|
+
private buildRequest;
|
|
13
|
+
_textSync(config: PromptConfig): Promise<Result<PromptResult>>;
|
|
14
|
+
_textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
13
15
|
}
|
package/dist/clients/openai.js
CHANGED
|
@@ -24,7 +24,7 @@ export class SmolOpenAi extends BaseClient {
|
|
|
24
24
|
getModel() {
|
|
25
25
|
return this.model;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
buildRequest(config) {
|
|
28
28
|
const messages = config.messages.map((msg) => msg.toOpenAIMessage());
|
|
29
29
|
const request = {
|
|
30
30
|
model: this.model,
|
|
@@ -34,6 +34,7 @@ export class SmolOpenAi extends BaseClient {
|
|
|
34
34
|
description: tool.description,
|
|
35
35
|
});
|
|
36
36
|
}),
|
|
37
|
+
...(config.rawAttributes || {}),
|
|
37
38
|
};
|
|
38
39
|
if (config.responseFormat) {
|
|
39
40
|
request.response_format = {
|
|
@@ -44,8 +45,15 @@ export class SmolOpenAi extends BaseClient {
|
|
|
44
45
|
},
|
|
45
46
|
};
|
|
46
47
|
}
|
|
48
|
+
return request;
|
|
49
|
+
}
|
|
50
|
+
async _textSync(config) {
|
|
51
|
+
const request = this.buildRequest(config);
|
|
47
52
|
this.logger.debug("Sending request to OpenAI:", JSON.stringify(request, null, 2));
|
|
48
|
-
const completion = await this.client.chat.completions.create(
|
|
53
|
+
const completion = await this.client.chat.completions.create({
|
|
54
|
+
...request,
|
|
55
|
+
stream: false,
|
|
56
|
+
});
|
|
49
57
|
this.logger.debug("Response from OpenAI:", JSON.stringify(completion, null, 2));
|
|
50
58
|
const message = completion.choices[0].message;
|
|
51
59
|
const output = message.content;
|
|
@@ -63,4 +71,52 @@ export class SmolOpenAi extends BaseClient {
|
|
|
63
71
|
}
|
|
64
72
|
return success({ output, toolCalls });
|
|
65
73
|
}
|
|
74
|
+
async *_textStream(config) {
|
|
75
|
+
const request = this.buildRequest(config);
|
|
76
|
+
this.logger.debug("Sending streaming request to OpenAI:", JSON.stringify(request, null, 2));
|
|
77
|
+
const completion = await this.client.chat.completions.create({
|
|
78
|
+
...request,
|
|
79
|
+
stream: true,
|
|
80
|
+
});
|
|
81
|
+
let content = "";
|
|
82
|
+
const toolCallsMap = new Map();
|
|
83
|
+
for await (const chunk of completion) {
|
|
84
|
+
const delta = chunk.choices[0]?.delta;
|
|
85
|
+
if (!delta)
|
|
86
|
+
continue;
|
|
87
|
+
if (delta.content) {
|
|
88
|
+
content += delta.content;
|
|
89
|
+
yield { type: "text", text: delta.content };
|
|
90
|
+
}
|
|
91
|
+
if (delta.tool_calls) {
|
|
92
|
+
for (const tc of delta.tool_calls) {
|
|
93
|
+
const index = tc.index;
|
|
94
|
+
if (!toolCallsMap.has(index)) {
|
|
95
|
+
toolCallsMap.set(index, {
|
|
96
|
+
id: tc.id || "",
|
|
97
|
+
name: tc.function?.name || "",
|
|
98
|
+
arguments: tc.function?.arguments || "",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const existing = toolCallsMap.get(index);
|
|
103
|
+
if (tc.id)
|
|
104
|
+
existing.id = tc.id;
|
|
105
|
+
if (tc.function?.name)
|
|
106
|
+
existing.name = tc.function.name;
|
|
107
|
+
if (tc.function?.arguments)
|
|
108
|
+
existing.arguments += tc.function.arguments;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
this.logger.debug("Streaming response completed from OpenAI");
|
|
114
|
+
const toolCalls = [];
|
|
115
|
+
for (const tc of toolCallsMap.values()) {
|
|
116
|
+
const toolCall = new ToolCall(tc.id, tc.name, tc.arguments);
|
|
117
|
+
toolCalls.push(toolCall);
|
|
118
|
+
yield { type: "tool_call", toolCall };
|
|
119
|
+
}
|
|
120
|
+
yield { type: "done", result: { output: content || null, toolCalls } };
|
|
121
|
+
}
|
|
66
122
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type PromptConfig = {
|
|
|
18
18
|
numSuggestions?: number;
|
|
19
19
|
parallelToolCalls?: boolean;
|
|
20
20
|
responseFormat?: ZodType;
|
|
21
|
+
stream?: boolean;
|
|
21
22
|
responseFormatOptions?: Partial<{
|
|
22
23
|
name: string;
|
|
23
24
|
strict: boolean;
|
|
@@ -46,10 +47,26 @@ export type PromptResult = {
|
|
|
46
47
|
output: string | null;
|
|
47
48
|
toolCalls: ToolCall[];
|
|
48
49
|
};
|
|
50
|
+
export type StreamChunk = {
|
|
51
|
+
type: "text";
|
|
52
|
+
text: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: "tool_call";
|
|
55
|
+
toolCall: ToolCall;
|
|
56
|
+
} | {
|
|
57
|
+
type: "done";
|
|
58
|
+
result: PromptResult;
|
|
59
|
+
} | {
|
|
60
|
+
type: "error";
|
|
61
|
+
error: string;
|
|
62
|
+
};
|
|
49
63
|
export interface SmolClient {
|
|
50
|
-
text(
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
text(promptConfig: PromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
65
|
+
textSync(config: PromptConfig): Promise<Result<PromptResult>>;
|
|
66
|
+
_textSync(config: PromptConfig): Promise<Result<PromptResult>>;
|
|
67
|
+
textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
68
|
+
_textStream(config: PromptConfig): AsyncGenerator<StreamChunk>;
|
|
69
|
+
prompt(text: string, config?: PromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
53
70
|
}
|
|
54
71
|
export type TextPart = {
|
|
55
72
|
type: "text";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smoltalk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "A common interface for LLM APIs",
|
|
5
5
|
"homepage": "https://github.com/egonSchiele/smoltalk",
|
|
6
6
|
"scripts": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"coverage": "vitest --coverage",
|
|
10
10
|
"build": "rm -rf dist && tsc",
|
|
11
11
|
"start": "cd dist && node index.js",
|
|
12
|
-
"doc": "typedoc --disableSources --out docs lib && prettier docs/ --write"
|
|
12
|
+
"doc": "typedoc --disableSources --out docs lib && prettier docs/ --write",
|
|
13
|
+
"typecheck": "tsc --noEmit"
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
15
16
|
"./dist"
|