smoltalk 0.0.67 → 0.2.2

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.
Files changed (53) hide show
  1. package/README.md +51 -154
  2. package/dist/client.d.ts +3 -3
  3. package/dist/client.js +9 -5
  4. package/dist/clients/anthropic.d.ts +4 -4
  5. package/dist/clients/anthropic.js +1 -1
  6. package/dist/clients/baseClient.d.ts +17 -20
  7. package/dist/clients/baseClient.js +11 -31
  8. package/dist/clients/google.d.ts +4 -4
  9. package/dist/clients/google.js +1 -1
  10. package/dist/clients/ollama.d.ts +4 -4
  11. package/dist/clients/ollama.js +1 -1
  12. package/dist/clients/openai.d.ts +4 -4
  13. package/dist/clients/openai.js +1 -1
  14. package/dist/clients/openaiResponses.d.ts +4 -4
  15. package/dist/clients/openaiResponses.js +1 -1
  16. package/dist/functions.d.ts +5 -10
  17. package/dist/functions.js +4 -55
  18. package/dist/index.d.ts +2 -4
  19. package/dist/index.js +1 -2
  20. package/dist/model.d.ts +2 -5
  21. package/dist/model.js +11 -27
  22. package/dist/models.d.ts +2 -2
  23. package/dist/models.js +3 -1
  24. package/dist/testing/index.d.ts +9 -0
  25. package/dist/testing/index.js +41 -0
  26. package/dist/types.d.ts +49 -157
  27. package/dist/util/logger.d.ts +17 -1
  28. package/dist/util/logger.js +68 -5
  29. package/package.json +15 -19
  30. package/dist/clients/llamaCpp.d.ts +0 -28
  31. package/dist/clients/llamaCpp.js +0 -316
  32. package/dist/latencyTracker.d.ts +0 -32
  33. package/dist/latencyTracker.js +0 -73
  34. package/dist/middleware.d.ts +0 -54
  35. package/dist/middleware.js +0 -321
  36. package/dist/strategies/baseStrategy.d.ts +0 -22
  37. package/dist/strategies/baseStrategy.js +0 -62
  38. package/dist/strategies/fallbackStrategy.d.ts +0 -14
  39. package/dist/strategies/fallbackStrategy.js +0 -122
  40. package/dist/strategies/fastestStrategy.d.ts +0 -19
  41. package/dist/strategies/fastestStrategy.js +0 -108
  42. package/dist/strategies/idStrategy.d.ts +0 -16
  43. package/dist/strategies/idStrategy.js +0 -62
  44. package/dist/strategies/index.d.ts +0 -17
  45. package/dist/strategies/index.js +0 -68
  46. package/dist/strategies/raceStrategy.d.ts +0 -12
  47. package/dist/strategies/raceStrategy.js +0 -72
  48. package/dist/strategies/randomStrategy.d.ts +0 -13
  49. package/dist/strategies/randomStrategy.js +0 -54
  50. package/dist/strategies/timeoutStrategy.d.ts +0 -13
  51. package/dist/strategies/timeoutStrategy.js +0 -65
  52. package/dist/strategies/types.d.ts +0 -78
  53. package/dist/strategies/types.js +0 -58
