refactor: centralize client identity (#38148)

This commit is contained in:
Dax 2026-07-21 14:01:04 -04:00 committed by GitHub
commit 9c38358197
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 102 additions and 94 deletions

View file

@ -3,6 +3,7 @@ import { Context, Duration, Effect, Layer, Option, Schedule, Schema } from "effe
import { HttpClient, HttpClientRequest } from "effect/unstable/http"
import { ModelsDev } from "@opencode-ai/schema/models-dev"
import { Money } from "@opencode-ai/schema/money"
import { Client } from "@opencode-ai/util/client"
import { Global } from "@opencode-ai/util/global"
import { Flock } from "@opencode-ai/util/flock"
import { Hash } from "@opencode-ai/util/hash"
@ -531,17 +532,18 @@ export const Options = Schema.Struct({
url: Schema.optional(Schema.String),
file: Schema.optional(Schema.String),
fetch: Schema.optional(Schema.Boolean),
client: Schema.optional(Schema.String),
})
export type Options = typeof Options.Type
export class Service extends Context.Service<Service, Interface>()("@opencode/ModelsDev") {}
export const layer = (options?: Options) => Layer.effect(
export const layer = (options?: Options) =>
Layer.effect(
Service,
Effect.gen(function* () {
const fs = yield* FSUtil.Service
const events = yield* EventV2.Service
const client = yield* Client.Name
const http = HttpClient.filterStatusOk(
(yield* HttpClient.HttpClient).pipe(
HttpClient.retryTransient({
@ -554,7 +556,7 @@ export const layer = (options?: Options) => Layer.effect(
const source = options?.url || "https://models.dev"
const fetch = options?.fetch ?? true
const userAgent = `opencode/${InstallationChannel}/${InstallationVersion}/${options?.client ?? "cli"}`
const userAgent = `opencode/${InstallationChannel}/${InstallationVersion}/${client}`
const filepath = path.join(
Global.Path.cache,
source === "https://models.dev" ? "models.json" : `models-${Hash.fast(source)}.json`,
@ -581,11 +583,7 @@ export const layer = (options?: Options) => Layer.effect(
const loadFromDisk = fs.readJson(options?.file ?? filepath).pipe(
Effect.map((input) => input as Record<string, SourceProvider>),
Effect.catch((error) => {
if (
options?.file === undefined &&
error._tag === "FileSystemError" &&
error.method === "readJson"
) {
if (options?.file === undefined && error._tag === "FileSystemError" && error.method === "readJson") {
return fs.remove(filepath, { force: true }).pipe(Effect.ignore, Effect.as(undefined))
}
return Effect.succeed(undefined)
@ -659,7 +657,11 @@ export const layer = (options?: Options) => Layer.effect(
)
export function configured(options?: Options) {
return makeGlobalNode({ service: Service, layer: layer(options), deps: [FSUtil.node, EventV2.node, httpClient] })
return makeGlobalNode({
service: Service,
layer: layer(options),
deps: [FSUtil.node, EventV2.node, Client.node, httpClient],
})
}
export const node = configured()