1import * as Effect from "effect/Effect";
2import * as Schema from "effect/Schema";
3import * as SchemaTransformation from "effect/SchemaTransformation";
4
5import { TrimmedNonEmptyString } from "./baseSchemas.ts";
6import { ProviderOptionSelections } from "./model.ts";
7import { ProviderInstanceId } from "./providerInstance.ts";
8
9const ModelSelectionWire = Schema.Struct({
10 instanceId: ProviderInstanceId,
11 model: TrimmedNonEmptyString,
12 options: Schema.optionalKey(ProviderOptionSelections),
13});
14
15const ModelSelectionSource = Schema.Struct({
16 provider: Schema.optional(Schema.Unknown),
17 instanceId: Schema.optional(Schema.Unknown),
18 model: Schema.Unknown,
19 options: Schema.optional(Schema.Unknown),
20});
21
22export const ModelSelection = ModelSelectionSource.pipe(
23 Schema.decodeTo(
24 ModelSelectionWire,
25 SchemaTransformation.transformEffect({
26 decode: (raw) => {
27 const instanceIdSource =
28 raw.instanceId !== undefined
29 ? raw.instanceId
30 : typeof raw.provider === "string"
31 ? raw.provider
32 : undefined;
33 const base: Record<string, unknown> = {
34 instanceId: instanceIdSource,
35 model: raw.model,
36 };
37 if (raw.options !== undefined) base.options = raw.options;
38 return Effect.succeed(base as typeof ModelSelectionWire.Encoded);
39 },
40 encode: (value) => {
41 const base: Record<string, unknown> = {
42 instanceId: value.instanceId,
43 model: value.model,
44 };
45 if (value.options !== undefined) base.options = value.options;
46 return Effect.succeed(base as typeof ModelSelectionSource.Encoded);
47 },
48 }),
49 ),
50);
51export type ModelSelection = typeof ModelSelection.Type;