feat(core): flatten provider config and load native packages (#35563)
Co-authored-by: Dax Raad <d@ironbay.co>
This commit is contained in:
parent
d603eed5a1
commit
e57d9ca390
107 changed files with 2593 additions and 1984 deletions
|
|
@ -1,9 +1,8 @@
|
|||
export * as Model from "./model.js"
|
||||
|
||||
import { Schema } from "effect"
|
||||
import { optional } from "./schema.js"
|
||||
import { optional, statics } from "./schema.js"
|
||||
import { Provider } from "./provider.js"
|
||||
import { statics } from "./schema.js"
|
||||
|
||||
export const ID = Schema.String.pipe(Schema.brand("ModelV2.ID"))
|
||||
export type ID = typeof ID.Type
|
||||
|
|
@ -42,36 +41,23 @@ export const Cost = Schema.Struct({
|
|||
}),
|
||||
}).annotate({ identifier: "Model.Cost" })
|
||||
|
||||
export const Api = Schema.Union([
|
||||
Schema.Struct({
|
||||
id: ID,
|
||||
...Provider.AISDK.fields,
|
||||
}),
|
||||
Schema.Struct({
|
||||
id: ID,
|
||||
...Provider.Native.fields,
|
||||
}),
|
||||
])
|
||||
.pipe(Schema.toTaggedUnion("type"))
|
||||
.annotate({ identifier: "Model.Api" })
|
||||
export type Api = typeof Api.Type
|
||||
export interface Variant extends Schema.Schema.Type<typeof Variant> {}
|
||||
export const Variant = Schema.Struct({
|
||||
id: VariantID,
|
||||
...Provider.Overlays,
|
||||
}).annotate({ identifier: "Model.Variant" })
|
||||
|
||||
export interface Info extends Schema.Schema.Type<typeof Info> {}
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
modelID: ID,
|
||||
providerID: Provider.ID,
|
||||
family: Family.pipe(optional),
|
||||
name: Schema.String,
|
||||
api: Api,
|
||||
package: Provider.Package.pipe(optional),
|
||||
...Provider.Overlays,
|
||||
capabilities: Capabilities,
|
||||
request: Schema.Struct({
|
||||
...Provider.Request.fields,
|
||||
variant: Schema.String.pipe(optional),
|
||||
}),
|
||||
variants: Schema.Struct({
|
||||
id: VariantID,
|
||||
...Provider.Request.fields,
|
||||
}).pipe(Schema.Array),
|
||||
variants: Schema.Array(Variant),
|
||||
time: Schema.Struct({
|
||||
released: Schema.Finite,
|
||||
}),
|
||||
|
|
@ -87,14 +73,13 @@ export const Info = Schema.Struct({
|
|||
.annotate({ identifier: "ModelV2.Info" })
|
||||
.pipe(
|
||||
statics((schema) => ({
|
||||
empty: (providerID: Provider.ID, modelID: ID) =>
|
||||
empty: (providerID: Provider.ID, id: ID) =>
|
||||
schema.make({
|
||||
id: modelID,
|
||||
id,
|
||||
modelID: id,
|
||||
providerID,
|
||||
name: modelID,
|
||||
api: { id: modelID, type: "native", settings: {} },
|
||||
name: id,
|
||||
capabilities: { tools: false, input: [], output: [] },
|
||||
request: { settings: {}, headers: {}, body: {} },
|
||||
variants: [],
|
||||
time: { released: 0 },
|
||||
cost: [],
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
export * as Provider from "./provider.js"
|
||||
|
||||
import { Effect, Schema } from "effect"
|
||||
import { optional } from "./schema.js"
|
||||
import { Integration } from "./integration.js"
|
||||
import { statics } from "./schema.js"
|
||||
import { optional, statics } from "./schema.js"
|
||||
|
||||
export const ID = Schema.String.pipe(
|
||||
Schema.brand("ProviderV2.ID"),
|
||||
|
|
@ -23,27 +22,16 @@ export const ID = Schema.String.pipe(
|
|||
)
|
||||
export type ID = typeof ID.Type
|
||||
|
||||
export interface AISDK extends Schema.Schema.Type<typeof AISDK> {}
|
||||
export const AISDK = Schema.Struct({
|
||||
type: Schema.Literal("aisdk"),
|
||||
package: Schema.String,
|
||||
url: Schema.String.pipe(optional),
|
||||
settings: Schema.Record(Schema.String, Schema.Unknown).pipe(optional),
|
||||
}).annotate({ identifier: "Provider.AISDK" })
|
||||
export const Package = Schema.String
|
||||
export type Package = typeof Package.Type
|
||||
|
||||
export interface Native extends Schema.Schema.Type<typeof Native> {}
|
||||
export const Native = Schema.Struct({
|
||||
type: Schema.Literal("native"),
|
||||
url: Schema.String.pipe(optional),
|
||||
settings: Schema.Record(Schema.String, Schema.Unknown),
|
||||
}).annotate({ identifier: "Provider.Native" })
|
||||
export const Overlays = {
|
||||
settings: Schema.Record(Schema.String, Schema.Json).pipe(optional),
|
||||
headers: Schema.Record(Schema.String, Schema.String).pipe(optional),
|
||||
body: Schema.Record(Schema.String, Schema.Json).pipe(optional),
|
||||
}
|
||||
|
||||
export const Api = Schema.Union([AISDK, Native])
|
||||
.pipe(Schema.toTaggedUnion("type"))
|
||||
.annotate({ identifier: "Provider.Api" })
|
||||
export type Api = typeof Api.Type
|
||||
|
||||
export const Settings = Schema.Record(Schema.String, Schema.Unknown).annotate({ identifier: "Provider.Settings" })
|
||||
export const Settings = Schema.Record(Schema.String, Schema.Json).annotate({ identifier: "Provider.Settings" })
|
||||
export type Settings = typeof Settings.Type
|
||||
|
||||
export interface Request extends Schema.Schema.Type<typeof Request> {}
|
||||
|
|
@ -59,18 +47,12 @@ export const Info = Schema.Struct({
|
|||
integrationID: Integration.ID.pipe(optional),
|
||||
name: Schema.String,
|
||||
disabled: Schema.Boolean.pipe(optional),
|
||||
api: Api,
|
||||
request: Request,
|
||||
package: Package,
|
||||
...Overlays,
|
||||
})
|
||||
.annotate({ identifier: "ProviderV2.Info" })
|
||||
.pipe(
|
||||
statics((schema) => ({
|
||||
empty: (id: ID) =>
|
||||
schema.make({
|
||||
id,
|
||||
name: id,
|
||||
api: { type: "native", settings: {} },
|
||||
request: { settings: {}, headers: {}, body: {} },
|
||||
}),
|
||||
empty: (id: ID) => schema.make({ id, name: id, package: "" }),
|
||||
})),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Agent } from "../src/agent.js"
|
|||
import { FileSystem } from "../src/filesystem.js"
|
||||
import { Model } from "../src/model.js"
|
||||
import { Project } from "../src/project.js"
|
||||
import { Provider } from "../src/provider.js"
|
||||
import { Pty } from "../src/pty.js"
|
||||
import { Question } from "../src/question.js"
|
||||
import { Session } from "../src/session.js"
|
||||
|
|
@ -18,6 +19,19 @@ describe("contract hygiene", () => {
|
|||
expect(Schema.encodeSync(Value)({ value: undefined })).toEqual({})
|
||||
})
|
||||
|
||||
test("model defaults and provider overlays preserve public invariants", () => {
|
||||
const id = Model.ID.make("model")
|
||||
expect(Model.Info.empty(Provider.ID.make("provider"), id)).toMatchObject({ modelID: id, variants: [] })
|
||||
expect(() =>
|
||||
Schema.decodeUnknownSync(Provider.Info)({
|
||||
id: "provider",
|
||||
name: "Provider",
|
||||
package: "native",
|
||||
settings: { invalid: 1n },
|
||||
}),
|
||||
).toThrow()
|
||||
})
|
||||
|
||||
test("todo status and priority preserve arbitrary strings", () => {
|
||||
const decode = Schema.decodeUnknownSync(SessionTodo.Info)
|
||||
expect(decode({ content: "ship", status: "waiting", priority: "urgent" })).toEqual({
|
||||
|
|
@ -39,7 +53,7 @@ describe("contract hygiene", () => {
|
|||
Model.Ref,
|
||||
Model.Capabilities,
|
||||
Model.Cost,
|
||||
Model.Api,
|
||||
Model.Variant,
|
||||
Project.Current,
|
||||
Project.Directory,
|
||||
Project.DirectoriesInput,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue