148 lines · 6.7 KB · TypeScript
RawDownload
/** * Provider-instance contracts. * * Splits the historical "provider kind" concept into two: * *   - `ProviderDriverKind` is the implementation kind selector (e.g. codex, *     claudeAgent, a fork's `ollama`, …). It picks which driver package *     handles the protocol, the probe, the adapter, and text generation. * *   - `ProviderInstanceId` is the routing key (a user-defined slug). *     Threads, sessions, runtime events, and persisted bindings reference *     instance ids — never driver kinds — so a user can configure multiple *     instances of the same driver (e.g. `codex_personal` + `codex_work`), *     each with independent driver-specific configuration. * * Forward/backward compatibility invariant * ---------------------------------------- * `ProviderDriverKind` is intentionally an **open** branded slug, not a closed * literal union. The server hosts forks, ships in PRs that add drivers, and * users frequently roll between branches and forks. Any of those paths can * leave `ServerSettings`, persisted thread state, or session bindings * referencing a driver that the currently-running build does not know about. * * The rule: parsing any of those payloads must always succeed, and the * runtime is responsible for marking the unknown driver/instance as * "unavailable" rather than crashing. Built-in drivers shipped by the core * product happens to register in a given build is not part of the contract * layer. Driver availability is discovered through the runtime registry. * * Driver-specific configuration is similarly opaque at the contracts layer: * drivers live in (or will be extracted to) their own packages and own their * config schemas. The contracts package only knows the envelope. * * @module providerInstance */import { Effect, Schema } from "effect";import { TrimmedNonEmptyString } from "./baseSchemas.ts"; const PROVIDER_SLUG_MAX_CHARS = 64;/** * Slug pattern shared by driver kinds and instance ids — letters, digits, * dashes, underscores. The first character must be a letter so slugs remain * JS-identifier friendly when used as object keys, log fields, or telemetry * attributes. Mixed case is permitted so historical driver kinds (e.g. * `claudeAgent`) can be used verbatim during the migration and so external * fork authors retain reasonable freedom. */const PROVIDER_SLUG_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;const ENVIRONMENT_VARIABLE_NAME_MAX_CHARS = 128;const ENVIRONMENT_VARIABLE_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/; const slugSchema = TrimmedNonEmptyString.check(  Schema.isMaxLength(PROVIDER_SLUG_MAX_CHARS),  Schema.isPattern(PROVIDER_SLUG_PATTERN),); /** * `ProviderDriverKind` — open branded slug naming a driver implementation. * * Constraints (validated at the schema layer): *   - starts with a letter *   - only letters, digits, `-`, `_` after the first char *   - 1..64 characters * * Notably **not** validated: that the driver is one we know how to load. * That check belongs to the runtime registry, which downgrades unknown * drivers gracefully (see module docs). */export const ProviderDriverKind = slugSchema.pipe(Schema.brand("ProviderDriverKind"));export type ProviderDriverKind = typeof ProviderDriverKind.Type; const isProviderDriverKindValue = Schema.is(ProviderDriverKind);export const isProviderDriverKind = (value: unknown): value is ProviderDriverKind =>  isProviderDriverKindValue(value); /** * `ProviderInstanceId` — user-defined routing key for a configured provider * instance. Same slug rules as `ProviderDriverKind`; branded separately so the * type system cannot confuse the two. */export const ProviderInstanceId = slugSchema.pipe(Schema.brand("ProviderInstanceId"));export type ProviderInstanceId = typeof ProviderInstanceId.Type; /** * Lightweight reference identifying which driver implements an instance. * Carried alongside `ProviderInstanceId` on wire shapes so consumers can * branch on driver behavior (icons, capabilities, presentation) without * having to look up the instance in the registry. */export const ProviderInstanceRef = Schema.Struct({  instanceId: ProviderInstanceId,  driver: ProviderDriverKind,});export type ProviderInstanceRef = typeof ProviderInstanceRef.Type; export const ProviderInstanceEnvironmentVariableName = TrimmedNonEmptyString.check(  Schema.isMaxLength(ENVIRONMENT_VARIABLE_NAME_MAX_CHARS),  Schema.isPattern(ENVIRONMENT_VARIABLE_NAME_PATTERN),);export type ProviderInstanceEnvironmentVariableName =  typeof ProviderInstanceEnvironmentVariableName.Type; export const ProviderInstanceEnvironmentVariable = Schema.Struct({  name: ProviderInstanceEnvironmentVariableName,  value: Schema.String.pipe(Schema.withDecodingDefault(Effect.succeed(""))),  sensitive: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))),  valueRedacted: Schema.optionalKey(Schema.Boolean),});export type ProviderInstanceEnvironmentVariable = typeof ProviderInstanceEnvironmentVariable.Type; export const ProviderInstanceEnvironment = Schema.Array(ProviderInstanceEnvironmentVariable);export type ProviderInstanceEnvironment = typeof ProviderInstanceEnvironment.Type; /** * Envelope shape for a provider instance configuration in `ServerSettings`. * * `driver` is intentionally accepted as any well-formed slug (see module * docs). The driver-specific config payload is left as `Schema.Unknown`; * each driver registers its own decoder with the runtime registry, and * envelopes for unknown drivers are preserved verbatim so they round-trip * across version changes without data loss. */export const ProviderInstanceConfig = Schema.Struct({  driver: ProviderDriverKind,  displayName: Schema.optional(TrimmedNonEmptyString),  accentColor: Schema.optional(TrimmedNonEmptyString),  environment: Schema.optionalKey(ProviderInstanceEnvironment),  enabled: Schema.optionalKey(Schema.Boolean),  config: Schema.optionalKey(Schema.Unknown),});export type ProviderInstanceConfig = typeof ProviderInstanceConfig.Type; /** * Map shape for `ServerSettings.providerInstances`. Keyed by * `ProviderInstanceId`, values are envelopes the registry feeds to drivers. */export const ProviderInstanceConfigMap = Schema.Record(ProviderInstanceId, ProviderInstanceConfig);export type ProviderInstanceConfigMap = typeof ProviderInstanceConfigMap.Type; /** * Construct the canonical `ProviderInstanceId` used as a back-compat default * for a built-in driver. The legacy single-instance-per-driver world used * the driver kind itself as the instance id; preserving that mapping keeps * existing persisted threads, bindings, and cache files routable across the * migration without rewriting their stored selection payloads. */export const defaultInstanceIdForDriver = (driver: ProviderDriverKind): ProviderInstanceId =>  ProviderInstanceId.make(driver);