@@ -1,16 +0,0 @@
1
- import { Model } from "../model.js";
2
- import { ModelLike, PromptResult, Result, SmolPromptConfig, StreamChunk } from "../types.js";
3
- import { BaseStrategy } from "./baseStrategy.js";
4
- import { StrategyJSON } from "./types.js";
5
- export declare class IDStrategy extends BaseStrategy {
6
- model: Model;
7
- constructor(model: ModelLike, provider?: string);
8
- toString(): string;
9
- toShortString(): string;
10
- private _getClientAndConfig;
11
- _text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
12
- _textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
13
- _textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
14
- toJSON(): StrategyJSON;
15
- static fromJSON(json: unknown): IDStrategy;
16
- }
@@ -1,62 +0,0 @@
1
- import { getClient } from "../client.js";
2
- import { splitConfig } from "../functions.js";
3
- import { Model } from "../model.js";
4
- import { BaseStrategy } from "./baseStrategy.js";
5
- import { IDStrategyJSONSchema, } from "./types.js";
6
- export class IDStrategy extends BaseStrategy {
7
- model;
8
- constructor(model, provider) {
9
- super();
10
- this.model = Model.create(model, provider);
11
- }
12
- toString() {
13
- return `IDStrategy(${this.model.toString()})`;
14
- }
15
- toShortString() {
16
- return `id(${this.model.toString()})`;
17
- }
18
- _getClientAndConfig(config) {
19
- const configOverrides = {
20
- model: this.model.getResolvedModel(),
21
- provider: this.model.getProvider(),
22
- };
23
- const { smolConfig, promptConfig } = splitConfig({
24
- ...config,
25
- ...configOverrides,
26
- });
27
- const client = getClient({
28
- ...smolConfig,
29
- ...configOverrides,
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);
38
- return client.textSync(promptConfig);
39
- }
40
- async *_textStream(config) {
41
- const { client, promptConfig } = this._getClientAndConfig(config);
42
- yield* client.textStream(promptConfig);
43
- }
44
- // todo: this toJSON isn't fully accurate as it resolves the model,
45
- // so strategy vs strategy.fromJSON(strategy.toJSON()) won't be the same
46
- toJSON() {
47
- return {
48
- type: "id",
49
- params: {
50
- model: this.model.getResolvedModel(),
51
- provider: this.model.getProvider(),
52
- },
53
- };
54
- }
55
- static fromJSON(json) {
56
- const parsed = IDStrategyJSONSchema.safeParse(json);
57
- if (parsed.success) {
58
- return new IDStrategy(parsed.data.params.model, parsed.data.params.provider);
59
- }
60
- throw new Error(`Invalid IDStrategy JSON: ${JSON.stringify(json)}`);
61
- }
62
- }
@@ -1,17 +0,0 @@
1
- import { Model } from "../model.js";
2
- import { ModelLike, ModelParam } from "../types.js";
3
- import { FallbackStrategyConfig, Strategy, StrategyJSON } from "./types.js";
4
- export * from "./baseStrategy.js";
5
- export * from "./fallbackStrategy.js";
6
- export * from "./idStrategy.js";
7
- export * from "./raceStrategy.js";
8
- export * from "./randomStrategy.js";
9
- export * from "./timeoutStrategy.js";
10
- export * from "./types.js";
11
- export declare function race(...strategies: ModelParam[]): Strategy;
12
- export declare function random(...strategies: ModelParam[]): Strategy;
13
- export declare function fastest(models: (string | Model)[], epsilon?: number): Strategy;
14
- export declare function id(model: ModelLike): Strategy;
15
- export declare function timeout(strategy: ModelParam, timeoutMs: number): Strategy;
16
- export declare function fallback(primaryStrategy: ModelParam, config: FallbackStrategyConfig | string | string[]): Strategy;
17
- export declare function fromJSON(json: StrategyJSON): Strategy;
@@ -1,68 +0,0 @@
1
- import { FallbackStrategy } from "./fallbackStrategy.js";
2
- import { FastestStrategy } from "./fastestStrategy.js";
3
- import { IDStrategy } from "./idStrategy.js";
4
- import { RaceStrategy } from "./raceStrategy.js";
5
- import { RandomStrategy } from "./randomStrategy.js";
6
- import { TimeoutStrategy } from "./timeoutStrategy.js";
7
- import { FallbackStrategyJSONSchema, FastestStrategyJSONSchema, IDStrategyJSONSchema, RaceStrategyJSONSchema, RandomStrategyJSONSchema, TimeoutStrategyJSONSchema, } from "./types.js";
8
- export * from "./baseStrategy.js";
9
- export * from "./fallbackStrategy.js";
10
- export * from "./idStrategy.js";
11
- export * from "./raceStrategy.js";
12
- export * from "./randomStrategy.js";
13
- export * from "./timeoutStrategy.js";
14
- export * from "./types.js";
15
- export function race(...strategies) {
16
- return new RaceStrategy(strategies);
17
- }
18
- export function random(...strategies) {
19
- return new RandomStrategy(...strategies);
20
- }
21
- export function fastest(models, epsilon) {
22
- return new FastestStrategy(models, epsilon);
23
- }
24
- export function id(model) {
25
- return new IDStrategy(model);
26
- }
27
- export function timeout(strategy, timeoutMs) {
28
- return new TimeoutStrategy(strategy, timeoutMs);
29
- }
30
- export function fallback(primaryStrategy, config) {
31
- let resolvedConfig;
32
- if (typeof config === "string") {
33
- resolvedConfig = { error: [config] };
34
- }
35
- else if (Array.isArray(config)) {
36
- resolvedConfig = { error: config };
37
- }
38
- else {
39
- resolvedConfig = config;
40
- }
41
- return new FallbackStrategy(primaryStrategy, resolvedConfig);
42
- }
43
- export function fromJSON(json) {
44
- if (IDStrategyJSONSchema.safeParse(json).success) {
45
- return IDStrategy.fromJSON(json);
46
- }
47
- else if (RaceStrategyJSONSchema.safeParse(json).success) {
48
- return RaceStrategy.fromJSON(json);
49
- }
50
- else if (FallbackStrategyJSONSchema.safeParse(json).success) {
51
- return FallbackStrategy.fromJSON(json);
52
- }
53
- else if (RandomStrategyJSONSchema.safeParse(json).success) {
54
- return RandomStrategy.fromJSON(json);
55
- }
56
- else if (FastestStrategyJSONSchema.safeParse(json).success) {
57
- return FastestStrategy.fromJSON(json);
58
- }
59
- else if (TimeoutStrategyJSONSchema.safeParse(json).success) {
60
- return TimeoutStrategy.fromJSON(json);
61
- }
62
- else if (typeof json === "string") {
63
- return id(json);
64
- }
65
- else {
66
- throw new Error(`Unknown strategy JSON: ${JSON.stringify(json)}`);
67
- }
68
- }
@@ -1,12 +0,0 @@
1
- import { ModelParam, PromptResult, SmolPromptConfig } from "../types.js";
2
- import { BaseStrategy } from "./baseStrategy.js";
3
- import { Strategy, StrategyJSON } from "./types.js";
4
- export declare class RaceStrategy extends BaseStrategy {
5
- strategies: Strategy[];
6
- constructor(strategies: ModelParam[]);
7
- toString(): string;
8
- toShortString(): string;
9
- _text(config: SmolPromptConfig): Promise<import("../types.js").Failure | import("../types.js").Success<PromptResult>>;
10
- toJSON(): StrategyJSON;
11
- static fromJSON(json: unknown): RaceStrategy;
12
- }
@@ -1,72 +0,0 @@
1
- import { z } from "zod";
2
- import { getLogger } from "../util/logger.js";
3
- import { BaseStrategy } from "./baseStrategy.js";
4
- import { fromJSON, IDStrategy } from "./index.js";
5
- import { RaceStrategyJSONSchema, } from "./types.js";
6
- export class RaceStrategy extends BaseStrategy {
7
- strategies;
8
- constructor(strategies) {
9
- super();
10
- this.strategies = strategies.map((s) => s instanceof BaseStrategy ? s : new IDStrategy(s));
11
- }
12
- toString() {
13
- return `RaceStrategy([${this.strategies.map((s) => s.toString()).join(", ")}])`;
14
- }
15
- toShortString() {
16
- return `race(${this.strategies.map((s) => s.toShortString?.() || s.toString()).join(", ")})`;
17
- }
18
- async _text(config) {
19
- const controllers = this.strategies.map(() => new AbortController());
20
- // Link to any existing abort signal so external cancellation still works
21
- if (config.abortSignal) {
22
- const external = config.abortSignal;
23
- for (const controller of controllers) {
24
- external.addEventListener("abort", () => controller.abort(external.reason), { once: true });
25
- }
26
- }
27
- const promises = this.strategies.map((strategy, i) => {
28
- return strategy.text({
29
- ...config,
30
- abortSignal: controllers[i].signal,
31
- });
32
- });
33
- let winnerIndex = null;
34
- return Promise.race(promises.map((p, i) => p.then((result) => {
35
- if (winnerIndex !== null) {
36
- // This strategy resolved after the winner (e.g. due to being aborted).
37
- // Do not attempt to abort other strategies again.
38
- return result;
39
- }
40
- winnerIndex = i;
41
- for (let j = 0; j < controllers.length; j++) {
42
- if (j !== i) {
43
- const logger = getLogger();
44
- logger.debug(`RaceStrategy: aborting strategy ${this.strategies[j]} because strategy ${this.strategies[i]} won the race.`);
45
- this.statelogClient?.debug("RaceStrategy: aborting losing strategy", {
46
- winner: this.strategies[i].toString(),
47
- aborted: this.strategies[j].toString(),
48
- });
49
- controllers[j].abort();
50
- }
51
- }
52
- return result;
53
- })));
54
- }
55
- toJSON() {
56
- return {
57
- type: "race",
58
- params: { strategies: this.strategies.map((s) => s.toJSON()) },
59
- };
60
- }
61
- static fromJSON(json) {
62
- const result = RaceStrategyJSONSchema.safeParse(json);
63
- if (!result.success) {
64
- console.error("Failed to parse RaceStrategy");
65
- console.error(JSON.stringify(json, null, 2));
66
- console.error(z.prettifyError(result.error));
67
- throw new Error("Failed to parse RaceStrategy");
68
- }
69
- const strategies = result.data.params.strategies.map((s) => fromJSON(s));
70
- return new RaceStrategy(strategies);
71
- }
72
- }
@@ -1,13 +0,0 @@
1
- import { ModelParam, PromptResult, Result, SmolPromptConfig, StreamChunk } from "../types.js";
2
- import { BaseStrategy } from "./baseStrategy.js";
3
- import { Strategy, StrategyJSON } from "./types.js";
4
- export declare class RandomStrategy extends BaseStrategy {
5
- strategies: Strategy[];
6
- constructor(...strategies: (Strategy | ModelParam)[]);
7
- toString(): string;
8
- toShortString(): string;
9
- _text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
10
- _textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
11
- toJSON(): StrategyJSON;
12
- static fromJSON(json: unknown): RandomStrategy;
13
- }
@@ -1,54 +0,0 @@
1
- import { z } from "zod";
2
- import { BaseStrategy } from "./baseStrategy.js";
3
- import { IDStrategy } from "./idStrategy.js";
4
- import { fromJSON } from "./index.js";
5
- import { RandomStrategyJSONSchema } from "./types.js";
6
- export class RandomStrategy extends BaseStrategy {
7
- strategies;
8
- constructor(...strategies) {
9
- super();
10
- this.strategies = strategies.map((s) => s instanceof BaseStrategy ? s : new IDStrategy(s));
11
- }
12
- toString() {
13
- return `RandomStrategy([${this.strategies.map((s) => s.toString()).join(", ")}])`;
14
- }
15
- toShortString() {
16
- return `random([${this.strategies.map((s) => s.toString()).join(", ")}])`;
17
- }
18
- async _text(config) {
19
- const randomIndex = Math.floor(Math.random() * this.strategies.length);
20
- const strategy = this.strategies[randomIndex];
21
- this.statelogClient?.debug("random strategy chosen", {
22
- strategy,
23
- });
24
- const result = await strategy.text(config);
25
- return result;
26
- }
27
- async *_textStream(config) {
28
- const randomIndex = Math.floor(Math.random() * this.strategies.length);
29
- const strategy = this.strategies[randomIndex];
30
- this.statelogClient?.debug("random strategy chosen (stream)", {
31
- strategy,
32
- });
33
- yield* strategy.textStream(config);
34
- }
35
- toJSON() {
36
- return {
37
- type: "random",
38
- params: {
39
- strategies: this.strategies.map((s) => s.toJSON()),
40
- },
41
- };
42
- }
43
- static fromJSON(json) {
44
- const result = RandomStrategyJSONSchema.safeParse(json);
45
- if (!result.success) {
46
- console.error("Failed to parse RandomStrategy");
47
- console.error(JSON.stringify(json, null, 2));
48
- console.error(z.prettifyError(result.error));
49
- throw new Error("Failed to parse RandomStrategy");
50
- }
51
- const strategies = result.data.params.strategies.map((s) => fromJSON(s));
52
- return new RandomStrategy(...strategies);
53
- }
54
- }
@@ -1,13 +0,0 @@
1
- import { ModelParam, PromptResult, Result, SmolPromptConfig } from "../types.js";
2
- import { BaseStrategy } from "./baseStrategy.js";
3
- import { Strategy, StrategyJSON } from "./types.js";
4
- export declare class TimeoutStrategy extends BaseStrategy {
5
- strategy: Strategy;
6
- timeoutMs: number;
7
- constructor(strategy: ModelParam, timeoutMs: number);
8
- toString(): string;
9
- toShortString(): string;
10
- _text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
11
- toJSON(): StrategyJSON;
12
- static fromJSON(json: unknown): TimeoutStrategy;
13
- }
@@ -1,65 +0,0 @@
1
- import { z } from "zod";
2
- import { SmolTimeoutError } from "../smolError.js";
3
- import { BaseStrategy } from "./baseStrategy.js";
4
- import { IDStrategy } from "./idStrategy.js";
5
- import { fromJSON } from "./index.js";
6
- import { TimeoutStrategyJSONSchema, } from "./types.js";
7
- export class TimeoutStrategy extends BaseStrategy {
8
- strategy;
9
- timeoutMs;
10
- constructor(strategy, timeoutMs) {
11
- super();
12
- this.strategy =
13
- strategy instanceof BaseStrategy
14
- ? strategy
15
- : new IDStrategy(strategy);
16
- this.timeoutMs = timeoutMs;
17
- }
18
- toString() {
19
- return `TimeoutStrategy(${this.strategy.toString()}, ${this.timeoutMs}ms)`;
20
- }
21
- toShortString() {
22
- return `timeout(${this.strategy.toShortString?.() || this.strategy.toString()}, ${this.timeoutMs}ms)`;
23
- }
24
- async _text(config) {
25
- const controller = new AbortController();
26
- // Link to any existing abort signal
27
- if (config.abortSignal) {
28
- const external = config.abortSignal;
29
- external.addEventListener("abort", () => controller.abort(external.reason), { once: true });
30
- }
31
- const timeoutPromise = new Promise((_, reject) => {
32
- const timer = setTimeout(() => {
33
- controller.abort();
34
- reject(new SmolTimeoutError(`Strategy timed out after ${this.timeoutMs}ms`));
35
- }, this.timeoutMs);
36
- // Clear timeout if the controller is aborted externally
37
- controller.signal.addEventListener("abort", () => clearTimeout(timer), { once: true });
38
- });
39
- const resultPromise = this.strategy.text({
40
- ...config,
41
- abortSignal: controller.signal,
42
- });
43
- return Promise.race([resultPromise, timeoutPromise]);
44
- }
45
- toJSON() {
46
- return {
47
- type: "timeout",
48
- params: {
49
- strategy: this.strategy.toJSON(),
50
- timeoutMs: this.timeoutMs,
51
- },
52
- };
53
- }
54
- static fromJSON(json) {
55
- const result = TimeoutStrategyJSONSchema.safeParse(json);
56
- if (!result.success) {
57
- console.error("Failed to parse TimeoutStrategy");
58
- console.error(JSON.stringify(json, null, 2));
59
- console.error(z.prettifyError(result.error));
60
- throw new Error("Failed to parse TimeoutStrategy");
61
- }
62
- const strategy = fromJSON(result.data.params.strategy);
63
- return new TimeoutStrategy(strategy, result.data.params.timeoutMs);
64
- }
65
- }
@@ -1,78 +0,0 @@
1
- import { z } from "zod";
2
- import { SmolPromptConfig, Result, PromptResult, StreamChunk } from "../types.js";
3
- export interface Strategy {
4
- text(config: SmolPromptConfig): Promise<Result<PromptResult>> | AsyncGenerator<StreamChunk>;
5
- _text(config: SmolPromptConfig): Promise<Result<PromptResult>>;
6
- textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
7
- _textSync(config: SmolPromptConfig): Promise<Result<PromptResult>>;
8
- textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
9
- _textStream(config: SmolPromptConfig): AsyncGenerator<StreamChunk>;
10
- toJSON(): StrategyJSON;
11
- toString(): string;
12
- toShortString(): string;
13
- }
14
- export declare const FallbackReasonSchema: z.ZodEnum<{
15
- error: "error";
16
- timeout: "timeout";
17
- structuredOutputFailure: "structuredOutputFailure";
18
- contentPolicyViolation: "contentPolicyViolation";
19
- contextWindowExceeded: "contextWindowExceeded";
20
- }>;
21
- export declare const FallbackStrategyConfigSchema: z.ZodLazy<z.ZodRecord<z.ZodEnum<{
22
- error: "error";
23
- timeout: "timeout";
24
- structuredOutputFailure: "structuredOutputFailure";
25
- contentPolicyViolation: "contentPolicyViolation";
26
- contextWindowExceeded: "contextWindowExceeded";
27
- }> & z.core.$partial, z.ZodArray<z.ZodType<StrategyJSON, unknown, z.core.$ZodTypeInternals<StrategyJSON, unknown>>>>>;
28
- export type FallbackReason = z.infer<typeof FallbackReasonSchema>;
29
- export type FallbackStrategyConfig = z.infer<typeof FallbackStrategyConfigSchema>;
30
- export type StrategyJSON = string | IDStrategyJSON | RaceStrategyJSON | FallbackStrategyJSON | RandomStrategyJSON | FastestStrategyJSON | TimeoutStrategyJSON;
31
- export declare const IDStrategyJSONSchema: z.ZodObject<{
32
- type: z.ZodLiteral<"id">;
33
- params: z.ZodObject<{
34
- model: z.ZodString;
35
- provider: z.ZodOptional<z.ZodString>;
36
- }, z.core.$strip>;
37
- }, z.core.$strip>;
38
- export type IDStrategyJSON = z.infer<typeof IDStrategyJSONSchema>;
39
- export declare const RaceStrategyJSONSchema: z.ZodType<RaceStrategyJSON>;
40
- export type RaceStrategyJSON = {
41
- type: "race";
42
- params: {
43
- strategies: StrategyJSON[];
44
- };
45
- };
46
- export declare const FallbackStrategyJSONSchema: z.ZodType<FallbackStrategyJSON>;
47
- export type FallbackStrategyJSON = {
48
- type: "fallback";
49
- params: {
50
- primaryStrategy: StrategyJSON;
51
- config: FallbackStrategyConfig;
52
- };
53
- };
54
- export declare const RandomStrategyJSONSchema: z.ZodType<RandomStrategyJSON>;
55
- export type RandomStrategyJSON = {
56
- type: "random";
57
- params: {
58
- strategies: StrategyJSON[];
59
- };
60
- };
61
- export declare const FastestStrategyJSONSchema: z.ZodType<FastestStrategyJSON>;
62
- export type FastestStrategyJSON = {
63
- type: "fastest";
64
- params: {
65
- models: string[];
66
- };
67
- };
68
- export declare const TimeoutStrategyJSONSchema: z.ZodType<TimeoutStrategyJSON>;
69
- export type TimeoutStrategyJSON = {
70
- type: "timeout";
71
- params: {
72
- strategy: StrategyJSON;
73
- timeoutMs: number;
74
- };
75
- };
76
- export declare const ModelNameSchema: z.ZodString;
77
- export declare const StrategyJSONSchema: z.ZodType<StrategyJSON>;
78
- export declare function isStrategy(value: unknown): value is StrategyJSON;
@@ -1,58 +0,0 @@
1
- import { z } from "zod";
2
- export const FallbackReasonSchema = z.enum([
3
- "error",
4
- "timeout",
5
- "structuredOutputFailure",
6
- "contentPolicyViolation",
7
- "contextWindowExceeded",
8
- ]);
9
- export const FallbackStrategyConfigSchema = z.lazy(() => z.partialRecord(FallbackReasonSchema, z.array(StrategyJSONSchema)));
10
- export const IDStrategyJSONSchema = z.object({
11
- type: z.literal("id"),
12
- params: z.object({ model: z.string(), provider: z.string().optional() }),
13
- });
14
- export const RaceStrategyJSONSchema = z.lazy(() => z.object({
15
- type: z.literal("race"),
16
- params: z.object({ strategies: z.array(StrategyJSONSchema) }),
17
- }));
18
- export const FallbackStrategyJSONSchema = z.lazy(() => z.object({
19
- type: z.literal("fallback"),
20
- params: z.object({
21
- primaryStrategy: StrategyJSONSchema,
22
- config: FallbackStrategyConfigSchema,
23
- }),
24
- }));
25
- export const RandomStrategyJSONSchema = z.lazy(() => z.object({
26
- type: z.literal("random"),
27
- params: z.object({ strategies: z.array(StrategyJSONSchema) }),
28
- }));
29
- export const FastestStrategyJSONSchema = z.lazy(() => z.object({
30
- type: z.literal("fastest"),
31
- params: z.object({
32
- models: z.array(z.string()),
33
- }),
34
- }));
35
- export const TimeoutStrategyJSONSchema = z.lazy(() => z.object({
36
- type: z.literal("timeout"),
37
- params: z.object({
38
- strategy: StrategyJSONSchema,
39
- timeoutMs: z.number(),
40
- }),
41
- }));
42
- export const ModelNameSchema = z
43
- .string()
44
- .regex(/^[a-zA-Z0-9._:-]+$/, "Model name must only contain letters, numbers, dots, underscores, hyphens, and colons");
45
- export const StrategyJSONSchema = z.lazy(() => z.union([
46
- ModelNameSchema,
47
- IDStrategyJSONSchema,
48
- RaceStrategyJSONSchema,
49
- FallbackStrategyJSONSchema,
50
- RandomStrategyJSONSchema,
51
- FastestStrategyJSONSchema,
52
- TimeoutStrategyJSONSchema,
53
- ]));
54
- // Helper to detect if a value is a StrategyJSON object (not a plain string)
55
- export function isStrategy(value) {
56
- const result = StrategyJSONSchema.safeParse(value);
57
- return result.success;
58
- }