chore: generate

This commit is contained in:
opencode-agent[bot]
2026-06-14 12:46:12 +00:00
parent 0cf3ee4406
commit 3ab19bfd7d
8 changed files with 811 additions and 1374 deletions
+1 -5
View File
@@ -93,11 +93,7 @@ export const layer = Layer.effect(
const integrations = yield* Integration.Service const integrations = yield* Integration.Service
const scope = yield* Scope.Scope const scope = yield* Scope.Scope
const available = ( const available = (provider: ProviderV2.Info, integration: Integration.Info | undefined, connected: boolean) => {
provider: ProviderV2.Info,
integration: Integration.Info | undefined,
connected: boolean,
) => {
if (provider.disabled) return false if (provider.disabled) return false
if (typeof provider.request.body.apiKey === "string") return true if (typeof provider.request.body.apiKey === "string") return true
if (connected) return true if (connected) return true
+10 -7
View File
@@ -228,7 +228,10 @@ export interface Interface {
readonly label?: string readonly label?: string
}) => Effect.Effect<Attempt, AuthorizationError> }) => Effect.Effect<Attempt, AuthorizationError>
/** Updates a stored credential exposed as a connection. */ /** Updates a stored credential exposed as a connection. */
readonly update: (credentialID: Credential.ID, updates: Partial<Pick<Credential.Stored, "label">>) => Effect.Effect<void> readonly update: (
credentialID: Credential.ID,
updates: Partial<Pick<Credential.Stored, "label">>,
) => Effect.Effect<void>
/** Removes a stored credential connection. */ /** Removes a stored credential connection. */
readonly remove: (credentialID: Credential.ID) => Effect.Effect<void> readonly remove: (credentialID: Credential.ID) => Effect.Effect<void>
} }
@@ -339,9 +342,11 @@ export const locationLayer = Layer.effect(
}) })
const connections = (entry: Entry, saved: readonly Credential.Stored[]): IntegrationConnection.Info[] => { const connections = (entry: Entry, saved: readonly Credential.Stored[]): IntegrationConnection.Info[] => {
const connected = saved.map( const connected = saved.map((credential) => ({
(credential) => ({ type: "credential" as const, id: credential.id, label: credential.label }), type: "credential" as const,
) id: credential.id,
label: credential.label,
}))
const detected = entry.methods const detected = entry.methods
.filter((method) => method.type === "env") .filter((method) => method.type === "env")
.flatMap((method) => method.names.filter((name) => process.env[name])) .flatMap((method) => method.names.filter((name) => process.env[name]))
@@ -446,9 +451,7 @@ export const locationLayer = Layer.effect(
list: Effect.fn("Integration.connection.list")(function* () { list: Effect.fn("Integration.connection.list")(function* () {
const saved = Map.groupBy(yield* credentials.all(), (credential) => credential.integrationID) const saved = Map.groupBy(yield* credentials.all(), (credential) => credential.integrationID)
return new Map( return new Map(
new Set([...state.get().integrations.keys(), ...saved.keys()]) new Set([...state.get().integrations.keys(), ...saved.keys()]).values().flatMap((id) => {
.values()
.flatMap((id) => {
const connection = activeConnection(state.get().integrations.get(id), saved.get(id) ?? []) const connection = activeConnection(state.get().integrations.get(id), saved.get(id) ?? [])
return connection ? [[id, connection] as const] : [] return connection ? [[id, connection] as const] : []
}), }),
@@ -14,9 +14,7 @@ export const OpencodePlugin = PluginV2.define({
if (!item) return if (!item) return
const integration = yield* integrations.get(Integration.ID.make(item.provider.id)) const integration = yield* integrations.get(Integration.ID.make(item.provider.id))
hasKey = Boolean( hasKey = Boolean(
process.env.OPENCODE_API_KEY || process.env.OPENCODE_API_KEY || integration?.connections.length || item.provider.request.body.apiKey,
integration?.connections.length ||
item.provider.request.body.apiKey,
) )
evt.provider.update(item.provider.id, (provider) => { evt.provider.update(item.provider.id, (provider) => {
if (!hasKey) provider.request.body.apiKey = "public" if (!hasKey) provider.request.body.apiKey = "public"
+1 -5
View File
@@ -48,11 +48,7 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/v2
/** Test or embedding seam for supplying a model resolver directly. */ /** Test or embedding seam for supplying a model resolver directly. */
export const layerWith = (resolve: Interface["resolve"]) => Layer.succeed(Service, Service.of({ resolve })) export const layerWith = (resolve: Interface["resolve"]) => Layer.succeed(Service, Service.of({ resolve }))
const apiKey = ( const apiKey = (model: ModelV2.Info, connection?: IntegrationConnection.Info, credential?: Credential.Stored) => {
model: ModelV2.Info,
connection?: IntegrationConnection.Info,
credential?: Credential.Stored,
) => {
if (credential?.value.type === "key") return Auth.value(credential.value.key) if (credential?.value.type === "key") return Auth.value(credential.value.key)
if (credential?.value.type === "oauth") return Auth.value(credential.value.access) if (credential?.value.type === "oauth") return Auth.value(credential.value.access)
const value = model.request.body.apiKey ?? model.api.settings?.apiKey const value = model.request.body.apiKey ?? model.api.settings?.apiKey
+4 -4
View File
@@ -36,12 +36,12 @@ describe("CatalogV2", () => {
Effect.gen(function* () { Effect.gen(function* () {
const catalog = yield* Catalog.Service const catalog = yield* Catalog.Service
const events = yield* EventV2.Service const events = yield* EventV2.Service
const updated = yield* events.subscribe(Catalog.Event.Updated).pipe(Stream.take(1), Stream.runCollect, Effect.forkScoped) const updated = yield* events
.subscribe(Catalog.Event.Updated)
.pipe(Stream.take(1), Stream.runCollect, Effect.forkScoped)
yield* Effect.yieldNow yield* Effect.yieldNow
yield* (yield* catalog.transform())((editor) => yield* (yield* catalog.transform())((editor) => editor.provider.update(ProviderV2.ID.make("test"), () => {}))
editor.provider.update(ProviderV2.ID.make("test"), () => {}),
)
expect((yield* Fiber.join(updated)).length).toBe(1) expect((yield* Fiber.join(updated)).length).toBe(1)
}), }),
+8 -5
View File
@@ -136,7 +136,8 @@ describe("ConfigProviderPlugin.Plugin", () => {
) )
it.effect("loads configured providers and applies later model overrides", () => it.effect("loads configured providers and applies later model overrides", () =>
withEnv({ CUSTOM_API_KEY: "secret" }, () => Effect.gen(function* () { withEnv({ CUSTOM_API_KEY: "secret" }, () =>
Effect.gen(function* () {
const catalog = yield* Catalog.Service const catalog = yield* Catalog.Service
const integrations = yield* Integration.Service const integrations = yield* Integration.Service
const plugin = yield* PluginV2.Service const plugin = yield* PluginV2.Service
@@ -232,9 +233,10 @@ describe("ConfigProviderPlugin.Plugin", () => {
const model = yield* catalog.model.get(providerID, modelID) const model = yield* catalog.model.get(providerID, modelID)
expect(Option.getOrUndefined(yield* catalog.model.default())?.id).toBe(ModelV2.ID.make("default")) expect(Option.getOrUndefined(yield* catalog.model.default())?.id).toBe(ModelV2.ID.make("default"))
expect(provider.name).toBe("Renamed") expect(provider.name).toBe("Renamed")
expect((yield* integrations.get(Integration.ID.make("custom")))?.methods).toContainEqual( expect((yield* integrations.get(Integration.ID.make("custom")))?.methods).toContainEqual({
{ type: "env", names: ["CUSTOM_API_KEY"] }, type: "env",
) names: ["CUSTOM_API_KEY"],
})
expect((yield* integrations.get(Integration.ID.make("custom")))?.name).toBe("Renamed") expect((yield* integrations.get(Integration.ID.make("custom")))?.name).toBe("Renamed")
expect(provider.disabled).toBeUndefined() expect(provider.disabled).toBeUndefined()
expect(provider.api).toEqual({ type: "aisdk", package: "custom-sdk", url: "https://example.test" }) expect(provider.api).toEqual({ type: "aisdk", package: "custom-sdk", url: "https://example.test" })
@@ -253,6 +255,7 @@ describe("ConfigProviderPlugin.Plugin", () => {
]) ])
expect(model.variants[0]?.headers).toEqual({ first: "first", shared: "last", last: "last" }) expect(model.variants[0]?.headers).toEqual({ first: "first", shared: "last", last: "last" })
expect(model.variants[1]?.headers).toEqual({ slow: "slow" }) expect(model.variants[1]?.headers).toEqual({ slow: "slow" })
})), }),
),
) )
}) })
+3 -5
View File
@@ -147,11 +147,9 @@ describe("Integration", () => {
method: { type: "key", label: "API key" }, method: { type: "key", label: "API key" },
}), }),
) )
const updated = yield* events.subscribe(Integration.Event.Updated).pipe( const updated = yield* events
Stream.take(1), .subscribe(Integration.Event.Updated)
Stream.runCollect, .pipe(Stream.take(1), Stream.runCollect, Effect.forkScoped)
Effect.forkScoped,
)
yield* Effect.yieldNow yield* Effect.yieldNow
yield* integrations.connection.key({ yield* integrations.connection.key({
+672 -1229
View File
File diff suppressed because it is too large Load Diff