@effect-agent/ai-typesafe 0.1.0-beta.100
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 +126 -0
- package/dist/TypeSafeClient-OS5hTVMz.mjs +189 -0
- package/dist/TypeSafeClient-OS5hTVMz.mjs.map +1 -0
- package/dist/TypeSafeClient.d.mts +65 -0
- package/dist/TypeSafeClient.mjs +3 -0
- package/dist/TypeSafeSchema.d.mts +305 -0
- package/dist/TypeSafeSchema.mjs +168 -0
- package/dist/TypeSafeSchema.mjs.map +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +3 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/package.json +1 -0
- package/src/TypeSafeClient.ts +145 -0
- package/src/TypeSafeSchema.ts +275 -0
- package/src/index.ts +2 -0
- package/src/internal/errors.ts +103 -0
- package/src/internal/schema.ts +86 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
declare namespace TypeSafeSchema_d_exports {
|
|
3
|
+
export { Answer, AnswerFor, Answers, ChoiceAnswer, ChoiceQuestion, Content, EvaluateRequest, EvaluateResponse, NoulAnswer, NoulQuestion, Probability, Question, Questions, ScoreAnswer, ScoreQuestion, Usage };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Text or JSON objects and arrays used as state and question instructions.
|
|
7
|
+
*
|
|
8
|
+
* @category schemas
|
|
9
|
+
* @since 0.1.0
|
|
10
|
+
*/
|
|
11
|
+
export declare const Content: 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>>]>;
|
|
12
|
+
/** @category models
|
|
13
|
+
* @since 0.1.0
|
|
14
|
+
*/
|
|
15
|
+
export type Content = typeof Content.Type;
|
|
16
|
+
/**
|
|
17
|
+
* A choice between named options. A null rubric uses the option name alone.
|
|
18
|
+
*
|
|
19
|
+
* @category schemas
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
*/
|
|
22
|
+
export declare const ChoiceQuestion: Schema.Struct<{
|
|
23
|
+
readonly type: Schema.Literal<"choice">;
|
|
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.$Record<Schema.String, Schema.NullOr<Schema.String>>;
|
|
26
|
+
}>;
|
|
27
|
+
/** @category models
|
|
28
|
+
* @since 0.1.0
|
|
29
|
+
*/
|
|
30
|
+
export type ChoiceQuestion = typeof ChoiceQuestion.Type;
|
|
31
|
+
/**
|
|
32
|
+
* A rating along at least two ordered, zero-indexed level descriptions.
|
|
33
|
+
*
|
|
34
|
+
* @category schemas
|
|
35
|
+
* @since 0.1.0
|
|
36
|
+
*/
|
|
37
|
+
export declare const ScoreQuestion: Schema.Struct<{
|
|
38
|
+
readonly type: Schema.Literal<"score">;
|
|
39
|
+
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>>]>;
|
|
40
|
+
readonly criteria: Schema.$Array<Schema.String>;
|
|
41
|
+
}>;
|
|
42
|
+
/** @category models
|
|
43
|
+
* @since 0.1.0
|
|
44
|
+
*/
|
|
45
|
+
export type ScoreQuestion = typeof ScoreQuestion.Type;
|
|
46
|
+
/**
|
|
47
|
+
* A yes/no judgment, with optional descriptions of either outcome.
|
|
48
|
+
*
|
|
49
|
+
* @category schemas
|
|
50
|
+
* @since 0.1.0
|
|
51
|
+
*/
|
|
52
|
+
export declare const NoulQuestion: Schema.Struct<{
|
|
53
|
+
readonly type: Schema.Literal<"noul">;
|
|
54
|
+
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>>]>;
|
|
55
|
+
readonly criteria: Schema.optionalKey<Schema.Struct<{
|
|
56
|
+
readonly true: Schema.optionalKey<Schema.String>;
|
|
57
|
+
readonly false: Schema.optionalKey<Schema.String>;
|
|
58
|
+
}>>;
|
|
59
|
+
}>;
|
|
60
|
+
/** @category models
|
|
61
|
+
* @since 0.1.0
|
|
62
|
+
*/
|
|
63
|
+
export type NoulQuestion = typeof NoulQuestion.Type;
|
|
64
|
+
/** @category schemas
|
|
65
|
+
* @since 0.1.0
|
|
66
|
+
*/
|
|
67
|
+
export declare const Question: Schema.Union<readonly [Schema.Struct<{
|
|
68
|
+
readonly type: Schema.Literal<"choice">;
|
|
69
|
+
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>>]>;
|
|
70
|
+
readonly criteria: Schema.$Record<Schema.String, Schema.NullOr<Schema.String>>;
|
|
71
|
+
}>, Schema.Struct<{
|
|
72
|
+
readonly type: Schema.Literal<"score">;
|
|
73
|
+
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>>]>;
|
|
74
|
+
readonly criteria: Schema.$Array<Schema.String>;
|
|
75
|
+
}>, Schema.Struct<{
|
|
76
|
+
readonly type: Schema.Literal<"noul">;
|
|
77
|
+
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>>]>;
|
|
78
|
+
readonly criteria: Schema.optionalKey<Schema.Struct<{
|
|
79
|
+
readonly true: Schema.optionalKey<Schema.String>;
|
|
80
|
+
readonly false: Schema.optionalKey<Schema.String>;
|
|
81
|
+
}>>;
|
|
82
|
+
}>]>;
|
|
83
|
+
/** @category models
|
|
84
|
+
* @since 0.1.0
|
|
85
|
+
*/
|
|
86
|
+
export type Question = typeof Question.Type;
|
|
87
|
+
/** @category schemas
|
|
88
|
+
* @since 0.1.0
|
|
89
|
+
*/
|
|
90
|
+
export declare const Questions: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.Struct<{
|
|
91
|
+
readonly type: Schema.Literal<"choice">;
|
|
92
|
+
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>>]>;
|
|
93
|
+
readonly criteria: Schema.$Record<Schema.String, Schema.NullOr<Schema.String>>;
|
|
94
|
+
}>, Schema.Struct<{
|
|
95
|
+
readonly type: Schema.Literal<"score">;
|
|
96
|
+
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>>]>;
|
|
97
|
+
readonly criteria: Schema.$Array<Schema.String>;
|
|
98
|
+
}>, Schema.Struct<{
|
|
99
|
+
readonly type: Schema.Literal<"noul">;
|
|
100
|
+
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>>]>;
|
|
101
|
+
readonly criteria: Schema.optionalKey<Schema.Struct<{
|
|
102
|
+
readonly true: Schema.optionalKey<Schema.String>;
|
|
103
|
+
readonly false: Schema.optionalKey<Schema.String>;
|
|
104
|
+
}>>;
|
|
105
|
+
}>]>>;
|
|
106
|
+
/** @category models
|
|
107
|
+
* @since 0.1.0
|
|
108
|
+
*/
|
|
109
|
+
export type Questions = typeof Questions.Type;
|
|
110
|
+
/** @category schemas
|
|
111
|
+
* @since 0.1.0
|
|
112
|
+
*/
|
|
113
|
+
export declare const EvaluateRequest: Schema.Struct<{
|
|
114
|
+
readonly model: Schema.String;
|
|
115
|
+
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>>]>;
|
|
116
|
+
readonly questions: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.Struct<{
|
|
117
|
+
readonly type: Schema.Literal<"choice">;
|
|
118
|
+
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>>]>;
|
|
119
|
+
readonly criteria: Schema.$Record<Schema.String, Schema.NullOr<Schema.String>>;
|
|
120
|
+
}>, Schema.Struct<{
|
|
121
|
+
readonly type: Schema.Literal<"score">;
|
|
122
|
+
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>>]>;
|
|
123
|
+
readonly criteria: Schema.$Array<Schema.String>;
|
|
124
|
+
}>, Schema.Struct<{
|
|
125
|
+
readonly type: Schema.Literal<"noul">;
|
|
126
|
+
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>>]>;
|
|
127
|
+
readonly criteria: Schema.optionalKey<Schema.Struct<{
|
|
128
|
+
readonly true: Schema.optionalKey<Schema.String>;
|
|
129
|
+
readonly false: Schema.optionalKey<Schema.String>;
|
|
130
|
+
}>>;
|
|
131
|
+
}>]>>;
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Evaluation input. Keep question literals with `satisfies Questions` when
|
|
135
|
+
* storing questions separately from the call to `evaluate`.
|
|
136
|
+
*
|
|
137
|
+
* @category models
|
|
138
|
+
* @since 0.1.0
|
|
139
|
+
*/
|
|
140
|
+
export type EvaluateRequest<Q extends Questions = Questions> = Omit<typeof EvaluateRequest.Type, "questions"> & {
|
|
141
|
+
readonly questions: Q;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* A finite probability or confidence in the inclusive range [0, 1].
|
|
145
|
+
*
|
|
146
|
+
* @category schemas
|
|
147
|
+
* @since 0.1.0
|
|
148
|
+
*/
|
|
149
|
+
export declare const Probability: Schema.Finite;
|
|
150
|
+
/**
|
|
151
|
+
* A selected option and its full distribution. Confidence summarizes the
|
|
152
|
+
* distribution; it does not guarantee correctness.
|
|
153
|
+
*
|
|
154
|
+
* @category schemas
|
|
155
|
+
* @since 0.1.0
|
|
156
|
+
*/
|
|
157
|
+
export declare const ChoiceAnswer: Schema.Struct<{
|
|
158
|
+
readonly type: Schema.Literal<"choice">;
|
|
159
|
+
readonly choice: Schema.String;
|
|
160
|
+
readonly probabilities: Schema.$Record<Schema.String, Schema.Finite>;
|
|
161
|
+
readonly confidence: Schema.Finite;
|
|
162
|
+
}>;
|
|
163
|
+
/**
|
|
164
|
+
* Known option unions infer literal choices and required probability keys.
|
|
165
|
+
* Open string or template-pattern option types allow absent dictionary entries.
|
|
166
|
+
*
|
|
167
|
+
* @category models
|
|
168
|
+
* @since 0.1.0
|
|
169
|
+
*/
|
|
170
|
+
export type ChoiceAnswer<Choice extends string = string> = Omit<typeof ChoiceAnswer.Type, "choice" | "probabilities"> & {
|
|
171
|
+
readonly choice: Choice;
|
|
172
|
+
readonly probabilities: { readonly [K in Choice]: {} extends Pick<Record<Choice, unknown>, K> ? number | undefined : number; };
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* A fractional, probability-weighted level, with the supplied rubric as legend.
|
|
176
|
+
*
|
|
177
|
+
* @category schemas
|
|
178
|
+
* @since 0.1.0
|
|
179
|
+
*/
|
|
180
|
+
export declare const ScoreAnswer: Schema.Struct<{
|
|
181
|
+
readonly type: Schema.Literal<"score">;
|
|
182
|
+
readonly score: Schema.Finite;
|
|
183
|
+
readonly legend: Schema.$Record<Schema.String, Schema.String>;
|
|
184
|
+
readonly probabilities: Schema.$Record<Schema.String, Schema.Finite>;
|
|
185
|
+
readonly confidence: Schema.Finite;
|
|
186
|
+
}>;
|
|
187
|
+
/**
|
|
188
|
+
* Score levels are keyed at runtime; an arbitrary legend or probability lookup
|
|
189
|
+
* may be absent.
|
|
190
|
+
*
|
|
191
|
+
* @category models
|
|
192
|
+
* @since 0.1.0
|
|
193
|
+
*/
|
|
194
|
+
export type ScoreAnswer = Omit<typeof ScoreAnswer.Type, "legend" | "probabilities"> & {
|
|
195
|
+
readonly legend: {
|
|
196
|
+
readonly [level: string]: string | undefined;
|
|
197
|
+
};
|
|
198
|
+
readonly probabilities: {
|
|
199
|
+
readonly [level: string]: number | undefined;
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* The probability of yes. Noul has no separate confidence field.
|
|
204
|
+
*
|
|
205
|
+
* @category schemas
|
|
206
|
+
* @since 0.1.0
|
|
207
|
+
*/
|
|
208
|
+
export declare const NoulAnswer: Schema.Struct<{
|
|
209
|
+
readonly type: Schema.Literal<"noul">;
|
|
210
|
+
readonly noul: Schema.Finite;
|
|
211
|
+
}>;
|
|
212
|
+
/** @category models
|
|
213
|
+
* @since 0.1.0
|
|
214
|
+
*/
|
|
215
|
+
export type NoulAnswer = typeof NoulAnswer.Type;
|
|
216
|
+
/** @category schemas
|
|
217
|
+
* @since 0.1.0
|
|
218
|
+
*/
|
|
219
|
+
export declare const Answer: Schema.Union<readonly [Schema.Struct<{
|
|
220
|
+
readonly type: Schema.Literal<"choice">;
|
|
221
|
+
readonly choice: Schema.String;
|
|
222
|
+
readonly probabilities: Schema.$Record<Schema.String, Schema.Finite>;
|
|
223
|
+
readonly confidence: Schema.Finite;
|
|
224
|
+
}>, Schema.Struct<{
|
|
225
|
+
readonly type: Schema.Literal<"score">;
|
|
226
|
+
readonly score: Schema.Finite;
|
|
227
|
+
readonly legend: Schema.$Record<Schema.String, Schema.String>;
|
|
228
|
+
readonly probabilities: Schema.$Record<Schema.String, Schema.Finite>;
|
|
229
|
+
readonly confidence: Schema.Finite;
|
|
230
|
+
}>, Schema.Struct<{
|
|
231
|
+
readonly type: Schema.Literal<"noul">;
|
|
232
|
+
readonly noul: Schema.Finite;
|
|
233
|
+
}>]>;
|
|
234
|
+
/** @category models
|
|
235
|
+
* @since 0.1.0
|
|
236
|
+
*/
|
|
237
|
+
export type Answer = ChoiceAnswer | ScoreAnswer | NoulAnswer;
|
|
238
|
+
/** @category schemas
|
|
239
|
+
* @since 0.1.0
|
|
240
|
+
*/
|
|
241
|
+
export declare const Usage: Schema.Struct<{
|
|
242
|
+
readonly input_tokens: Schema.Natural;
|
|
243
|
+
readonly output_tokens: Schema.Natural;
|
|
244
|
+
}>;
|
|
245
|
+
/** @category models
|
|
246
|
+
* @since 0.1.0
|
|
247
|
+
*/
|
|
248
|
+
export type Usage = typeof Usage.Type;
|
|
249
|
+
/**
|
|
250
|
+
* The wire response shape. `TypeSafeClient.evaluate` additionally validates
|
|
251
|
+
* answer IDs, question kinds, criteria, distributions, and score correlations.
|
|
252
|
+
*
|
|
253
|
+
* @category schemas
|
|
254
|
+
* @since 0.1.0
|
|
255
|
+
*/
|
|
256
|
+
export declare const EvaluateResponse: Schema.Struct<{
|
|
257
|
+
readonly model: Schema.String;
|
|
258
|
+
readonly answers: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.Struct<{
|
|
259
|
+
readonly type: Schema.Literal<"choice">;
|
|
260
|
+
readonly choice: Schema.String;
|
|
261
|
+
readonly probabilities: Schema.$Record<Schema.String, Schema.Finite>;
|
|
262
|
+
readonly confidence: Schema.Finite;
|
|
263
|
+
}>, Schema.Struct<{
|
|
264
|
+
readonly type: Schema.Literal<"score">;
|
|
265
|
+
readonly score: Schema.Finite;
|
|
266
|
+
readonly legend: Schema.$Record<Schema.String, Schema.String>;
|
|
267
|
+
readonly probabilities: Schema.$Record<Schema.String, Schema.Finite>;
|
|
268
|
+
readonly confidence: Schema.Finite;
|
|
269
|
+
}>, Schema.Struct<{
|
|
270
|
+
readonly type: Schema.Literal<"noul">;
|
|
271
|
+
readonly noul: Schema.Finite;
|
|
272
|
+
}>]>>;
|
|
273
|
+
readonly usage: Schema.Struct<{
|
|
274
|
+
readonly input_tokens: Schema.Natural;
|
|
275
|
+
readonly output_tokens: Schema.Natural;
|
|
276
|
+
}>;
|
|
277
|
+
}>;
|
|
278
|
+
type ChoiceAnswerFor<Criteria> = Criteria extends unknown ? Omit<typeof ChoiceAnswer.Type, "choice" | "probabilities"> & {
|
|
279
|
+
readonly choice: `${Extract<keyof Criteria, string | number>}`;
|
|
280
|
+
readonly probabilities: { readonly [K in keyof Criteria as K extends string | number ? `${K}` : never]: {} extends Pick<Criteria, K> ? number | undefined : number; };
|
|
281
|
+
} : never;
|
|
282
|
+
/**
|
|
283
|
+
* Infer a question's answer, preserving optional choice criteria in its probabilities.
|
|
284
|
+
*
|
|
285
|
+
* @category models
|
|
286
|
+
* @since 0.1.0
|
|
287
|
+
*/
|
|
288
|
+
export type AnswerFor<Q extends Question> = Q extends ChoiceQuestion ? ChoiceAnswerFor<Q["criteria"]> : Q extends ScoreQuestion ? ScoreAnswer : NoulAnswer;
|
|
289
|
+
/**
|
|
290
|
+
* One answer for each required question. Optional properties and open string,
|
|
291
|
+
* numeric, or template-pattern indexes require checking an entry for absence.
|
|
292
|
+
*
|
|
293
|
+
* @category models
|
|
294
|
+
* @since 0.1.0
|
|
295
|
+
*/
|
|
296
|
+
export type Answers<Q extends Questions> = { readonly [K in keyof Q as K extends string | number ? `${K}` : never]: {} extends Pick<Q, K> ? AnswerFor<NonNullable<Q[K]>> | undefined : AnswerFor<Q[K]>; };
|
|
297
|
+
/** @category models
|
|
298
|
+
* @since 0.1.0
|
|
299
|
+
*/
|
|
300
|
+
export type EvaluateResponse<Q extends Questions = Questions> = Omit<typeof EvaluateResponse.Type, "answers"> & {
|
|
301
|
+
readonly answers: Answers<Q>;
|
|
302
|
+
};
|
|
303
|
+
//#endregion
|
|
304
|
+
export { TypeSafeSchema_d_exports as t };
|
|
305
|
+
//# sourceMappingURL=TypeSafeSchema.d.mts.map
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
//#region src/TypeSafeSchema.ts
|
|
4
|
+
/**
|
|
5
|
+
* Request and response schemas for TypeSafe's System One HTTP API.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.1.0
|
|
8
|
+
*/
|
|
9
|
+
var TypeSafeSchema_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
Answer: () => Answer,
|
|
11
|
+
ChoiceAnswer: () => ChoiceAnswer,
|
|
12
|
+
ChoiceQuestion: () => ChoiceQuestion,
|
|
13
|
+
Content: () => Content,
|
|
14
|
+
EvaluateRequest: () => EvaluateRequest,
|
|
15
|
+
EvaluateResponse: () => EvaluateResponse,
|
|
16
|
+
NoulAnswer: () => NoulAnswer,
|
|
17
|
+
NoulQuestion: () => NoulQuestion,
|
|
18
|
+
Probability: () => Probability,
|
|
19
|
+
Question: () => Question,
|
|
20
|
+
Questions: () => Questions,
|
|
21
|
+
ScoreAnswer: () => ScoreAnswer,
|
|
22
|
+
ScoreQuestion: () => ScoreQuestion,
|
|
23
|
+
Usage: () => Usage
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Text or JSON objects and arrays used as state and question instructions.
|
|
27
|
+
*
|
|
28
|
+
* @category schemas
|
|
29
|
+
* @since 0.1.0
|
|
30
|
+
*/
|
|
31
|
+
const Content = Schema.Union([
|
|
32
|
+
Schema.String,
|
|
33
|
+
Schema.JsonObject,
|
|
34
|
+
Schema.Array(Schema.Json)
|
|
35
|
+
]);
|
|
36
|
+
/**
|
|
37
|
+
* A choice between named options. A null rubric uses the option name alone.
|
|
38
|
+
*
|
|
39
|
+
* @category schemas
|
|
40
|
+
* @since 0.1.0
|
|
41
|
+
*/
|
|
42
|
+
const ChoiceQuestion = Schema.Struct({
|
|
43
|
+
type: Schema.Literal("choice"),
|
|
44
|
+
instructions: Content,
|
|
45
|
+
criteria: Schema.Record(Schema.String, Schema.NullOr(Schema.String)).check(Schema.isMinProperties(1))
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* A rating along at least two ordered, zero-indexed level descriptions.
|
|
49
|
+
*
|
|
50
|
+
* @category schemas
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
*/
|
|
53
|
+
const ScoreQuestion = Schema.Struct({
|
|
54
|
+
type: Schema.Literal("score"),
|
|
55
|
+
instructions: Content,
|
|
56
|
+
criteria: Schema.Array(Schema.String).check(Schema.isMinLength(2))
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* A yes/no judgment, with optional descriptions of either outcome.
|
|
60
|
+
*
|
|
61
|
+
* @category schemas
|
|
62
|
+
* @since 0.1.0
|
|
63
|
+
*/
|
|
64
|
+
const NoulQuestion = Schema.Struct({
|
|
65
|
+
type: Schema.Literal("noul"),
|
|
66
|
+
instructions: Content,
|
|
67
|
+
criteria: Schema.optionalKey(Schema.Struct({
|
|
68
|
+
true: Schema.optionalKey(Schema.String),
|
|
69
|
+
false: Schema.optionalKey(Schema.String)
|
|
70
|
+
}))
|
|
71
|
+
});
|
|
72
|
+
/** @category schemas
|
|
73
|
+
* @since 0.1.0
|
|
74
|
+
*/
|
|
75
|
+
const Question = Schema.Union([
|
|
76
|
+
ChoiceQuestion,
|
|
77
|
+
ScoreQuestion,
|
|
78
|
+
NoulQuestion
|
|
79
|
+
]);
|
|
80
|
+
/** @category schemas
|
|
81
|
+
* @since 0.1.0
|
|
82
|
+
*/
|
|
83
|
+
const Questions = Schema.Record(Schema.String, Question);
|
|
84
|
+
/** @category schemas
|
|
85
|
+
* @since 0.1.0
|
|
86
|
+
*/
|
|
87
|
+
const EvaluateRequest = Schema.Struct({
|
|
88
|
+
model: Schema.String,
|
|
89
|
+
state: Content,
|
|
90
|
+
questions: Questions
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* A finite probability or confidence in the inclusive range [0, 1].
|
|
94
|
+
*
|
|
95
|
+
* @category schemas
|
|
96
|
+
* @since 0.1.0
|
|
97
|
+
*/
|
|
98
|
+
const Probability = Schema.Finite.check(Schema.isBetween({
|
|
99
|
+
minimum: 0,
|
|
100
|
+
maximum: 1
|
|
101
|
+
}));
|
|
102
|
+
/**
|
|
103
|
+
* A selected option and its full distribution. Confidence summarizes the
|
|
104
|
+
* distribution; it does not guarantee correctness.
|
|
105
|
+
*
|
|
106
|
+
* @category schemas
|
|
107
|
+
* @since 0.1.0
|
|
108
|
+
*/
|
|
109
|
+
const ChoiceAnswer = Schema.Struct({
|
|
110
|
+
type: Schema.Literal("choice"),
|
|
111
|
+
choice: Schema.String,
|
|
112
|
+
probabilities: Schema.Record(Schema.String, Probability),
|
|
113
|
+
confidence: Probability
|
|
114
|
+
});
|
|
115
|
+
/**
|
|
116
|
+
* A fractional, probability-weighted level, with the supplied rubric as legend.
|
|
117
|
+
*
|
|
118
|
+
* @category schemas
|
|
119
|
+
* @since 0.1.0
|
|
120
|
+
*/
|
|
121
|
+
const ScoreAnswer = Schema.Struct({
|
|
122
|
+
type: Schema.Literal("score"),
|
|
123
|
+
score: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
124
|
+
legend: Schema.Record(Schema.String, Schema.String),
|
|
125
|
+
probabilities: Schema.Record(Schema.String, Probability),
|
|
126
|
+
confidence: Probability
|
|
127
|
+
});
|
|
128
|
+
/**
|
|
129
|
+
* The probability of yes. Noul has no separate confidence field.
|
|
130
|
+
*
|
|
131
|
+
* @category schemas
|
|
132
|
+
* @since 0.1.0
|
|
133
|
+
*/
|
|
134
|
+
const NoulAnswer = Schema.Struct({
|
|
135
|
+
type: Schema.Literal("noul"),
|
|
136
|
+
noul: Probability
|
|
137
|
+
});
|
|
138
|
+
/** @category schemas
|
|
139
|
+
* @since 0.1.0
|
|
140
|
+
*/
|
|
141
|
+
const Answer = Schema.Union([
|
|
142
|
+
ChoiceAnswer,
|
|
143
|
+
ScoreAnswer,
|
|
144
|
+
NoulAnswer
|
|
145
|
+
]);
|
|
146
|
+
/** @category schemas
|
|
147
|
+
* @since 0.1.0
|
|
148
|
+
*/
|
|
149
|
+
const Usage = Schema.Struct({
|
|
150
|
+
input_tokens: Schema.Natural,
|
|
151
|
+
output_tokens: Schema.Natural
|
|
152
|
+
});
|
|
153
|
+
/**
|
|
154
|
+
* The wire response shape. `TypeSafeClient.evaluate` additionally validates
|
|
155
|
+
* answer IDs, question kinds, criteria, distributions, and score correlations.
|
|
156
|
+
*
|
|
157
|
+
* @category schemas
|
|
158
|
+
* @since 0.1.0
|
|
159
|
+
*/
|
|
160
|
+
const EvaluateResponse = Schema.Struct({
|
|
161
|
+
model: Schema.String,
|
|
162
|
+
answers: Schema.Record(Schema.String, Answer),
|
|
163
|
+
usage: Usage
|
|
164
|
+
});
|
|
165
|
+
//#endregion
|
|
166
|
+
export { Answer, ChoiceAnswer, ChoiceQuestion, Content, EvaluateRequest, EvaluateResponse, NoulAnswer, NoulQuestion, Probability, Question, Questions, ScoreAnswer, ScoreQuestion, Usage, TypeSafeSchema_exports as t };
|
|
167
|
+
|
|
168
|
+
//# sourceMappingURL=TypeSafeSchema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypeSafeSchema.mjs","names":[],"sources":["../src/TypeSafeSchema.ts"],"sourcesContent":["/**\n * Request and response schemas for TypeSafe's System One HTTP API.\n *\n * @since 0.1.0\n */\nimport * as Schema from \"effect/Schema\";\n\n/**\n * Text or JSON objects and arrays used as state and question instructions.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Content = Schema.Union([Schema.String, Schema.JsonObject, Schema.Array(Schema.Json)]);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Content = typeof Content.Type;\n\n/**\n * A choice between named options. A null rubric uses the option name alone.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ChoiceQuestion = Schema.Struct({\n type: Schema.Literal(\"choice\"),\n instructions: Content,\n criteria: Schema.Record(Schema.String, Schema.NullOr(Schema.String)).check(\n Schema.isMinProperties(1),\n ),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type ChoiceQuestion = typeof ChoiceQuestion.Type;\n\n/**\n * A rating along at least two ordered, zero-indexed level descriptions.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ScoreQuestion = Schema.Struct({\n type: Schema.Literal(\"score\"),\n instructions: Content,\n criteria: Schema.Array(Schema.String).check(Schema.isMinLength(2)),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type ScoreQuestion = typeof ScoreQuestion.Type;\n\n/**\n * A yes/no judgment, with optional descriptions of either outcome.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const NoulQuestion = Schema.Struct({\n type: Schema.Literal(\"noul\"),\n instructions: Content,\n criteria: Schema.optionalKey(\n Schema.Struct({\n true: Schema.optionalKey(Schema.String),\n false: Schema.optionalKey(Schema.String),\n }),\n ),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type NoulQuestion = typeof NoulQuestion.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Question = Schema.Union([ChoiceQuestion, ScoreQuestion, NoulQuestion]);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Question = typeof Question.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Questions = Schema.Record(Schema.String, Question);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Questions = typeof Questions.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const EvaluateRequest = Schema.Struct({\n model: Schema.String,\n state: Content,\n questions: Questions,\n});\n\n/**\n * Evaluation input. Keep question literals with `satisfies Questions` when\n * storing questions separately from the call to `evaluate`.\n *\n * @category models\n * @since 0.1.0\n */\nexport type EvaluateRequest<Q extends Questions = Questions> = Omit<\n typeof EvaluateRequest.Type,\n \"questions\"\n> & { readonly questions: Q };\n\n/**\n * A finite probability or confidence in the inclusive range [0, 1].\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Probability = Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 1 }));\n\n/**\n * A selected option and its full distribution. Confidence summarizes the\n * distribution; it does not guarantee correctness.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ChoiceAnswer = Schema.Struct({\n type: Schema.Literal(\"choice\"),\n choice: Schema.String,\n probabilities: Schema.Record(Schema.String, Probability),\n confidence: Probability,\n});\n\n/**\n * Known option unions infer literal choices and required probability keys.\n * Open string or template-pattern option types allow absent dictionary entries.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ChoiceAnswer<Choice extends string = string> = Omit<\n typeof ChoiceAnswer.Type,\n \"choice\" | \"probabilities\"\n> & {\n readonly choice: Choice;\n readonly probabilities: {\n readonly [K in Choice]: {} extends Pick<Record<Choice, unknown>, K>\n ? number | undefined\n : number;\n };\n};\n\n/**\n * A fractional, probability-weighted level, with the supplied rubric as legend.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ScoreAnswer = Schema.Struct({\n type: Schema.Literal(\"score\"),\n score: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),\n legend: Schema.Record(Schema.String, Schema.String),\n probabilities: Schema.Record(Schema.String, Probability),\n confidence: Probability,\n});\n\n/**\n * Score levels are keyed at runtime; an arbitrary legend or probability lookup\n * may be absent.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ScoreAnswer = Omit<typeof ScoreAnswer.Type, \"legend\" | \"probabilities\"> & {\n readonly legend: { readonly [level: string]: string | undefined };\n readonly probabilities: { readonly [level: string]: number | undefined };\n};\n\n/**\n * The probability of yes. Noul has no separate confidence field.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const NoulAnswer = Schema.Struct({ type: Schema.Literal(\"noul\"), noul: Probability });\n\n/** @category models\n * @since 0.1.0\n */\nexport type NoulAnswer = typeof NoulAnswer.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Answer = Schema.Union([ChoiceAnswer, ScoreAnswer, NoulAnswer]);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Answer = ChoiceAnswer | ScoreAnswer | NoulAnswer;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Usage = Schema.Struct({ input_tokens: Schema.Natural, output_tokens: Schema.Natural });\n\n/** @category models\n * @since 0.1.0\n */\nexport type Usage = typeof Usage.Type;\n\n/**\n * The wire response shape. `TypeSafeClient.evaluate` additionally validates\n * answer IDs, question kinds, criteria, distributions, and score correlations.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const EvaluateResponse = Schema.Struct({\n model: Schema.String,\n answers: Schema.Record(Schema.String, Answer),\n usage: Usage,\n});\n\ntype ChoiceAnswerFor<Criteria> = Criteria extends unknown\n ? Omit<typeof ChoiceAnswer.Type, \"choice\" | \"probabilities\"> & {\n readonly choice: `${Extract<keyof Criteria, string | number>}`;\n readonly probabilities: {\n readonly [\n K in keyof Criteria as K extends string | number ? `${K}` : never\n ]: {} extends Pick<Criteria, K> ? number | undefined : number;\n };\n }\n : never;\n\n/**\n * Infer a question's answer, preserving optional choice criteria in its probabilities.\n *\n * @category models\n * @since 0.1.0\n */\nexport type AnswerFor<Q extends Question> = Q extends ChoiceQuestion\n ? ChoiceAnswerFor<Q[\"criteria\"]>\n : Q extends ScoreQuestion\n ? ScoreAnswer\n : NoulAnswer;\n\n/**\n * One answer for each required question. Optional properties and open string,\n * numeric, or template-pattern indexes require checking an entry for absence.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Answers<Q extends Questions> = {\n readonly [K in keyof Q as K extends string | number ? `${K}` : never]: {} extends Pick<Q, K>\n ? AnswerFor<NonNullable<Q[K]>> | undefined\n : AnswerFor<Q[K]>;\n};\n\n/** @category models\n * @since 0.1.0\n */\nexport type EvaluateResponse<Q extends Questions = Questions> = Omit<\n typeof EvaluateResponse.Type,\n \"answers\"\n> & { readonly answers: Answers<Q> };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,MAAa,UAAU,OAAO,MAAM;CAAC,OAAO;CAAQ,OAAO;CAAY,OAAO,MAAM,OAAO,IAAI;AAAC,CAAC;;;;;;;AAajG,MAAa,iBAAiB,OAAO,OAAO;CAC1C,MAAM,OAAO,QAAQ,QAAQ;CAC7B,cAAc;CACd,UAAU,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,CAAC,MACnE,OAAO,gBAAgB,CAAC,CAC1B;AACF,CAAC;;;;;;;AAaD,MAAa,gBAAgB,OAAO,OAAO;CACzC,MAAM,OAAO,QAAQ,OAAO;CAC5B,cAAc;CACd,UAAU,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AACnE,CAAC;;;;;;;AAaD,MAAa,eAAe,OAAO,OAAO;CACxC,MAAM,OAAO,QAAQ,MAAM;CAC3B,cAAc;CACd,UAAU,OAAO,YACf,OAAO,OAAO;EACZ,MAAM,OAAO,YAAY,OAAO,MAAM;EACtC,OAAO,OAAO,YAAY,OAAO,MAAM;CACzC,CAAC,CACH;AACF,CAAC;;;;AAUD,MAAa,WAAW,OAAO,MAAM;CAAC;CAAgB;CAAe;AAAY,CAAC;;;;AAUlF,MAAa,YAAY,OAAO,OAAO,OAAO,QAAQ,QAAQ;;;;AAU9D,MAAa,kBAAkB,OAAO,OAAO;CAC3C,OAAO,OAAO;CACd,OAAO;CACP,WAAW;AACb,CAAC;;;;;;;AAoBD,MAAa,cAAc,OAAO,OAAO,MAAM,OAAO,UAAU;CAAE,SAAS;CAAG,SAAS;AAAE,CAAC,CAAC;;;;;;;;AAS3F,MAAa,eAAe,OAAO,OAAO;CACxC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,QAAQ,OAAO;CACf,eAAe,OAAO,OAAO,OAAO,QAAQ,WAAW;CACvD,YAAY;AACd,CAAC;;;;;;;AA2BD,MAAa,cAAc,OAAO,OAAO;CACvC,MAAM,OAAO,QAAQ,OAAO;CAC5B,OAAO,OAAO,OAAO,MAAM,OAAO,uBAAuB,CAAC,CAAC;CAC3D,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,MAAM;CAClD,eAAe,OAAO,OAAO,OAAO,QAAQ,WAAW;CACvD,YAAY;AACd,CAAC;;;;;;;AAoBD,MAAa,aAAa,OAAO,OAAO;CAAE,MAAM,OAAO,QAAQ,MAAM;CAAG,MAAM;AAAY,CAAC;;;;AAU3F,MAAa,SAAS,OAAO,MAAM;CAAC;CAAc;CAAa;AAAU,CAAC;;;;AAU1E,MAAa,QAAQ,OAAO,OAAO;CAAE,cAAc,OAAO;CAAS,eAAe,OAAO;AAAQ,CAAC;;;;;;;;AAclG,MAAa,mBAAmB,OAAO,OAAO;CAC5C,OAAO,OAAO;CACd,SAAS,OAAO,OAAO,OAAO,QAAQ,MAAM;CAC5C,OAAO;AACT,CAAC"}
|
package/dist/index.d.mts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"@effect-agent/ai-typesafe","version":"0.1.0-beta.100","devDependencies":{"@effect/vitest":"4.0.0-rc.115","effect":"4.0.0-rc.115","typescript":"7.0.2","vite-plus":"0.3.2"},"peerDependencies":{"effect":"^4.0.0-rc.115"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./type-safe-client":{"types":"./dist/TypeSafeClient.d.mts","default":"./dist/TypeSafeClient.mjs"},"./type-safe-schema":{"types":"./dist/TypeSafeSchema.d.mts","default":"./dist/TypeSafeSchema.mjs"}},"description":"TypeSafe AI evaluation with Effect HttpClient and request-derived answer types.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/ai-typesafe"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test"}}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An Effect HttpClient integration for TypeSafe's System One evaluations.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
import * as Config from "effect/Config";
|
|
7
|
+
import * as Context from "effect/Context";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import { flow, identity } from "effect/Function";
|
|
10
|
+
import * as Layer from "effect/Layer";
|
|
11
|
+
import * as Redacted from "effect/Redacted";
|
|
12
|
+
import * as Schema from "effect/Schema";
|
|
13
|
+
import * as AiError from "effect/unstable/ai/AiError";
|
|
14
|
+
import * as Headers from "effect/unstable/http/Headers";
|
|
15
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
16
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
17
|
+
import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
|
|
18
|
+
|
|
19
|
+
import * as Errors from "./internal/errors.ts";
|
|
20
|
+
import { responseFor } from "./internal/schema.ts";
|
|
21
|
+
import * as TypeSafeSchema from "./TypeSafeSchema.ts";
|
|
22
|
+
|
|
23
|
+
/** @category services
|
|
24
|
+
* @since 0.1.0
|
|
25
|
+
*/
|
|
26
|
+
export interface Service {
|
|
27
|
+
readonly client: HttpClient.HttpClient;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Evaluate mixed questions against one state. Answers are validated against
|
|
31
|
+
* the submitted IDs, types, and criteria before receiving their inferred type.
|
|
32
|
+
* There are no automatic retries or timeouts; compose those with Effect.
|
|
33
|
+
*/
|
|
34
|
+
readonly evaluate: <const Q extends TypeSafeSchema.Questions>(
|
|
35
|
+
options: TypeSafeSchema.EvaluateRequest<Q>,
|
|
36
|
+
) => Effect.Effect<TypeSafeSchema.EvaluateResponse<Q>, AiError.AiError>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @category services
|
|
40
|
+
* @since 0.1.0
|
|
41
|
+
*/
|
|
42
|
+
export class TypeSafeClient extends Context.Service<TypeSafeClient, Service>()(
|
|
43
|
+
"@effect-agent/ai-typesafe/TypeSafeClient",
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
/** @category options
|
|
47
|
+
* @since 0.1.0
|
|
48
|
+
*/
|
|
49
|
+
export interface Options {
|
|
50
|
+
readonly apiKey: Redacted.Redacted<string>;
|
|
51
|
+
/** Base URL, including the API version. Defaults to https://api.typesafe.ai/v1. */
|
|
52
|
+
readonly apiUrl?: string | undefined;
|
|
53
|
+
/** Applied after authentication and status filtering, for explicit HTTP policies. */
|
|
54
|
+
readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const encodeRequest = Schema.encodeEffect(Schema.fromJsonString(TypeSafeSchema.EvaluateRequest));
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Construct the client using a supplied, platform-neutral HttpClient.
|
|
61
|
+
* Acquiring the service does not send a request.
|
|
62
|
+
*
|
|
63
|
+
* @category constructors
|
|
64
|
+
* @since 0.1.0
|
|
65
|
+
*/
|
|
66
|
+
export const make = Effect.fnUntraced(function* (
|
|
67
|
+
options: Options,
|
|
68
|
+
): Effect.fn.Return<Service, never, HttpClient.HttpClient> {
|
|
69
|
+
const apiKey = Redacted.value(options.apiKey);
|
|
70
|
+
|
|
71
|
+
const redact = (text: string) =>
|
|
72
|
+
apiKey.length === 0 ? text : text.replaceAll(apiKey, "<redacted>");
|
|
73
|
+
|
|
74
|
+
const client = (yield* HttpClient.HttpClient).pipe(
|
|
75
|
+
HttpClient.mapRequest(
|
|
76
|
+
flow(
|
|
77
|
+
HttpClientRequest.prependUrl(options.apiUrl ?? "https://api.typesafe.ai/v1"),
|
|
78
|
+
HttpClientRequest.bearerToken(options.apiKey),
|
|
79
|
+
HttpClientRequest.acceptJson,
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
HttpClient.filterStatusOk,
|
|
83
|
+
options.transformClient ?? identity,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const evaluate = Effect.fnUntraced(function* <const Q extends TypeSafeSchema.Questions>(
|
|
87
|
+
options: TypeSafeSchema.EvaluateRequest<Q>,
|
|
88
|
+
): Effect.fn.Return<TypeSafeSchema.EvaluateResponse<Q>, AiError.AiError> {
|
|
89
|
+
const body = yield* encodeRequest(options).pipe(
|
|
90
|
+
Effect.mapError((error) =>
|
|
91
|
+
Errors.make(new AiError.InvalidRequestError({ description: redact(error.message) })),
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const schema = responseFor(options.questions);
|
|
96
|
+
|
|
97
|
+
return yield* client
|
|
98
|
+
.execute(
|
|
99
|
+
HttpClientRequest.post("/systemone").pipe(
|
|
100
|
+
HttpClientRequest.bodyText(body, "application/json"),
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
.pipe(
|
|
104
|
+
Effect.flatMap(HttpClientResponse.schemaBodyJson(schema, { onExcessProperty: "error" })),
|
|
105
|
+
Effect.catchTags({
|
|
106
|
+
HttpClientError: (error) => Errors.mapHttpClientError(error, redact),
|
|
107
|
+
SchemaError: (error) => Effect.fail(Errors.mapSchemaError(error, redact)),
|
|
108
|
+
}),
|
|
109
|
+
Effect.updateService(Headers.CurrentRedactedNames, (names) => [...names, "authorization"]),
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return TypeSafeClient.of({ client, evaluate });
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
/** @category layers
|
|
117
|
+
* @since 0.1.0
|
|
118
|
+
*/
|
|
119
|
+
export const layer = (
|
|
120
|
+
options: Options,
|
|
121
|
+
): Layer.Layer<TypeSafeClient, never, HttpClient.HttpClient> =>
|
|
122
|
+
Layer.effect(TypeSafeClient, make(options));
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Configure the client with Effect Config. The API key defaults to
|
|
126
|
+
* `Config.Redacted("TYPESAFE_API_KEY")`.
|
|
127
|
+
*
|
|
128
|
+
* @category layers
|
|
129
|
+
* @since 0.1.0
|
|
130
|
+
*/
|
|
131
|
+
export const layerConfig = (options?: {
|
|
132
|
+
readonly apiKey?: Config.Config<Redacted.Redacted<string>> | undefined;
|
|
133
|
+
readonly apiUrl?: Config.Config<string> | undefined;
|
|
134
|
+
readonly transformClient?: Options["transformClient"];
|
|
135
|
+
}): Layer.Layer<TypeSafeClient, Config.ConfigError, HttpClient.HttpClient> =>
|
|
136
|
+
Layer.effect(
|
|
137
|
+
TypeSafeClient,
|
|
138
|
+
Effect.gen(function* () {
|
|
139
|
+
return yield* make({
|
|
140
|
+
apiKey: yield* options?.apiKey ?? Config.Redacted("TYPESAFE_API_KEY"),
|
|
141
|
+
apiUrl: options?.apiUrl === undefined ? undefined : yield* options.apiUrl,
|
|
142
|
+
transformClient: options?.transformClient,
|
|
143
|
+
});
|
|
144
|
+
}),
|
|
145
|
+
);
|