@opencode/ai 2.0.11 → 2.0.13
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 +41 -0
- package/dist/experimental/evaluation-client.d.ts +21 -0
- package/dist/experimental/evaluation-client.js +28 -0
- package/dist/experimental/evaluation.d.ts +234 -0
- package/dist/experimental/evaluation.js +114 -0
- package/dist/experimental/system-one.d.ts +16 -0
- package/dist/experimental/system-one.js +143 -0
- package/dist/experimental.d.ts +3 -0
- package/dist/experimental.js +2 -0
- package/dist/providers/google-vertex.js +1 -13
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.js +2 -0
- package/dist/providers/opencode-zen.d.ts +32 -0
- package/dist/providers/opencode-zen.js +20 -0
- package/dist/providers/typesafe-ai.d.ts +32 -0
- package/dist/providers/typesafe-ai.js +20 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -29,6 +29,47 @@ await Effect.runPromise(program.pipe(Effect.provide(llmLayer)))
|
|
|
29
29
|
|
|
30
30
|
Run `LLMClient.stream(request)` instead of `generate` when you want incremental `LLMEvent`s. The event stream is provider-neutral — same shape across OpenAI Chat, OpenAI Responses, Anthropic Messages, Gemini, Bedrock Converse, and any OpenAI-compatible deployment.
|
|
31
31
|
|
|
32
|
+
## Experimental evaluation
|
|
33
|
+
|
|
34
|
+
Evaluation models compare shared state with typed choice, score, and boolean questions. The API is
|
|
35
|
+
isolated under an experimental entrypoint and provider namespace while the contract evolves:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { Effect } from "effect"
|
|
39
|
+
import { Evaluation, EvaluationClient } from "@opencode/ai/experimental"
|
|
40
|
+
import { TypeSafeAI } from "@opencode/ai/providers"
|
|
41
|
+
|
|
42
|
+
const model = TypeSafeAI.configure().experimental.evaluation("jev-latest")
|
|
43
|
+
|
|
44
|
+
const program = Evaluation.evaluate({
|
|
45
|
+
model,
|
|
46
|
+
state: "I was charged twice. Please refund the duplicate payment.",
|
|
47
|
+
questions: {
|
|
48
|
+
department: {
|
|
49
|
+
type: "choice",
|
|
50
|
+
instructions: "Which team should handle this?",
|
|
51
|
+
criteria: { billing: "Payments and refunds", technical: "Bugs and outages" },
|
|
52
|
+
},
|
|
53
|
+
urgency: {
|
|
54
|
+
type: "score",
|
|
55
|
+
instructions: "How urgent is this?",
|
|
56
|
+
criteria: ["Can wait", "Needs prompt attention", "Blocking revenue"],
|
|
57
|
+
},
|
|
58
|
+
refund: { type: "boolean", instructions: "Is the customer asking for a refund?" },
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const response = await Effect.runPromise(program.pipe(Effect.provide(EvaluationClient.fetchLayer)))
|
|
63
|
+
|
|
64
|
+
console.log(response.answers.department.choice)
|
|
65
|
+
console.log(response.answers.refund.probability)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`TypeSafeAI` reads `TYPESAFE_API_KEY`. `OpenCodeZen` exposes the same selector and reads
|
|
69
|
+
`OPENCODE_API_KEY`. The common API uses `boolean`; System One routes lower it to native `noul`.
|
|
70
|
+
Choice and score confidence plus score legends remain available in provider metadata, and the
|
|
71
|
+
provider's rounded probabilities are returned unchanged.
|
|
72
|
+
|
|
32
73
|
## Alibaba Cloud Model Studio
|
|
33
74
|
|
|
34
75
|
`Alibaba` provides standard Model Studio inference. Configure a region explicitly, then select
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { RequestExecutor } from "../route/executor.js";
|
|
3
|
+
import { type AIError } from "../schema/index.js";
|
|
4
|
+
import { type EvaluationOptions, type EvaluationQuestions, type EvaluationRequestFor, type EvaluationResponseFor } from "./evaluation.js";
|
|
5
|
+
export type Execute = RequestExecutor.Interface["execute"];
|
|
6
|
+
export interface Interface {
|
|
7
|
+
readonly evaluate: <Options extends EvaluationOptions, const Questions extends EvaluationQuestions>(request: EvaluationRequestFor<Options, Questions>) => Effect.Effect<EvaluationResponseFor<Questions>, AIError>;
|
|
8
|
+
}
|
|
9
|
+
declare const Service_base: Context.ServiceClass<Service, "@opencode/AI/Experimental/EvaluationClient", Interface>;
|
|
10
|
+
export declare class Service extends Service_base {
|
|
11
|
+
}
|
|
12
|
+
export declare const evaluate: <Options extends EvaluationOptions, const Questions extends EvaluationQuestions>(request: EvaluationRequestFor<Options, Questions>) => Effect.Effect<EvaluationResponseFor<Questions>, AIError, Service>;
|
|
13
|
+
export declare const layer: Layer.Layer<Service, never, RequestExecutor.Service>;
|
|
14
|
+
export declare const fetchLayer: Layer.Layer<Service, never, never>;
|
|
15
|
+
export declare const EvaluationClient: {
|
|
16
|
+
readonly Service: typeof Service;
|
|
17
|
+
readonly layer: Layer.Layer<Service, never, RequestExecutor.Service>;
|
|
18
|
+
readonly fetchLayer: Layer.Layer<Service, never, never>;
|
|
19
|
+
readonly evaluate: <Options extends EvaluationOptions, const Questions extends EvaluationQuestions>(request: EvaluationRequestFor<Options, Questions>) => Effect.Effect<EvaluationResponseFor<Questions>, AIError, Service>;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { RequestExecutor } from "../route/executor.js";
|
|
3
|
+
import { mergeHttpOptions } from "../schema/index.js";
|
|
4
|
+
import { sanitizeSurrogates } from "../utils/sanitize.js";
|
|
5
|
+
import {} from "./evaluation.js";
|
|
6
|
+
export class Service extends Context.Service()("@opencode/AI/Experimental/EvaluationClient") {
|
|
7
|
+
}
|
|
8
|
+
export const evaluate = (request) => Effect.flatMap(Service, (client) => client.evaluate(request));
|
|
9
|
+
export const layer = Layer.effect(Service, Effect.gen(function* () {
|
|
10
|
+
const executor = yield* RequestExecutor.Service;
|
|
11
|
+
return Service.of({
|
|
12
|
+
evaluate: (request) => request.model.route.evaluate({
|
|
13
|
+
...sanitizeSurrogates({
|
|
14
|
+
...request,
|
|
15
|
+
model: undefined,
|
|
16
|
+
http: mergeHttpOptions(request.model.http, request.http),
|
|
17
|
+
}),
|
|
18
|
+
model: request.model,
|
|
19
|
+
}, executor.execute),
|
|
20
|
+
});
|
|
21
|
+
}));
|
|
22
|
+
export const fetchLayer = layer.pipe(Layer.provide(RequestExecutor.fetchLayer));
|
|
23
|
+
export const EvaluationClient = {
|
|
24
|
+
Service,
|
|
25
|
+
layer,
|
|
26
|
+
fetchLayer,
|
|
27
|
+
evaluate,
|
|
28
|
+
};
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { AIError, HttpOptions, ModelID, ProviderID, Usage } from "../schema/index.js";
|
|
3
|
+
import { Service, type Execute } from "./evaluation-client.js";
|
|
4
|
+
export declare const EvaluationInput: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
5
|
+
export type EvaluationInput = Schema.Schema.Type<typeof EvaluationInput>;
|
|
6
|
+
export declare const ChoiceQuestion: Schema.Struct<{
|
|
7
|
+
readonly type: Schema.Literal<"choice">;
|
|
8
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
9
|
+
readonly criteria: Schema.refine<{
|
|
10
|
+
readonly [x: string]: string | {
|
|
11
|
+
readonly [x: string]: Schema.Json;
|
|
12
|
+
} | readonly Schema.Json[] | null;
|
|
13
|
+
}, Schema.$Record<Schema.String, Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>>;
|
|
14
|
+
}>;
|
|
15
|
+
export type ChoiceQuestion = Schema.Schema.Type<typeof ChoiceQuestion>;
|
|
16
|
+
export declare const ScoreQuestion: Schema.Struct<{
|
|
17
|
+
readonly type: Schema.Literal<"score">;
|
|
18
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
19
|
+
readonly criteria: Schema.$Array<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
20
|
+
}>;
|
|
21
|
+
export type ScoreQuestion = Schema.Schema.Type<typeof ScoreQuestion>;
|
|
22
|
+
export declare const BooleanQuestion: Schema.Struct<{
|
|
23
|
+
readonly type: Schema.Literal<"boolean">;
|
|
24
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
25
|
+
readonly criteria: Schema.optional<Schema.Struct<{
|
|
26
|
+
readonly true: Schema.optional<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
27
|
+
readonly false: Schema.optional<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
28
|
+
}>>;
|
|
29
|
+
}>;
|
|
30
|
+
export type BooleanQuestion = Schema.Schema.Type<typeof BooleanQuestion>;
|
|
31
|
+
export declare const EvaluationQuestion: Schema.toTaggedUnion<"type", readonly [Schema.Struct<{
|
|
32
|
+
readonly type: Schema.Literal<"choice">;
|
|
33
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
34
|
+
readonly criteria: Schema.refine<{
|
|
35
|
+
readonly [x: string]: string | {
|
|
36
|
+
readonly [x: string]: Schema.Json;
|
|
37
|
+
} | readonly Schema.Json[] | null;
|
|
38
|
+
}, Schema.$Record<Schema.String, Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>>;
|
|
39
|
+
}>, Schema.Struct<{
|
|
40
|
+
readonly type: Schema.Literal<"score">;
|
|
41
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
42
|
+
readonly criteria: Schema.$Array<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
43
|
+
}>, Schema.Struct<{
|
|
44
|
+
readonly type: Schema.Literal<"boolean">;
|
|
45
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
46
|
+
readonly criteria: Schema.optional<Schema.Struct<{
|
|
47
|
+
readonly true: Schema.optional<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
48
|
+
readonly false: Schema.optional<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
49
|
+
}>>;
|
|
50
|
+
}>]>;
|
|
51
|
+
export type EvaluationQuestion = Schema.Schema.Type<typeof EvaluationQuestion>;
|
|
52
|
+
export type EvaluationQuestions = Readonly<Record<string, EvaluationQuestion>>;
|
|
53
|
+
export declare const ChoiceAnswer: Schema.Struct<{
|
|
54
|
+
readonly type: Schema.Literal<"choice">;
|
|
55
|
+
readonly choice: Schema.String;
|
|
56
|
+
readonly probabilities: Schema.optional<Schema.$Record<Schema.String, Schema.Number>>;
|
|
57
|
+
}>;
|
|
58
|
+
export type ChoiceAnswer = Schema.Schema.Type<typeof ChoiceAnswer>;
|
|
59
|
+
export declare const ScoreAnswer: Schema.Struct<{
|
|
60
|
+
readonly type: Schema.Literal<"score">;
|
|
61
|
+
readonly score: Schema.Number;
|
|
62
|
+
readonly probabilities: Schema.optional<Schema.$Record<Schema.String, Schema.Number>>;
|
|
63
|
+
}>;
|
|
64
|
+
export type ScoreAnswer = Schema.Schema.Type<typeof ScoreAnswer>;
|
|
65
|
+
export declare const BooleanAnswer: Schema.Struct<{
|
|
66
|
+
readonly type: Schema.Literal<"boolean">;
|
|
67
|
+
readonly probability: Schema.Number;
|
|
68
|
+
}>;
|
|
69
|
+
export type BooleanAnswer = Schema.Schema.Type<typeof BooleanAnswer>;
|
|
70
|
+
export declare const EvaluationAnswer: Schema.toTaggedUnion<"type", readonly [Schema.Struct<{
|
|
71
|
+
readonly type: Schema.Literal<"choice">;
|
|
72
|
+
readonly choice: Schema.String;
|
|
73
|
+
readonly probabilities: Schema.optional<Schema.$Record<Schema.String, Schema.Number>>;
|
|
74
|
+
}>, Schema.Struct<{
|
|
75
|
+
readonly type: Schema.Literal<"score">;
|
|
76
|
+
readonly score: Schema.Number;
|
|
77
|
+
readonly probabilities: Schema.optional<Schema.$Record<Schema.String, Schema.Number>>;
|
|
78
|
+
}>, Schema.Struct<{
|
|
79
|
+
readonly type: Schema.Literal<"boolean">;
|
|
80
|
+
readonly probability: Schema.Number;
|
|
81
|
+
}>]>;
|
|
82
|
+
export type EvaluationAnswer = Schema.Schema.Type<typeof EvaluationAnswer>;
|
|
83
|
+
export type AnswerFor<Question extends EvaluationQuestion> = Question extends {
|
|
84
|
+
readonly type: "choice";
|
|
85
|
+
readonly criteria: infer Criteria;
|
|
86
|
+
} ? {
|
|
87
|
+
readonly type: "choice";
|
|
88
|
+
readonly choice: Extract<keyof Criteria, string>;
|
|
89
|
+
readonly probabilities?: Readonly<Record<Extract<keyof Criteria, string>, number>>;
|
|
90
|
+
} : Question extends {
|
|
91
|
+
readonly type: "score";
|
|
92
|
+
} ? ScoreAnswer : BooleanAnswer;
|
|
93
|
+
export type AnswersFor<Questions extends EvaluationQuestions> = {
|
|
94
|
+
readonly [ID in keyof Questions]: AnswerFor<Questions[ID]>;
|
|
95
|
+
};
|
|
96
|
+
export type EvaluationOptions = Record<string, unknown>;
|
|
97
|
+
export interface EvaluationRoute<Options extends EvaluationOptions = EvaluationOptions> {
|
|
98
|
+
readonly id: string;
|
|
99
|
+
readonly evaluate: <const Questions extends EvaluationQuestions>(request: EvaluationRequestFor<Options, Questions>, execute: Execute) => Effect.Effect<EvaluationResponseFor<Questions>, AIError>;
|
|
100
|
+
}
|
|
101
|
+
export declare class EvaluationModel<Options extends EvaluationOptions = EvaluationOptions> {
|
|
102
|
+
protected readonly _Options: (options: Options) => Options;
|
|
103
|
+
readonly id: ModelID;
|
|
104
|
+
readonly provider: ProviderID;
|
|
105
|
+
readonly route: EvaluationRoute<Options>;
|
|
106
|
+
readonly http?: HttpOptions;
|
|
107
|
+
constructor(input: EvaluationModel.Input<Options>);
|
|
108
|
+
static make<Options extends EvaluationOptions = EvaluationOptions>(input: EvaluationModel.MakeInput<Options>): EvaluationModel<Options>;
|
|
109
|
+
}
|
|
110
|
+
export declare namespace EvaluationModel {
|
|
111
|
+
interface Input<Options extends EvaluationOptions = EvaluationOptions> {
|
|
112
|
+
readonly id: ModelID;
|
|
113
|
+
readonly provider: ProviderID;
|
|
114
|
+
readonly route: EvaluationRoute<Options>;
|
|
115
|
+
readonly http?: HttpOptions;
|
|
116
|
+
}
|
|
117
|
+
interface MakeInput<Options extends EvaluationOptions = EvaluationOptions> extends Omit<Input<Options>, "id" | "provider"> {
|
|
118
|
+
readonly id: string | ModelID;
|
|
119
|
+
readonly provider: string | ProviderID;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export declare const EvaluationModelSchema: Schema.declare<EvaluationModel<EvaluationOptions>, EvaluationModel<EvaluationOptions>>;
|
|
123
|
+
declare const EvaluationRequest_base: Schema.Class<EvaluationRequest, Schema.Struct<{
|
|
124
|
+
readonly model: Schema.declare<EvaluationModel<EvaluationOptions>, EvaluationModel<EvaluationOptions>>;
|
|
125
|
+
readonly state: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
126
|
+
readonly questions: Schema.refine<{
|
|
127
|
+
readonly [x: string]: {
|
|
128
|
+
readonly type: "choice";
|
|
129
|
+
readonly instructions: string | {
|
|
130
|
+
readonly [x: string]: Schema.Json;
|
|
131
|
+
} | readonly Schema.Json[];
|
|
132
|
+
readonly criteria: {
|
|
133
|
+
readonly [x: string]: string | {
|
|
134
|
+
readonly [x: string]: Schema.Json;
|
|
135
|
+
} | readonly Schema.Json[] | null;
|
|
136
|
+
};
|
|
137
|
+
} | {
|
|
138
|
+
readonly type: "score";
|
|
139
|
+
readonly instructions: string | {
|
|
140
|
+
readonly [x: string]: Schema.Json;
|
|
141
|
+
} | readonly Schema.Json[];
|
|
142
|
+
readonly criteria: readonly (string | {
|
|
143
|
+
readonly [x: string]: Schema.Json;
|
|
144
|
+
} | readonly Schema.Json[] | null)[];
|
|
145
|
+
} | {
|
|
146
|
+
readonly type: "boolean";
|
|
147
|
+
readonly instructions: string | {
|
|
148
|
+
readonly [x: string]: Schema.Json;
|
|
149
|
+
} | readonly Schema.Json[];
|
|
150
|
+
readonly criteria?: {
|
|
151
|
+
readonly true?: string | {
|
|
152
|
+
readonly [x: string]: Schema.Json;
|
|
153
|
+
} | readonly Schema.Json[] | null | undefined;
|
|
154
|
+
readonly false?: string | {
|
|
155
|
+
readonly [x: string]: Schema.Json;
|
|
156
|
+
} | readonly Schema.Json[] | null | undefined;
|
|
157
|
+
} | undefined;
|
|
158
|
+
};
|
|
159
|
+
}, Schema.$Record<Schema.String, Schema.toTaggedUnion<"type", readonly [Schema.Struct<{
|
|
160
|
+
readonly type: Schema.Literal<"choice">;
|
|
161
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
162
|
+
readonly criteria: Schema.refine<{
|
|
163
|
+
readonly [x: string]: string | {
|
|
164
|
+
readonly [x: string]: Schema.Json;
|
|
165
|
+
} | readonly Schema.Json[] | null;
|
|
166
|
+
}, Schema.$Record<Schema.String, Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>>;
|
|
167
|
+
}>, Schema.Struct<{
|
|
168
|
+
readonly type: Schema.Literal<"score">;
|
|
169
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
170
|
+
readonly criteria: Schema.$Array<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
171
|
+
}>, Schema.Struct<{
|
|
172
|
+
readonly type: Schema.Literal<"boolean">;
|
|
173
|
+
readonly instructions: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
174
|
+
readonly criteria: Schema.optional<Schema.Struct<{
|
|
175
|
+
readonly true: Schema.optional<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
176
|
+
readonly false: Schema.optional<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>>>;
|
|
177
|
+
}>>;
|
|
178
|
+
}>]>>>;
|
|
179
|
+
readonly options: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
180
|
+
readonly http: Schema.optional<typeof HttpOptions>;
|
|
181
|
+
}>, {}>;
|
|
182
|
+
export declare class EvaluationRequest extends EvaluationRequest_base {
|
|
183
|
+
protected readonly _EvaluationRequest: void;
|
|
184
|
+
}
|
|
185
|
+
export type EvaluationModelOptions<Model> = Model extends EvaluationModel<infer Options> ? Options : never;
|
|
186
|
+
export type EvaluationRequestFor<Options extends EvaluationOptions = EvaluationOptions, Questions extends EvaluationQuestions = EvaluationQuestions> = Omit<EvaluationRequest, "model" | "questions" | "options"> & {
|
|
187
|
+
readonly model: EvaluationModel<Options>;
|
|
188
|
+
readonly questions: Questions;
|
|
189
|
+
readonly options?: Options;
|
|
190
|
+
};
|
|
191
|
+
export type EvaluationRequestInput<Model extends object = EvaluationModel, Questions extends EvaluationQuestions = EvaluationQuestions> = Omit<ConstructorParameters<typeof EvaluationRequest>[0], "model" | "questions" | "options" | "http"> & {
|
|
192
|
+
readonly model: Model;
|
|
193
|
+
readonly questions: Questions;
|
|
194
|
+
readonly options?: NoInfer<EvaluationModelOptions<Model>>;
|
|
195
|
+
readonly http?: HttpOptions.Input;
|
|
196
|
+
} & (Model extends EvaluationModel<EvaluationModelOptions<Model>> ? unknown : never);
|
|
197
|
+
declare const EvaluationRounding_base: Schema.Class<EvaluationRounding, Schema.Struct<{
|
|
198
|
+
readonly probabilityDecimals: Schema.optional<Schema.Int>;
|
|
199
|
+
readonly scoreDecimals: Schema.optional<Schema.Int>;
|
|
200
|
+
}>, {}>;
|
|
201
|
+
export declare class EvaluationRounding extends EvaluationRounding_base {
|
|
202
|
+
}
|
|
203
|
+
declare const EvaluationResponse_base: Schema.Class<EvaluationResponse, Schema.Struct<{
|
|
204
|
+
readonly model: Schema.brand<Schema.String, "AI.ModelID">;
|
|
205
|
+
readonly answers: Schema.$Record<Schema.String, Schema.toTaggedUnion<"type", readonly [Schema.Struct<{
|
|
206
|
+
readonly type: Schema.Literal<"choice">;
|
|
207
|
+
readonly choice: Schema.String;
|
|
208
|
+
readonly probabilities: Schema.optional<Schema.$Record<Schema.String, Schema.Number>>;
|
|
209
|
+
}>, Schema.Struct<{
|
|
210
|
+
readonly type: Schema.Literal<"score">;
|
|
211
|
+
readonly score: Schema.Number;
|
|
212
|
+
readonly probabilities: Schema.optional<Schema.$Record<Schema.String, Schema.Number>>;
|
|
213
|
+
}>, Schema.Struct<{
|
|
214
|
+
readonly type: Schema.Literal<"boolean">;
|
|
215
|
+
readonly probability: Schema.Number;
|
|
216
|
+
}>]>>;
|
|
217
|
+
readonly usage: Schema.optional<typeof Usage>;
|
|
218
|
+
readonly rounding: Schema.optional<typeof EvaluationRounding>;
|
|
219
|
+
readonly providerMetadata: Schema.optional<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>>;
|
|
220
|
+
}>, {}>;
|
|
221
|
+
export declare class EvaluationResponse extends EvaluationResponse_base {
|
|
222
|
+
}
|
|
223
|
+
export type EvaluationResponseFor<Questions extends EvaluationQuestions> = Omit<EvaluationResponse, "answers"> & {
|
|
224
|
+
readonly answers: AnswersFor<Questions>;
|
|
225
|
+
};
|
|
226
|
+
export declare function request<const Model extends object, const Questions extends EvaluationQuestions>(input: EvaluationRequestInput<Model, Questions>): EvaluationRequestFor<EvaluationModelOptions<Model>, Questions>;
|
|
227
|
+
export declare function request(input: EvaluationRequest): EvaluationRequest;
|
|
228
|
+
export declare function evaluate<const Model extends object, const Questions extends EvaluationQuestions>(input: EvaluationRequestInput<Model, Questions>): Effect.Effect<EvaluationResponseFor<Questions>, AIError, Service>;
|
|
229
|
+
export declare function evaluate(input: EvaluationRequest): Effect.Effect<EvaluationResponse, AIError, Service>;
|
|
230
|
+
export declare const Evaluation: {
|
|
231
|
+
readonly request: typeof request;
|
|
232
|
+
readonly evaluate: typeof evaluate;
|
|
233
|
+
};
|
|
234
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { AIError, HttpOptions, InvalidRequestError, ModelID, ProviderID, ProviderMetadata, Usage, } from "../schema/index.js";
|
|
3
|
+
import { EvaluationClient, Service } from "./evaluation-client.js";
|
|
4
|
+
export const EvaluationInput = Schema.Union([Schema.String, Schema.JsonObject, Schema.Array(Schema.Json)]);
|
|
5
|
+
const EvaluationCriterion = Schema.NullOr(EvaluationInput);
|
|
6
|
+
const ChoiceCriteria = Schema.Record(Schema.String, EvaluationCriterion).pipe(Schema.refine((x) => Object.keys(x).length > 0, {
|
|
7
|
+
message: "Choice criteria must be a nonempty option map",
|
|
8
|
+
}));
|
|
9
|
+
export const ChoiceQuestion = Schema.Struct({
|
|
10
|
+
type: Schema.Literal("choice"),
|
|
11
|
+
instructions: EvaluationInput,
|
|
12
|
+
criteria: ChoiceCriteria,
|
|
13
|
+
});
|
|
14
|
+
export const ScoreQuestion = Schema.Struct({
|
|
15
|
+
type: Schema.Literal("score"),
|
|
16
|
+
instructions: EvaluationInput,
|
|
17
|
+
criteria: Schema.Array(EvaluationCriterion).check(Schema.isMinLength(2)),
|
|
18
|
+
});
|
|
19
|
+
export const BooleanQuestion = Schema.Struct({
|
|
20
|
+
type: Schema.Literal("boolean"),
|
|
21
|
+
instructions: EvaluationInput,
|
|
22
|
+
criteria: Schema.optional(Schema.Struct({
|
|
23
|
+
true: Schema.optional(EvaluationCriterion),
|
|
24
|
+
false: Schema.optional(EvaluationCriterion),
|
|
25
|
+
})),
|
|
26
|
+
});
|
|
27
|
+
export const EvaluationQuestion = Schema.Union([ChoiceQuestion, ScoreQuestion, BooleanQuestion]).pipe(Schema.toTaggedUnion("type"));
|
|
28
|
+
const EvaluationQuestions = Schema.Record(Schema.String, EvaluationQuestion).pipe(Schema.refine((x) => Object.keys(x).length > 0, {
|
|
29
|
+
message: "Evaluation questions must be a nonempty map",
|
|
30
|
+
}));
|
|
31
|
+
const Probability = Schema.Number.check(Schema.isBetween({ minimum: 0, maximum: 1 }));
|
|
32
|
+
export const ChoiceAnswer = Schema.Struct({
|
|
33
|
+
type: Schema.Literal("choice"),
|
|
34
|
+
choice: Schema.String,
|
|
35
|
+
probabilities: Schema.optional(Schema.Record(Schema.String, Probability)),
|
|
36
|
+
});
|
|
37
|
+
export const ScoreAnswer = Schema.Struct({
|
|
38
|
+
type: Schema.Literal("score"),
|
|
39
|
+
score: Schema.Number,
|
|
40
|
+
probabilities: Schema.optional(Schema.Record(Schema.String, Probability)),
|
|
41
|
+
});
|
|
42
|
+
export const BooleanAnswer = Schema.Struct({
|
|
43
|
+
type: Schema.Literal("boolean"),
|
|
44
|
+
probability: Probability,
|
|
45
|
+
});
|
|
46
|
+
export const EvaluationAnswer = Schema.Union([ChoiceAnswer, ScoreAnswer, BooleanAnswer]).pipe(Schema.toTaggedUnion("type"));
|
|
47
|
+
export class EvaluationModel {
|
|
48
|
+
id;
|
|
49
|
+
provider;
|
|
50
|
+
route;
|
|
51
|
+
http;
|
|
52
|
+
constructor(input) {
|
|
53
|
+
this.id = input.id;
|
|
54
|
+
this.provider = input.provider;
|
|
55
|
+
this.route = input.route;
|
|
56
|
+
this.http = input.http;
|
|
57
|
+
}
|
|
58
|
+
static make(input) {
|
|
59
|
+
return new EvaluationModel({
|
|
60
|
+
id: ModelID.make(input.id),
|
|
61
|
+
provider: ProviderID.make(input.provider),
|
|
62
|
+
route: input.route,
|
|
63
|
+
http: input.http,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export const EvaluationModelSchema = Schema.declare((value) => value instanceof EvaluationModel, {
|
|
68
|
+
expected: "Evaluation.Model",
|
|
69
|
+
});
|
|
70
|
+
export class EvaluationRequest extends Schema.Class("Evaluation.Request")({
|
|
71
|
+
model: EvaluationModelSchema,
|
|
72
|
+
state: EvaluationInput,
|
|
73
|
+
questions: EvaluationQuestions,
|
|
74
|
+
options: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
|
|
75
|
+
http: Schema.optional(HttpOptions),
|
|
76
|
+
}) {
|
|
77
|
+
}
|
|
78
|
+
export class EvaluationRounding extends Schema.Class("Evaluation.Rounding")({
|
|
79
|
+
probabilityDecimals: Schema.optional(Schema.Int),
|
|
80
|
+
scoreDecimals: Schema.optional(Schema.Int),
|
|
81
|
+
}) {
|
|
82
|
+
}
|
|
83
|
+
export class EvaluationResponse extends Schema.Class("Evaluation.Response")({
|
|
84
|
+
model: ModelID,
|
|
85
|
+
answers: Schema.Record(Schema.String, EvaluationAnswer),
|
|
86
|
+
usage: Schema.optional(Usage),
|
|
87
|
+
rounding: Schema.optional(EvaluationRounding),
|
|
88
|
+
providerMetadata: Schema.optional(ProviderMetadata),
|
|
89
|
+
}) {
|
|
90
|
+
}
|
|
91
|
+
export function request(input) {
|
|
92
|
+
if (input instanceof EvaluationRequest)
|
|
93
|
+
return input;
|
|
94
|
+
return new EvaluationRequest({
|
|
95
|
+
...input,
|
|
96
|
+
model: input.model,
|
|
97
|
+
http: input.http === undefined ? undefined : HttpOptions.make(input.http),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export function evaluate(input) {
|
|
101
|
+
return Effect.try({
|
|
102
|
+
try: () => (input instanceof EvaluationRequest ? input : request(input)),
|
|
103
|
+
catch: (cause) => new AIError({
|
|
104
|
+
reason: new InvalidRequestError({
|
|
105
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
106
|
+
cause,
|
|
107
|
+
}),
|
|
108
|
+
}),
|
|
109
|
+
}).pipe(Effect.flatMap((request) => EvaluationClient.evaluate(request)));
|
|
110
|
+
}
|
|
111
|
+
export const Evaluation = {
|
|
112
|
+
request,
|
|
113
|
+
evaluate,
|
|
114
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EvaluationModel } from "./evaluation.js";
|
|
2
|
+
import { type Definition as AuthDefinition } from "../route/auth.js";
|
|
3
|
+
import { HttpOptions, ModelID } from "../schema/index.js";
|
|
4
|
+
export interface ModelInput {
|
|
5
|
+
readonly id: string | ModelID;
|
|
6
|
+
readonly provider: string;
|
|
7
|
+
readonly providerMetadataKey: string;
|
|
8
|
+
readonly auth: AuthDefinition;
|
|
9
|
+
readonly baseURL: string;
|
|
10
|
+
readonly headers?: Record<string, string>;
|
|
11
|
+
readonly http?: HttpOptions;
|
|
12
|
+
}
|
|
13
|
+
export declare const model: (cfg: ModelInput) => EvaluationModel<import("./evaluation.js").EvaluationOptions>;
|
|
14
|
+
export declare const SystemOne: {
|
|
15
|
+
readonly model: (cfg: ModelInput) => EvaluationModel<import("./evaluation.js").EvaluationOptions>;
|
|
16
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { Headers, HttpClientRequest } from "effect/unstable/http";
|
|
3
|
+
import { BooleanAnswer, ChoiceAnswer, ChoiceQuestion, EvaluationInput, EvaluationModel, EvaluationResponse, EvaluationRounding, ScoreAnswer, ScoreQuestion, } from "./evaluation.js";
|
|
4
|
+
import { Auth } from "../route/auth.js";
|
|
5
|
+
import { AIError, HttpContext, HttpOptions, InvalidProviderOutputError, InvalidRequestError, ModelID, Usage, mergeJsonRecords, } from "../schema/index.js";
|
|
6
|
+
const Noul = Schema.Struct({
|
|
7
|
+
type: Schema.Literal("noul"),
|
|
8
|
+
instructions: EvaluationInput,
|
|
9
|
+
criteria: Schema.optional(Schema.Struct({
|
|
10
|
+
true: Schema.optional(Schema.NullOr(EvaluationInput)),
|
|
11
|
+
false: Schema.optional(Schema.NullOr(EvaluationInput)),
|
|
12
|
+
})),
|
|
13
|
+
});
|
|
14
|
+
const Question = Schema.Union([
|
|
15
|
+
ChoiceQuestion.pipe(Schema.refine((x) => Object.keys(x.criteria).length <= 255, {
|
|
16
|
+
message: "System One Choice questions support at most 255 options",
|
|
17
|
+
})),
|
|
18
|
+
ScoreQuestion.pipe(Schema.refine((x) => x.criteria.length <= 10, {
|
|
19
|
+
message: "System One Score questions support at most 10 levels",
|
|
20
|
+
})),
|
|
21
|
+
Noul,
|
|
22
|
+
]);
|
|
23
|
+
const Request = Schema.StructWithRest(Schema.Struct({
|
|
24
|
+
model: Schema.String,
|
|
25
|
+
state: EvaluationInput,
|
|
26
|
+
questions: Schema.Record(Schema.String, Question),
|
|
27
|
+
}), [Schema.Record(Schema.String, Schema.Any)]);
|
|
28
|
+
const Probability = Schema.Number.check(Schema.isBetween({ minimum: 0, maximum: 1 }));
|
|
29
|
+
const NoulAnswer = Schema.Struct({ type: Schema.Literal("noul"), noul: Probability });
|
|
30
|
+
const Choice = Schema.Struct({
|
|
31
|
+
type: Schema.Literal("choice"),
|
|
32
|
+
choice: Schema.String,
|
|
33
|
+
probabilities: Schema.Record(Schema.String, Probability),
|
|
34
|
+
confidence: Schema.optional(Probability),
|
|
35
|
+
});
|
|
36
|
+
const Score = Schema.Struct({
|
|
37
|
+
type: Schema.Literal("score"),
|
|
38
|
+
score: Schema.Number,
|
|
39
|
+
probabilities: Schema.Record(Schema.String, Probability),
|
|
40
|
+
legend: Schema.optional(Schema.Record(Schema.String, Schema.Json)),
|
|
41
|
+
confidence: Schema.optional(Probability),
|
|
42
|
+
});
|
|
43
|
+
const NativeUsage = Schema.Struct({
|
|
44
|
+
input_tokens: Schema.optional(Schema.Number),
|
|
45
|
+
output_tokens: Schema.optional(Schema.Number),
|
|
46
|
+
});
|
|
47
|
+
const encode = Schema.encodeUnknownEffect(Schema.fromJsonString(Request));
|
|
48
|
+
const exact = (x, keys) => Object.keys(x).length === keys.length && keys.every((key) => Object.hasOwn(x, key));
|
|
49
|
+
export const model = (cfg) => {
|
|
50
|
+
const route = {
|
|
51
|
+
id: "system-one",
|
|
52
|
+
evaluate: (req, send) => Effect.gen(function* () {
|
|
53
|
+
const url = new URL(`${cfg.baseURL.replace(/\/$/, "")}/systemone`);
|
|
54
|
+
Object.entries(req.http?.query ?? {}).forEach(([key, value]) => url.searchParams.set(key, value));
|
|
55
|
+
const body = yield* encode({
|
|
56
|
+
...mergeJsonRecords(req.options, req.http?.body),
|
|
57
|
+
model: req.model.id,
|
|
58
|
+
state: req.state,
|
|
59
|
+
questions: Object.fromEntries(Object.entries(req.questions).map(([id, x]) => [id, x.type === "boolean" ? { ...x, type: "noul" } : x])),
|
|
60
|
+
}).pipe(Effect.mapError((cause) => new AIError({ reason: new InvalidRequestError({ message: cause.message, cause }) })));
|
|
61
|
+
const headers = yield* Auth.toEffect(cfg.auth)({
|
|
62
|
+
request: req,
|
|
63
|
+
method: "POST",
|
|
64
|
+
url: url.toString(),
|
|
65
|
+
body,
|
|
66
|
+
headers: Headers.fromInput({ ...cfg.headers, ...req.http?.headers }),
|
|
67
|
+
});
|
|
68
|
+
const res = yield* send(HttpClientRequest.post(url).pipe(HttpClientRequest.setHeaders(headers), HttpClientRequest.bodyText(body, "application/json")));
|
|
69
|
+
const http = new HttpContext({ url: res.request.url, status: res.status, headers: res.headers });
|
|
70
|
+
const fail = (message, cause, body) => new AIError({ reason: new InvalidProviderOutputError({ route: route.id, message, body, http, cause }) });
|
|
71
|
+
const text = yield* res.text.pipe(Effect.mapError((cause) => fail("Failed to read the System One response", cause)));
|
|
72
|
+
const entries = Object.entries(req.questions);
|
|
73
|
+
const output = Schema.Struct({
|
|
74
|
+
model: Schema.String,
|
|
75
|
+
answers: Schema.Struct(Object.fromEntries(entries.map(([id, question]) => {
|
|
76
|
+
if (question.type === "boolean")
|
|
77
|
+
return [id, NoulAnswer];
|
|
78
|
+
if (question.type === "choice") {
|
|
79
|
+
const keys = Object.keys(question.criteria);
|
|
80
|
+
return [
|
|
81
|
+
id,
|
|
82
|
+
Choice.pipe(Schema.refine((x) => Object.hasOwn(question.criteria, x.choice) && exact(x.probabilities, keys), { message: `Question "${id}" returned an invalid choice answer` })),
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
const keys = question.criteria.map((_, index) => String(index));
|
|
86
|
+
return [
|
|
87
|
+
id,
|
|
88
|
+
Score.pipe(Schema.refine((x) => x.score >= 0 && x.score <= question.criteria.length - 1 && exact(x.probabilities, keys), { message: `Question "${id}" returned an invalid score answer` })),
|
|
89
|
+
];
|
|
90
|
+
}))),
|
|
91
|
+
usage: Schema.optional(NativeUsage),
|
|
92
|
+
});
|
|
93
|
+
const data = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(output))(text).pipe(Effect.mapError((cause) => fail("System One returned an invalid response", cause, text)));
|
|
94
|
+
const confidence = {};
|
|
95
|
+
const legend = {};
|
|
96
|
+
const answers = Object.fromEntries(entries.map(([id, question]) => {
|
|
97
|
+
const answer = data.answers[id];
|
|
98
|
+
if (question.type === "boolean")
|
|
99
|
+
return [
|
|
100
|
+
id,
|
|
101
|
+
{ type: "boolean", probability: answer.noul },
|
|
102
|
+
];
|
|
103
|
+
if (question.type === "choice") {
|
|
104
|
+
const value = answer;
|
|
105
|
+
if (value.confidence !== undefined)
|
|
106
|
+
confidence[id] = value.confidence;
|
|
107
|
+
return [
|
|
108
|
+
id,
|
|
109
|
+
{ type: "choice", choice: value.choice, probabilities: value.probabilities },
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
const value = answer;
|
|
113
|
+
if (value.confidence !== undefined)
|
|
114
|
+
confidence[id] = value.confidence;
|
|
115
|
+
if (value.legend !== undefined)
|
|
116
|
+
legend[id] = value.legend;
|
|
117
|
+
return [id, { type: "score", score: value.score, probabilities: value.probabilities }];
|
|
118
|
+
}));
|
|
119
|
+
const meta = {
|
|
120
|
+
...(Object.keys(confidence).length === 0 ? {} : { confidence }),
|
|
121
|
+
...(Object.keys(legend).length === 0 ? {} : { legend }),
|
|
122
|
+
};
|
|
123
|
+
return new EvaluationResponse({
|
|
124
|
+
model: ModelID.make(data.model),
|
|
125
|
+
answers,
|
|
126
|
+
usage: data.usage
|
|
127
|
+
? new Usage({
|
|
128
|
+
inputTokens: data.usage.input_tokens,
|
|
129
|
+
outputTokens: data.usage.output_tokens,
|
|
130
|
+
totalTokens: data.usage.input_tokens === undefined && data.usage.output_tokens === undefined
|
|
131
|
+
? undefined
|
|
132
|
+
: (data.usage.input_tokens ?? 0) + (data.usage.output_tokens ?? 0),
|
|
133
|
+
providerMetadata: { [cfg.providerMetadataKey]: data.usage },
|
|
134
|
+
})
|
|
135
|
+
: undefined,
|
|
136
|
+
rounding: new EvaluationRounding({ probabilityDecimals: 2, scoreDecimals: 2 }),
|
|
137
|
+
providerMetadata: Object.keys(meta).length === 0 ? undefined : { [cfg.providerMetadataKey]: meta },
|
|
138
|
+
});
|
|
139
|
+
}),
|
|
140
|
+
};
|
|
141
|
+
return EvaluationModel.make({ id: cfg.id, provider: cfg.provider, route, http: cfg.http });
|
|
142
|
+
};
|
|
143
|
+
export const SystemOne = { model };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { EvaluationClient } from "./experimental/evaluation-client.js";
|
|
2
|
+
export { BooleanAnswer, BooleanQuestion, ChoiceAnswer, ChoiceQuestion, Evaluation, EvaluationAnswer, EvaluationInput, EvaluationModel, EvaluationModelSchema, EvaluationQuestion, EvaluationRequest, EvaluationResponse, EvaluationRounding, ScoreAnswer, ScoreQuestion, } from "./experimental/evaluation.js";
|
|
3
|
+
export type { AnswerFor, AnswersFor, EvaluationModelOptions, EvaluationOptions, EvaluationQuestions, EvaluationRequestFor, EvaluationRequestInput, EvaluationResponseFor, EvaluationRoute, } from "./experimental/evaluation.js";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { EvaluationClient } from "./experimental/evaluation-client.js";
|
|
2
|
+
export { BooleanAnswer, BooleanQuestion, ChoiceAnswer, ChoiceQuestion, Evaluation, EvaluationAnswer, EvaluationInput, EvaluationModel, EvaluationModelSchema, EvaluationQuestion, EvaluationRequest, EvaluationResponse, EvaluationRounding, ScoreAnswer, ScoreQuestion, } from "./experimental/evaluation.js";
|
|
@@ -10,23 +10,11 @@ import { GoogleVertexShared } from "./google-vertex-shared.js";
|
|
|
10
10
|
export const id = ProviderID.make("google-vertex");
|
|
11
11
|
const fromRequest = Effect.fn("GoogleVertex.fromRequest")(function* (request) {
|
|
12
12
|
const { serviceTier: _, ...body } = yield* Gemini.protocol.body.from(request);
|
|
13
|
-
// Vertex's native REST schema rejects `id` on FunctionCall/FunctionResponse parts with HTTP 400,
|
|
14
|
-
// unlike AI Studio, so history minted there cannot be lowered verbatim.
|
|
15
|
-
const contents = body.contents.map((content) => ({
|
|
16
|
-
...content,
|
|
17
|
-
parts: (content.parts ?? []).map((part) => {
|
|
18
|
-
if ("functionCall" in part)
|
|
19
|
-
return { ...part, functionCall: { ...part.functionCall, id: undefined } };
|
|
20
|
-
if ("functionResponse" in part)
|
|
21
|
-
return { ...part, functionResponse: { ...part.functionResponse, id: undefined } };
|
|
22
|
-
return part;
|
|
23
|
-
}),
|
|
24
|
-
}));
|
|
25
13
|
const value = request.providerOptions?.labels;
|
|
26
14
|
const labels = ProviderShared.isRecord(value)
|
|
27
15
|
? Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"))
|
|
28
16
|
: undefined;
|
|
29
|
-
return { ...body,
|
|
17
|
+
return { ...body, labels };
|
|
30
18
|
});
|
|
31
19
|
const protocol = {
|
|
32
20
|
...Gemini.protocol,
|
|
@@ -24,8 +24,10 @@ export * as Moonshot from "./moonshot.js";
|
|
|
24
24
|
export * as OpenAI from "./openai.js";
|
|
25
25
|
export * as OpenAICompatible from "./openai-compatible.js";
|
|
26
26
|
export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
|
|
27
|
+
export * as OpenCodeZen from "./opencode-zen.js";
|
|
27
28
|
export * as OpenRouter from "./openrouter.js";
|
|
28
29
|
export * as TogetherAI from "./togetherai.js";
|
|
30
|
+
export * as TypeSafeAI from "./typesafe-ai.js";
|
|
29
31
|
export * as XAI from "./xai.js";
|
|
30
32
|
export * as ZAI from "./zai.js";
|
|
31
33
|
export * as ZAICodingPlan from "./zai-coding-plan.js";
|
package/dist/providers/index.js
CHANGED
|
@@ -24,8 +24,10 @@ export * as Moonshot from "./moonshot.js";
|
|
|
24
24
|
export * as OpenAI from "./openai.js";
|
|
25
25
|
export * as OpenAICompatible from "./openai-compatible.js";
|
|
26
26
|
export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
|
|
27
|
+
export * as OpenCodeZen from "./opencode-zen.js";
|
|
27
28
|
export * as OpenRouter from "./openrouter.js";
|
|
28
29
|
export * as TogetherAI from "./togetherai.js";
|
|
30
|
+
export * as TypeSafeAI from "./typesafe-ai.js";
|
|
29
31
|
export * as XAI from "./xai.js";
|
|
30
32
|
export * as ZAI from "./zai.js";
|
|
31
33
|
export * as ZAICodingPlan from "./zai-coding-plan.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HttpOptions, type ModelID } from "../schema/index.js";
|
|
2
|
+
import { type ProviderAuthOption } from "../route/auth-options.js";
|
|
3
|
+
export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
4
|
+
export type Options = ProviderAuthOption<"optional"> & {
|
|
5
|
+
readonly baseURL?: string;
|
|
6
|
+
readonly headers?: Record<string, string>;
|
|
7
|
+
readonly http?: HttpOptions.Input;
|
|
8
|
+
};
|
|
9
|
+
export declare const configure: (input?: Options) => {
|
|
10
|
+
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
11
|
+
experimental: {
|
|
12
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
13
|
+
};
|
|
14
|
+
configure: (input?: Options) => /*elided*/ any;
|
|
15
|
+
};
|
|
16
|
+
export declare const provider: {
|
|
17
|
+
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
18
|
+
experimental: {
|
|
19
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
20
|
+
};
|
|
21
|
+
configure: (input?: Options) => {
|
|
22
|
+
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
23
|
+
experimental: {
|
|
24
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
25
|
+
};
|
|
26
|
+
configure: /*elided*/ any;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export declare const experimental: {
|
|
30
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
31
|
+
};
|
|
32
|
+
export * as OpenCodeZen from "./opencode-zen.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HttpOptions, ProviderID } from "../schema/index.js";
|
|
2
|
+
import { AuthOptions } from "../route/auth-options.js";
|
|
3
|
+
import { SystemOne } from "../experimental/system-one.js";
|
|
4
|
+
export const id = ProviderID.make("opencode");
|
|
5
|
+
const baseURL = "https://opencode.ai/zen/v1";
|
|
6
|
+
export const configure = (input = {}) => {
|
|
7
|
+
const evaluation = (modelID) => SystemOne.model({
|
|
8
|
+
id: modelID,
|
|
9
|
+
provider: id,
|
|
10
|
+
providerMetadataKey: "opencode",
|
|
11
|
+
auth: AuthOptions.bearer(input, "OPENCODE_API_KEY"),
|
|
12
|
+
baseURL: input.baseURL ?? baseURL,
|
|
13
|
+
headers: input.headers,
|
|
14
|
+
http: input.http === undefined ? undefined : HttpOptions.make(input.http),
|
|
15
|
+
});
|
|
16
|
+
return { id, experimental: { evaluation }, configure };
|
|
17
|
+
};
|
|
18
|
+
export const provider = configure();
|
|
19
|
+
export const experimental = provider.experimental;
|
|
20
|
+
export * as OpenCodeZen from "./opencode-zen.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HttpOptions, type ModelID } from "../schema/index.js";
|
|
2
|
+
import { type ProviderAuthOption } from "../route/auth-options.js";
|
|
3
|
+
export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
4
|
+
export type Options = ProviderAuthOption<"optional"> & {
|
|
5
|
+
readonly baseURL?: string;
|
|
6
|
+
readonly headers?: Record<string, string>;
|
|
7
|
+
readonly http?: HttpOptions.Input;
|
|
8
|
+
};
|
|
9
|
+
export declare const configure: (input?: Options) => {
|
|
10
|
+
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
11
|
+
experimental: {
|
|
12
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
13
|
+
};
|
|
14
|
+
configure: (input?: Options) => /*elided*/ any;
|
|
15
|
+
};
|
|
16
|
+
export declare const provider: {
|
|
17
|
+
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
18
|
+
experimental: {
|
|
19
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
20
|
+
};
|
|
21
|
+
configure: (input?: Options) => {
|
|
22
|
+
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
23
|
+
experimental: {
|
|
24
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
25
|
+
};
|
|
26
|
+
configure: /*elided*/ any;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export declare const experimental: {
|
|
30
|
+
evaluation: (modelID: string | ModelID) => import("../experimental.js").EvaluationModel<import("../experimental.js").EvaluationOptions>;
|
|
31
|
+
};
|
|
32
|
+
export * as TypeSafeAI from "./typesafe-ai.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HttpOptions, ProviderID } from "../schema/index.js";
|
|
2
|
+
import { AuthOptions } from "../route/auth-options.js";
|
|
3
|
+
import { SystemOne } from "../experimental/system-one.js";
|
|
4
|
+
export const id = ProviderID.make("typesafe-ai");
|
|
5
|
+
const baseURL = "https://api.typesafe.ai/v1";
|
|
6
|
+
export const configure = (input = {}) => {
|
|
7
|
+
const evaluation = (modelID) => SystemOne.model({
|
|
8
|
+
id: modelID,
|
|
9
|
+
provider: id,
|
|
10
|
+
providerMetadataKey: "typesafe",
|
|
11
|
+
auth: AuthOptions.bearer(input, "TYPESAFE_API_KEY"),
|
|
12
|
+
baseURL: input.baseURL ?? baseURL,
|
|
13
|
+
headers: input.headers,
|
|
14
|
+
http: input.http === undefined ? undefined : HttpOptions.make(input.http),
|
|
15
|
+
});
|
|
16
|
+
return { id, experimental: { evaluation }, configure };
|
|
17
|
+
};
|
|
18
|
+
export const provider = configure();
|
|
19
|
+
export const experimental = provider.experimental;
|
|
20
|
+
export * as TypeSafeAI from "./typesafe-ai.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.13",
|
|
4
4
|
"name": "@opencode/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
32
32
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
33
|
-
"@opencode/http-recorder": "2.0.
|
|
33
|
+
"@opencode/http-recorder": "2.0.13",
|
|
34
34
|
"@tsconfig/bun": "1.0.9",
|
|
35
35
|
"@types/bun": "1.4.0",
|
|
36
36
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@aws-sdk/credential-providers": "3.1057.0",
|
|
41
41
|
"@smithy/eventstream-codec": "4.2.14",
|
|
42
42
|
"@smithy/util-utf8": "4.2.2",
|
|
43
|
-
"@opencode/schema": "2.0.
|
|
43
|
+
"@opencode/schema": "2.0.13",
|
|
44
44
|
"aws4fetch": "1.0.20",
|
|
45
45
|
"effect": "4.0.0-rc.112",
|
|
46
46
|
"google-auth-library": "10.5.0"
|