/** * kosha-discovery — Versioned discovery contract helpers. * * I keep the v1 schema, trusted capability taxonomy, and lightweight * heuristics here so the registry can stay focused on orchestration. * @module */ import type { ModelCard, ModelPricing, StructuredOutputMode, ToolDialect } from "./types.js"; import type { ProviderDescriptor } from "./provider-catalog.js"; /** Stable schema version exposed to Chitragupta and other daemon consumers. */ export declare const DISCOVERY_SCHEMA_VERSION = 1; /** Trusted capability taxonomy surfaced by the v1 discovery contract. */ export type TrustedCapability = "chat" | "function_calling" | "embeddings" | "vision" | "video_generation" | "rerank" | "judgment" | "structured_output" | "streaming" | "long_context" | "local_exec" | "code_generation" | "reasoning" | "low_latency" | "cheap_inference" | "free_tier"; /** Normalized role hints exposed by the v1 schema. */ export interface DiscoveryRoleDefinition { /** Stable role identifier. */ roleId: string; /** Capabilities required for the role to be viable. */ requiredCapabilities: TrustedCapability[]; /** Capabilities that improve suitability but are not mandatory. */ preferredCapabilities: TrustedCapability[]; /** Short human-readable hint for consumers. */ suitabilityHint: string; } /** Credential prompt shape exposed in the v1 schema. */ export interface DiscoveryCredentialPrompt { providerId: string; providerName: string; required: boolean; envVars: string[]; message: string; } /** Stable provider shape emitted by the v1 discovery snapshot. */ export interface DiscoveryProviderV1 { providerId: string; canonicalProviderId: string; aliases: string[]; name: string; origin: string; isLocal: boolean; transport: string; authenticated: boolean; credentialSource: string | null; credentialsPresent: boolean; credentialsRequired: boolean; credentialEnvVars: string[]; modelCount: number; lastRefreshed: number | null; baseUrl: string; } /** Stable model shape emitted by the v1 discovery snapshot. */ export interface DiscoveryModelV1 { key: string; modelId: string; name: string; providerId: string; canonicalProviderId: string; originProviderId: string; mode: string; capabilities: TrustedCapability[]; rawCapabilities: string[]; contextWindow: number | null; maxOutputTokens: number | null; pricing: ModelPricing | null; originPricing?: ModelPricing | null; dimensions: number | null; maxInputTokens: number | null; discoveredAt: number; source: string; aliases: string[]; region: string | null; projectId: string | null; runtimeFamily: string | null; tokenizerFamily: string | null; quantization: string | null; memoryFootprintBytes: number | null; computeTarget: string | null; supportsStructuredOutput: boolean | null; supportsStreaming: boolean | null; /** Tool-calling dialect family (e.g. `"anthropic-tools"`). */ toolDialect: ToolDialect | null; /** Structured-output production modes surfaced for bindings. */ structuredOutputModes: StructuredOutputMode[]; /** Whether the model supports multiple tool calls per turn. */ supportsParallelToolCalls: boolean | null; /** Lifecycle status used by routing and deprecation warnings. */ status: "active" | "preview" | "deprecated" | "retired" | null; /** ISO-8601 deprecation/sunset date when announced by the provider. */ deprecationDate: string | null; /** Canonical successor model ID when the provider has published one. */ replacedBy: string | null; /** * Number of consecutive discovery passes in which this model was absent * from the fresh fetch. Reset to 0 when the model reappears. Once it * exceeds the lifecycle TTL (see `registry-runtime.ts`) the model is * dropped from the merged manifest entirely. Absent in fresh entries. */ missingRunCount?: number; } /** Normalized provider health exposed by the v1 discovery snapshot. */ export interface DiscoveryHealthRecord { providerId: string; state: "healthy" | "degraded" | "down" | "auth_error" | "throttled" | "unknown"; failureCount: number; lastError: string | null; lastSuccessAt: number | null; lastFailureAt: number | null; latencyClass: "low" | "medium" | "high" | "timeout" | "unknown"; timeoutRate: number; rateLimitState: "ok" | "throttled" | "unknown"; circuitState: "closed" | "open" | "half-open"; } /** Full v1 discovery snapshot. */ export interface DiscoverySnapshotV1 { schemaVersion: number; discoveredAt: number | null; cursor: string; providers: DiscoveryProviderV1[]; models: DiscoveryModelV1[]; roles: DiscoveryRoleDefinition[]; health: DiscoveryHealthRecord[]; credentialPrompts: DiscoveryCredentialPrompt[]; } /** Entity kinds that can appear in a delta stream. */ export type DiscoveryChangeEntity = "provider" | "model" | "health" | "credential_prompt"; /** Individual change item inside a delta batch. */ export interface DiscoveryChangeV1 { entity: DiscoveryChangeEntity; action: "upsert" | "remove"; key: string; value: DiscoveryProviderV1 | DiscoveryModelV1 | DiscoveryHealthRecord | DiscoveryCredentialPrompt | null; } /** Aggregate delta response used by polling and live watch. */ export interface DiscoveryDeltaV1 { schemaVersion: number; sinceCursor: string | null; cursor: string; changedAt: number | null; resetRequired: boolean; changes: DiscoveryChangeV1[]; } /** Stable cheapest-candidate match used by the v1 debug/library surface. */ export interface DiscoveryCheapestCandidateV1 { modelId: string; providerId: string; canonicalProviderId: string; score: number | null; priceMetric: string; capabilities: TrustedCapability[]; } /** Cheapest-candidate response for a normalized query. */ export interface DiscoveryCheapestResultV1 { schemaVersion: number; query: Record; candidates: number; pricedCandidates: number; skippedNoPricing: number; priceMetric: string; matches: DiscoveryCheapestCandidateV1[]; } /** Binding query used by the additive v1 selection-hints surface. */ export interface DiscoveryBindingQuery { role?: string; capability?: string; provider?: string; originProvider?: string; mode?: string; limit?: number; priceMetric?: string; preferLocalProviders?: boolean; allowCrossProvider?: boolean; } /** Query-scoped discovery hints used to build Chitragupta bindings. */ export interface DiscoveryBindingHintsV1 { schemaVersion: number; query: Record; selectedModelId: string | null; selectedProviderId: string | null; candidateModelIds: string[]; preferredModelIds: string[]; preferredProviderIds: string[]; preferLocalProviders: boolean; allowCrossProvider: boolean; } /** Stable role definitions shipped with the v1 schema. */ export declare const DISCOVERY_ROLE_DEFINITIONS: readonly DiscoveryRoleDefinition[]; /** * Build a stable composite key for a model route. */ export declare function makeModelKey(model: Pick, descriptor: ProviderDescriptor): string; /** * Return the raw capability list that a discoverer originally emitted. */ export declare function rawCapabilitiesForModel(model: ModelCard): string[]; /** * Normalize free-form model metadata into the trusted capability taxonomy. * * I keep the heuristics intentionally conservative. When I cannot infer a * capability with reasonable confidence, I leave it out of the trusted set. */ export declare function trustedCapabilitiesForModel(model: ModelCard, descriptor: ProviderDescriptor): TrustedCapability[]; /** * Return stable role definitions for the v1 snapshot. */ export declare function discoveryRoles(): DiscoveryRoleDefinition[]; //# sourceMappingURL=discovery-contract.d.ts.map