smoltalk 0.0.60 → 0.0.61
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/functions.js +2 -4
- package/dist/strategies/baseStrategy.d.ts +11 -3
- package/dist/strategies/baseStrategy.js +25 -3
- package/dist/strategies/fastestStrategy.d.ts +3 -1
- package/dist/strategies/fastestStrategy.js +32 -26
- package/dist/strategies/idStrategy.d.ts +3 -1
- package/dist/strategies/idStrategy.js +12 -4
- package/dist/strategies/raceStrategy.d.ts +2 -2
- package/dist/strategies/randomStrategy.d.ts +2 -1
- package/dist/strategies/randomStrategy.js +8 -0
- package/dist/strategies/types.d.ts +4 -3
- package/package.json +1 -1
package/dist/functions.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getClient } from "./client.js";
|
|
2
1
|
import { Model } from "./model.js";
|
|
3
2
|
import { BaseStrategy } from "./strategies/baseStrategy.js";
|
|
4
3
|
import { fromJSON } from "./strategies/index.js";
|
|
@@ -38,7 +37,6 @@ export function textSync(config) {
|
|
|
38
37
|
return strategy.textSync(config);
|
|
39
38
|
}
|
|
40
39
|
export function textStream(config) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
return client.textStream(promptConfig);
|
|
40
|
+
const strategy = getStrategy(config.model);
|
|
41
|
+
return strategy.textStream(config);
|
|
44
42
|
}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { StatelogClient } from "../statelogClient.js";
|
|
2
|
-
import { PromptResult, Result, SmolPromptConfig } from "../types.js";
|
|
2
|
+
import { PromptResult, Result, SmolPromptConfig, StreamChunk } from "../types.js";
|
|
3
3
|
import { Strategy, StrategyJSON } from "./types.js";
|
|
4
4
|
export declare class BaseStrategy implements Strategy {
|
|
5
5
|
statelogClient?: StatelogClient;
|
|
6
|
-
text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
6
|
+
text(config: Omit<SmolPromptConfig, "stream">): Promise<Result<PromptResult>>;
|
|
7
|
+
text(config: Omit<SmolPromptConfig, "stream"> & {
|
|
8
|
+
stream: false;
|
|
9
|
+
}): Promise<Result<PromptResult>>;
|
|
10
|
+
text(config: Omit<SmolPromptConfig, "stream"> & {
|
|
11
|
+
stream: true;
|
|
12
|
+
}): AsyncGenerator<StreamChunk>;
|
|
13
|
+
text(config: SmolPromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
7
14
|
textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
8
|
-
textStream(config: SmolPromptConfig):
|
|
15
|
+
textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
9
16
|
_text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
10
17
|
_textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
18
|
+
_textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
11
19
|
toJSON(): StrategyJSON;
|
|
12
20
|
toString(): string;
|
|
13
21
|
toShortString(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getStatelogClient } from "../statelogClient.js";
|
|
2
2
|
export class BaseStrategy {
|
|
3
3
|
statelogClient;
|
|
4
|
-
|
|
4
|
+
text(config) {
|
|
5
5
|
this.statelogClient = config.statelog
|
|
6
6
|
? getStatelogClient(config.statelog)
|
|
7
7
|
: undefined;
|
|
@@ -10,6 +10,9 @@ export class BaseStrategy {
|
|
|
10
10
|
this.statelogClient?.debug(`Calling onStrategyStart hook for strategy ${this.toString()}`);
|
|
11
11
|
config.hooks.onStrategyStart(this, config);
|
|
12
12
|
}
|
|
13
|
+
if (config.stream) {
|
|
14
|
+
return this.textStream(config);
|
|
15
|
+
}
|
|
13
16
|
return this._text(config);
|
|
14
17
|
}
|
|
15
18
|
async textSync(config) {
|
|
@@ -19,8 +22,12 @@ export class BaseStrategy {
|
|
|
19
22
|
this.statelogClient?.debug(`Starting strategy (sync) ${this.toString()}`);
|
|
20
23
|
return this._textSync(config);
|
|
21
24
|
}
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
textStream(config) {
|
|
26
|
+
this.statelogClient = config.statelog
|
|
27
|
+
? getStatelogClient(config.statelog)
|
|
28
|
+
: undefined;
|
|
29
|
+
this.statelogClient?.debug(`Starting strategy (stream) ${this.toString()}`);
|
|
30
|
+
return this._textStream(config);
|
|
24
31
|
}
|
|
25
32
|
async _text(config) {
|
|
26
33
|
throw new Error("_text method not implemented.");
|
|
@@ -28,6 +35,21 @@ export class BaseStrategy {
|
|
|
28
35
|
async _textSync(config) {
|
|
29
36
|
throw new Error("_textSync method not implemented.");
|
|
30
37
|
}
|
|
38
|
+
async *_textStream(config) {
|
|
39
|
+
const result = await this._textSync(config);
|
|
40
|
+
if (result.success) {
|
|
41
|
+
if (result.value.output) {
|
|
42
|
+
yield { type: "text", text: result.value.output };
|
|
43
|
+
}
|
|
44
|
+
for (const tc of result.value.toolCalls) {
|
|
45
|
+
yield { type: "tool_call", toolCall: tc };
|
|
46
|
+
}
|
|
47
|
+
yield { type: "done", result: result.value };
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
yield { type: "error", error: result.error };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
31
53
|
toJSON() {
|
|
32
54
|
throw new Error("toJSON method not implemented.");
|
|
33
55
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Model } from "../model.js";
|
|
2
|
-
import { PromptResult, Result, SmolPromptConfig } from "../types.js";
|
|
2
|
+
import { PromptResult, Result, SmolPromptConfig, StreamChunk } from "../types.js";
|
|
3
3
|
import { BaseStrategy } from "./baseStrategy.js";
|
|
4
4
|
import { StrategyJSON } from "./types.js";
|
|
5
5
|
export declare class FastestStrategy extends BaseStrategy {
|
|
@@ -8,7 +8,9 @@ export declare class FastestStrategy extends BaseStrategy {
|
|
|
8
8
|
constructor(models: (string | Model)[], epsilon?: number);
|
|
9
9
|
toString(): string;
|
|
10
10
|
toShortString(): string;
|
|
11
|
+
private chooseModel;
|
|
11
12
|
_text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
13
|
+
_textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
12
14
|
private pickFastest;
|
|
13
15
|
/** Get tokens/sec for a model: tracked latency first, then static estimate, then 0. */
|
|
14
16
|
private getSpeed;
|
|
@@ -20,47 +20,53 @@ export class FastestStrategy extends BaseStrategy {
|
|
|
20
20
|
toShortString() {
|
|
21
21
|
return `fastest([${this.models.map((s) => s.toString()).join(", ")}])`;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
chooseModel(config) {
|
|
24
24
|
const resolved = this.models.map((model) => Model.create(model));
|
|
25
|
-
let chosen = null;
|
|
26
25
|
const logger = getLogger(config.logLevel);
|
|
27
26
|
if (Math.random() < this.epsilon) {
|
|
28
27
|
// Explore: pick a random model
|
|
29
|
-
chosen = resolved[Math.floor(Math.random() * resolved.length)];
|
|
28
|
+
const chosen = resolved[Math.floor(Math.random() * resolved.length)];
|
|
30
29
|
logger.debug("fastest strategy - exploring random model", {
|
|
31
30
|
model: chosen.getResolvedModel(),
|
|
32
31
|
});
|
|
33
32
|
this.statelogClient?.debug("fastest strategy - picking random model", {
|
|
34
33
|
model: chosen.getResolvedModel(),
|
|
35
34
|
});
|
|
35
|
+
return chosen;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
// we don't have latency data for any model, so just pick randomly
|
|
50
|
-
chosen = resolved[Math.floor(Math.random() * resolved.length)];
|
|
51
|
-
logger.debug("fastest strategy - no latency data, picking random model", {
|
|
52
|
-
models: resolved.map((m) => m.getResolvedModel()),
|
|
53
|
-
chosen: chosen.getResolvedModel(),
|
|
54
|
-
});
|
|
55
|
-
this.statelogClient?.debug("fastest strategy - no latency data, picking random model", {
|
|
56
|
-
models: resolved.map((m) => m.getResolvedModel()),
|
|
57
|
-
chosen,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
37
|
+
// Exploit: pick the fastest model by tracked latency
|
|
38
|
+
const fastest = this.pickFastest(resolved);
|
|
39
|
+
if (fastest) {
|
|
40
|
+
logger.debug("fastest strategy - exploiting fastest model", {
|
|
41
|
+
model: fastest.getResolvedModel(),
|
|
42
|
+
});
|
|
43
|
+
this.statelogClient?.debug("fastest strategy - using fastest model", {
|
|
44
|
+
model: fastest.getResolvedModel(),
|
|
45
|
+
});
|
|
46
|
+
return fastest;
|
|
60
47
|
}
|
|
48
|
+
// we don't have latency data for any model, so just pick randomly
|
|
49
|
+
const chosen = resolved[Math.floor(Math.random() * resolved.length)];
|
|
50
|
+
logger.debug("fastest strategy - no latency data, picking random model", {
|
|
51
|
+
models: resolved.map((m) => m.getResolvedModel()),
|
|
52
|
+
chosen: chosen.getResolvedModel(),
|
|
53
|
+
});
|
|
54
|
+
this.statelogClient?.debug("fastest strategy - no latency data, picking random model", {
|
|
55
|
+
models: resolved.map((m) => m.getResolvedModel()),
|
|
56
|
+
chosen,
|
|
57
|
+
});
|
|
58
|
+
return chosen;
|
|
59
|
+
}
|
|
60
|
+
async _text(config) {
|
|
61
|
+
const chosen = this.chooseModel(config);
|
|
61
62
|
const strategy = new IDStrategy(chosen);
|
|
62
63
|
return strategy.text(config);
|
|
63
64
|
}
|
|
65
|
+
async *_textStream(config) {
|
|
66
|
+
const chosen = this.chooseModel(config);
|
|
67
|
+
const strategy = new IDStrategy(chosen);
|
|
68
|
+
yield* strategy.textStream(config);
|
|
69
|
+
}
|
|
64
70
|
pickFastest(models) {
|
|
65
71
|
let best = null;
|
|
66
72
|
let bestSpeed = 0;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Model } from "../model.js";
|
|
2
|
-
import { ModelLike, PromptResult, Result, SmolPromptConfig } from "../types.js";
|
|
2
|
+
import { ModelLike, PromptResult, Result, SmolPromptConfig, StreamChunk } from "../types.js";
|
|
3
3
|
import { BaseStrategy } from "./baseStrategy.js";
|
|
4
4
|
import { StrategyJSON } from "./types.js";
|
|
5
5
|
export declare class IDStrategy extends BaseStrategy {
|
|
@@ -7,8 +7,10 @@ export declare class IDStrategy extends BaseStrategy {
|
|
|
7
7
|
constructor(model: ModelLike, provider?: string);
|
|
8
8
|
toString(): string;
|
|
9
9
|
toShortString(): string;
|
|
10
|
+
private _getClientAndConfig;
|
|
10
11
|
_text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
11
12
|
_textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
13
|
+
_textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
12
14
|
toJSON(): StrategyJSON;
|
|
13
15
|
static fromJSON(json: unknown): IDStrategy;
|
|
14
16
|
}
|
|
@@ -15,10 +15,7 @@ export class IDStrategy extends BaseStrategy {
|
|
|
15
15
|
toShortString() {
|
|
16
16
|
return `id(${this.model.toString()})`;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
return this._textSync(config);
|
|
20
|
-
}
|
|
21
|
-
async _textSync(config) {
|
|
18
|
+
_getClientAndConfig(config) {
|
|
22
19
|
const configOverrides = {
|
|
23
20
|
model: this.model.getResolvedModel(),
|
|
24
21
|
provider: this.model.getProvider(),
|
|
@@ -31,8 +28,19 @@ export class IDStrategy extends BaseStrategy {
|
|
|
31
28
|
...smolConfig,
|
|
32
29
|
...configOverrides,
|
|
33
30
|
});
|
|
31
|
+
return { client, promptConfig };
|
|
32
|
+
}
|
|
33
|
+
async _text(config) {
|
|
34
|
+
return this._textSync(config);
|
|
35
|
+
}
|
|
36
|
+
async _textSync(config) {
|
|
37
|
+
const { client, promptConfig } = this._getClientAndConfig(config);
|
|
34
38
|
return client.textSync(promptConfig);
|
|
35
39
|
}
|
|
40
|
+
async *_textStream(config) {
|
|
41
|
+
const { client, promptConfig } = this._getClientAndConfig(config);
|
|
42
|
+
yield* client.textStream(promptConfig);
|
|
43
|
+
}
|
|
36
44
|
// todo: this toJSON isn't fully accurate as it resolves the model,
|
|
37
45
|
// so strategy vs strategy.fromJSON(strategy.toJSON()) won't be the same
|
|
38
46
|
toJSON() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelParam, SmolPromptConfig } from "../types.js";
|
|
1
|
+
import { ModelParam, PromptResult, SmolPromptConfig } from "../types.js";
|
|
2
2
|
import { BaseStrategy } from "./baseStrategy.js";
|
|
3
3
|
import { Strategy, StrategyJSON } from "./types.js";
|
|
4
4
|
export declare class RaceStrategy extends BaseStrategy {
|
|
@@ -6,7 +6,7 @@ export declare class RaceStrategy extends BaseStrategy {
|
|
|
6
6
|
constructor(strategies: ModelParam[]);
|
|
7
7
|
toString(): string;
|
|
8
8
|
toShortString(): string;
|
|
9
|
-
_text(config: SmolPromptConfig): Promise<import("../types.js").Failure | import("../types.js").Success<
|
|
9
|
+
_text(config: SmolPromptConfig): Promise<import("../types.js").Failure | import("../types.js").Success<PromptResult>>;
|
|
10
10
|
toJSON(): StrategyJSON;
|
|
11
11
|
static fromJSON(json: unknown): RaceStrategy;
|
|
12
12
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelParam, PromptResult, Result, SmolPromptConfig } from "../types.js";
|
|
1
|
+
import { ModelParam, PromptResult, Result, SmolPromptConfig, StreamChunk } from "../types.js";
|
|
2
2
|
import { BaseStrategy } from "./baseStrategy.js";
|
|
3
3
|
import { Strategy, StrategyJSON } from "./types.js";
|
|
4
4
|
export declare class RandomStrategy extends BaseStrategy {
|
|
@@ -7,6 +7,7 @@ export declare class RandomStrategy extends BaseStrategy {
|
|
|
7
7
|
toString(): string;
|
|
8
8
|
toShortString(): string;
|
|
9
9
|
_text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
10
|
+
_textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
10
11
|
toJSON(): StrategyJSON;
|
|
11
12
|
static fromJSON(json: unknown): RandomStrategy;
|
|
12
13
|
}
|
|
@@ -23,6 +23,14 @@ export class RandomStrategy extends BaseStrategy {
|
|
|
23
23
|
const result = await strategy.text(config);
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
26
|
+
async *_textStream(config) {
|
|
27
|
+
const randomIndex = Math.floor(Math.random() * this.strategies.length);
|
|
28
|
+
const strategy = this.strategies[randomIndex];
|
|
29
|
+
this.statelogClient?.debug("random strategy chosen (stream)", {
|
|
30
|
+
strategy,
|
|
31
|
+
});
|
|
32
|
+
yield* strategy.textStream(config);
|
|
33
|
+
}
|
|
26
34
|
toJSON() {
|
|
27
35
|
return {
|
|
28
36
|
type: "random",
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { SmolPromptConfig, Result, PromptResult } from "../types.js";
|
|
2
|
+
import { SmolPromptConfig, Result, PromptResult, StreamChunk } from "../types.js";
|
|
3
3
|
export interface Strategy {
|
|
4
|
-
text(config: SmolPromptConfig): Promise<Result<PromptResult
|
|
4
|
+
text(config: SmolPromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
|
|
5
5
|
_text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
6
6
|
textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
7
7
|
_textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
|
|
8
|
-
textStream(config: SmolPromptConfig):
|
|
8
|
+
textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
9
|
+
_textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
|
|
9
10
|
toJSON(): StrategyJSON;
|
|
10
11
|
toString(): string;
|
|
11
12
|
toShortString(): string;
|