use super::*;
pub fn typescript_binding() -> Result<String, serde_json::Error> {
let json = artifact_json()?;
Ok(format!(
"{}{}{}{}{}",
generated_header("//", "typescript"),
TYPESCRIPT_TYPES,
"\nexport const harnProviderCatalog: HarnProviderCatalog = ",
json.trim_end(),
";\n",
) + TYPESCRIPT_COMPAT_EXPORTS)
}
pub fn swift_binding() -> Result<String, serde_json::Error> {
let json = artifact_json()?;
Ok(format!(
"{}{}\npublic let harnProviderCatalogJSON = #\"\"\"\n{}\"\"\"#\n",
generated_header("//", "swift"),
SWIFT_TYPES,
json
))
}
fn generated_header(comment: &str, language: &str) -> String {
format!(
"{comment} GENERATED by `{PROVIDER_CATALOG_GENERATOR}` - do not edit by hand.\n{comment} Source: Harn runtime provider catalog schema v{PROVIDER_CATALOG_SCHEMA_VERSION}.\n{comment} Language: {language}.\n\n"
)
}
const TYPESCRIPT_TYPES: &str = r#"export interface HarnProviderCatalog {
schema_version: 2
schema: string
generated_by: string
providers: HarnCatalogProvider[]
models: HarnCatalogModel[]
aliases: HarnCatalogAlias[]
variants: HarnCatalogVariant[]
qc_defaults: Record<string, string>
}
export interface HarnCatalogProvider {
id: string
display_name: string
icon?: string
classification: "hosted" | "local"
endpoint: HarnProviderEndpoint
auth: HarnProviderAuth
protocols: string[]
features: string[]
caveats: string[]
rpm?: number
rate_limits?: HarnRateLimits
local_runtime?: HarnLocalRuntime
latency_p50_ms?: number
}
export interface HarnLocalRuntime {
kind?: "daemon_api" | "managed_process" | "external"
command?: string
model_source?: string
model_source_env?: string
default_port?: number
model_arg?: string
served_model_arg?: string
host_arg?: string
port_arg?: string
ctx_arg?: string
parallel_arg?: string
gpu_layers_arg?: string
cache_type_k_arg?: string
cache_type_v_arg?: string
cache_ram_arg?: string
default_args?: string[]
stop?: "keep_alive_zero" | "pid" | "external"
source_url?: string
last_verified?: string
notes?: string
}
export interface HarnProviderEndpoint {
base_url: string
base_url_env?: string
chat_endpoint: string
completion_endpoint?: string
}
export interface HarnProviderAuth {
style: string
header?: string
env: string[]
required: boolean
}
export interface HarnCatalogAlias {
name: string
model_id: string
provider: string
tool_format?: string
tool_calling?: HarnAliasToolCalling
}
export interface HarnAliasToolCalling {
native?: string
text?: string
streaming_native?: string
fallback_mode?: string
failure_reason?: string
last_probe_at?: string
}
export interface HarnCatalogModel {
id: string
name: string
provider: string
aliases: string[]
context_window: number
logical_model?: string
equivalence_group?: string
served_variant?: string
wire_model?: string
api_dialect?: string
rate_limits?: HarnRateLimits
architecture?: HarnModelArchitecture
local_memory?: HarnLocalMemory
runtime_context_window?: number
stream_timeout?: number
modalities: { input: string[]; output: string[] }
tool_support: {
native: boolean
text: boolean
preferred_format?: string
parity?: string
parity_notes?: string
empirical_parity?: HarnToolEmpiricalParity
tool_search: string[]
max_tools?: number
}
structured_output: string
format_preferences: {
prefers_xml_scaffolding: boolean
prefers_markdown_scaffolding: boolean
structured_output_mode: "native_json" | "delimited" | "xml_tagged" | "none"
supports_assistant_prefill: boolean
prefers_role_developer: boolean
prefers_xml_tools: boolean
thinking_block_style: "none" | "thinking_blocks" | "reasoning_summary" | "inline"
}
reasoning: {
modes: string[]
effort_supported: boolean
none_supported: boolean
interleaved_supported: boolean
preserve_thinking: boolean
}
prompt_cache: boolean
pricing?: HarnModelPricing
deprecation: { status: "active" | "deprecated"; note?: string; superseded_by?: string }
availability: "serverless" | "dedicated" | "unknown"
quality_tags: string[]
capability_tags: string[]
family: string
lineage: string
complementary_with?: string[]
avoid_as_reviewer_for?: string[]
tier: "small" | "mid" | "frontier" | "reasoning"
open_weight?: boolean
strengths?: string[]
benchmarks?: Record<string, number>
fast_mode?: HarnModelFastMode
}
export interface HarnToolEmpiricalParity {
verdict: string
preferred_format: string
confidence: string
sample_size: number
last_evaluated: string
native_pass_rate: number
text_pass_rate: number
verifier_divergence_rate: number
}
export interface HarnModelPricing {
input_per_mtok: number
output_per_mtok: number
cache_read_per_mtok?: number | null
cache_write_per_mtok?: number | null
}
export interface HarnRateLimits {
rpm?: number
rph?: number
rpd?: number
tpm?: number
tph?: number
tpd?: number
input_tpm?: number
output_tpm?: number
concurrency?: number
tier?: string
source_url?: string
last_verified?: string
notes?: string
}
export interface HarnModelArchitecture {
parameter_count_b?: number
active_parameter_count_b?: number
moe?: boolean
quantization?: string
precision?: string
license?: string
tokenizer?: string
knowledge_cutoff?: string
source_url?: string
last_verified?: string
}
export interface HarnLocalMemory {
measured_resident_gib?: number
measured_context_window?: number
measured_cache_type?: string
base_resident_gib?: number
kv_cache_gib_per_1k_ctx?: number
cache_type_multipliers?: Record<string, number>
default_cache_type?: string
safety_margin_gib?: number
max_recommended_context?: number
source_url?: string
last_verified?: string
notes?: string
}
export interface HarnModelFastMode {
param: string
value: string
beta_header?: string
otps_speedup?: number
status?: string
pricing?: HarnModelPricing
note?: string
}
export interface HarnCatalogVariant {
id: string
label: string
description: string
model_id: string
provider: string
source: string
}
export interface CatalogEntry {
id: string
name: string
provider: string
contextWindow: number
runtimeContextWindow?: number
capabilities: string[]
family: string
lineage: string
pricing?: {
inputPerMTok: number
outputPerMTok: number
cacheReadPerMTok?: number | null
cacheWritePerMTok?: number | null
}
streamTimeout?: number
}
export interface CatalogAlias {
alias: string
id: string
provider: string
toolFormat?: string
toolCalling?: HarnAliasToolCalling
}
"#;
const TYPESCRIPT_COMPAT_EXPORTS: &str = r#"
export const MODEL_CATALOG: readonly CatalogEntry[] = harnProviderCatalog.models.map((model) => ({
id: model.id,
name: model.name,
provider: model.provider,
contextWindow: model.context_window,
runtimeContextWindow: model.runtime_context_window,
capabilities: model.capability_tags,
family: model.family,
lineage: model.lineage,
pricing: model.pricing
? {
inputPerMTok: model.pricing.input_per_mtok,
outputPerMTok: model.pricing.output_per_mtok,
cacheReadPerMTok: model.pricing.cache_read_per_mtok,
cacheWritePerMTok: model.pricing.cache_write_per_mtok,
}
: undefined,
streamTimeout: model.stream_timeout,
}))
export const ALIASES: readonly CatalogAlias[] = harnProviderCatalog.aliases.map((alias) => ({
alias: alias.name,
id: alias.model_id,
provider: alias.provider,
toolFormat: alias.tool_format,
toolCalling: alias.tool_calling,
}))
export const QC_DEFAULTS: Readonly<Record<string, string>> = harnProviderCatalog.qc_defaults
export function pricingFor(modelId: string): CatalogEntry["pricing"] | undefined {
return entryFor(modelId)?.pricing
}
export function entryFor(modelId: string): CatalogEntry | undefined {
return MODEL_CATALOG.find((entry) => entry.id === modelId)
}
export function aliasesByProvider(provider: string): readonly CatalogAlias[] {
return ALIASES.filter((alias) => alias.provider === provider)
}
export function qcDefaultModel(provider: string): string | undefined {
return QC_DEFAULTS[provider]
}
"#;
const SWIFT_TYPES: &str = r#"public struct HarnProviderCatalog: Codable, Sendable, Equatable {
public let schemaVersion: Int
public let schema: String
public let generatedBy: String
public let providers: [HarnCatalogProvider]
public let models: [HarnCatalogModel]
public let aliases: [HarnCatalogAlias]
public let variants: [HarnCatalogVariant]
public let qcDefaults: [String: String]
enum CodingKeys: String, CodingKey {
case schemaVersion = "schema_version"
case schema
case generatedBy = "generated_by"
case providers
case models
case aliases
case variants
case qcDefaults = "qc_defaults"
}
}
public struct HarnCatalogProvider: Codable, Sendable, Equatable {
public let id: String
public let displayName: String
public let icon: String?
public let classification: String
public let endpoint: HarnProviderEndpoint
public let auth: HarnProviderAuth
public let protocols: [String]
public let features: [String]
public let caveats: [String]
public let rpm: Int?
public let rateLimits: HarnRateLimits?
public let localRuntime: HarnLocalRuntime?
public let latencyP50Ms: Int?
enum CodingKeys: String, CodingKey {
case id
case displayName = "display_name"
case icon
case classification
case endpoint
case auth
case protocols
case features
case caveats
case rpm
case rateLimits = "rate_limits"
case localRuntime = "local_runtime"
case latencyP50Ms = "latency_p50_ms"
}
}
public struct HarnLocalRuntime: Codable, Sendable, Equatable {
public let kind: String?
public let command: String?
public let modelSource: String?
public let modelSourceEnv: String?
public let defaultPort: Int?
public let modelArg: String?
public let servedModelArg: String?
public let hostArg: String?
public let portArg: String?
public let ctxArg: String?
public let parallelArg: String?
public let gpuLayersArg: String?
public let cacheTypeKArg: String?
public let cacheTypeVArg: String?
public let cacheRamArg: String?
public let defaultArgs: [String]?
public let stop: String?
public let sourceURL: String?
public let lastVerified: String?
public let notes: String?
enum CodingKeys: String, CodingKey {
case kind
case command
case modelSource = "model_source"
case modelSourceEnv = "model_source_env"
case defaultPort = "default_port"
case modelArg = "model_arg"
case servedModelArg = "served_model_arg"
case hostArg = "host_arg"
case portArg = "port_arg"
case ctxArg = "ctx_arg"
case parallelArg = "parallel_arg"
case gpuLayersArg = "gpu_layers_arg"
case cacheTypeKArg = "cache_type_k_arg"
case cacheTypeVArg = "cache_type_v_arg"
case cacheRamArg = "cache_ram_arg"
case defaultArgs = "default_args"
case stop
case sourceURL = "source_url"
case lastVerified = "last_verified"
case notes
}
}
public struct HarnProviderEndpoint: Codable, Sendable, Equatable {
public let baseURL: String
public let baseURLEnv: String?
public let chatEndpoint: String
public let completionEndpoint: String?
enum CodingKeys: String, CodingKey {
case baseURL = "base_url"
case baseURLEnv = "base_url_env"
case chatEndpoint = "chat_endpoint"
case completionEndpoint = "completion_endpoint"
}
}
public struct HarnProviderAuth: Codable, Sendable, Equatable {
public let style: String
public let header: String?
public let env: [String]
public let required: Bool
}
public struct HarnCatalogAlias: Codable, Sendable, Equatable {
public let name: String
public let modelID: String
public let provider: String
public let toolFormat: String?
public let toolCalling: HarnAliasToolCalling?
enum CodingKeys: String, CodingKey {
case name
case modelID = "model_id"
case provider
case toolFormat = "tool_format"
case toolCalling = "tool_calling"
}
}
public struct HarnAliasToolCalling: Codable, Sendable, Equatable {
public let native: String?
public let text: String?
public let streamingNative: String?
public let fallbackMode: String?
public let failureReason: String?
public let lastProbeAt: String?
enum CodingKeys: String, CodingKey {
case native
case text
case streamingNative = "streaming_native"
case fallbackMode = "fallback_mode"
case failureReason = "failure_reason"
case lastProbeAt = "last_probe_at"
}
}
public struct HarnCatalogModel: Codable, Sendable, Equatable {
public let id: String
public let name: String
public let provider: String
public let aliases: [String]
public let contextWindow: Int
public let logicalModel: String?
public let equivalenceGroup: String?
public let servedVariant: String?
public let wireModel: String?
public let apiDialect: String?
public let rateLimits: HarnRateLimits?
public let architecture: HarnModelArchitecture?
public let localMemory: HarnLocalMemory?
public let runtimeContextWindow: Int?
public let streamTimeout: Double?
public let modalities: HarnModelModalities
public let toolSupport: HarnModelToolSupport
public let structuredOutput: String
public let formatPreferences: HarnModelFormatPreferences
public let reasoning: HarnModelReasoning
public let promptCache: Bool
public let pricing: HarnModelPricing?
public let deprecation: HarnModelDeprecation
public let availability: String
public let qualityTags: [String]
public let capabilityTags: [String]
public let family: String
public let lineage: String
public let complementaryWith: [String]
public let avoidAsReviewerFor: [String]
/// Popular-consensus tier label: "small" | "mid" | "frontier" | "reasoning".
public let tier: String
/// True when weights are downloadable / self-hostable; nil when the
/// catalog row predates the field.
public let openWeight: Bool?
/// Workload-shaped strength tags (`coding`, `summarization`, `vision`, ...).
public let strengths: [String]
/// Public benchmark numbers keyed by `snake_case` identifier.
public let benchmarks: [String: Double]
/// Accelerated-serving ("fast mode") tier metadata, when offered.
public let fastMode: HarnModelFastMode?
enum CodingKeys: String, CodingKey {
case id
case name
case provider
case aliases
case contextWindow = "context_window"
case logicalModel = "logical_model"
case equivalenceGroup = "equivalence_group"
case servedVariant = "served_variant"
case wireModel = "wire_model"
case apiDialect = "api_dialect"
case rateLimits = "rate_limits"
case architecture
case localMemory = "local_memory"
case runtimeContextWindow = "runtime_context_window"
case streamTimeout = "stream_timeout"
case modalities
case toolSupport = "tool_support"
case structuredOutput = "structured_output"
case formatPreferences = "format_preferences"
case reasoning
case promptCache = "prompt_cache"
case pricing
case deprecation
case availability
case qualityTags = "quality_tags"
case capabilityTags = "capability_tags"
case family
case lineage
case complementaryWith = "complementary_with"
case avoidAsReviewerFor = "avoid_as_reviewer_for"
case tier
case openWeight = "open_weight"
case strengths
case benchmarks
case fastMode = "fast_mode"
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
provider = try container.decode(String.self, forKey: .provider)
aliases = try container.decode([String].self, forKey: .aliases)
contextWindow = try container.decode(Int.self, forKey: .contextWindow)
logicalModel = try container.decodeIfPresent(String.self, forKey: .logicalModel)
equivalenceGroup = try container.decodeIfPresent(String.self, forKey: .equivalenceGroup)
servedVariant = try container.decodeIfPresent(String.self, forKey: .servedVariant)
wireModel = try container.decodeIfPresent(String.self, forKey: .wireModel)
apiDialect = try container.decodeIfPresent(String.self, forKey: .apiDialect)
rateLimits = try container.decodeIfPresent(HarnRateLimits.self, forKey: .rateLimits)
architecture = try container.decodeIfPresent(HarnModelArchitecture.self, forKey: .architecture)
localMemory = try container.decodeIfPresent(HarnLocalMemory.self, forKey: .localMemory)
runtimeContextWindow = try container.decodeIfPresent(Int.self, forKey: .runtimeContextWindow)
streamTimeout = try container.decodeIfPresent(Double.self, forKey: .streamTimeout)
modalities = try container.decode(HarnModelModalities.self, forKey: .modalities)
toolSupport = try container.decode(HarnModelToolSupport.self, forKey: .toolSupport)
structuredOutput = try container.decode(String.self, forKey: .structuredOutput)
formatPreferences = try container.decode(HarnModelFormatPreferences.self, forKey: .formatPreferences)
reasoning = try container.decode(HarnModelReasoning.self, forKey: .reasoning)
promptCache = try container.decode(Bool.self, forKey: .promptCache)
pricing = try container.decodeIfPresent(HarnModelPricing.self, forKey: .pricing)
deprecation = try container.decode(HarnModelDeprecation.self, forKey: .deprecation)
availability = try container.decode(String.self, forKey: .availability)
qualityTags = try container.decode([String].self, forKey: .qualityTags)
capabilityTags = try container.decode([String].self, forKey: .capabilityTags)
family = try container.decode(String.self, forKey: .family)
lineage = try container.decode(String.self, forKey: .lineage)
complementaryWith = try container.decodeIfPresent([String].self, forKey: .complementaryWith) ?? []
avoidAsReviewerFor = try container.decodeIfPresent([String].self, forKey: .avoidAsReviewerFor) ?? []
tier = try container.decode(String.self, forKey: .tier)
openWeight = try container.decodeIfPresent(Bool.self, forKey: .openWeight)
strengths = try container.decodeIfPresent([String].self, forKey: .strengths) ?? []
benchmarks = try container.decodeIfPresent([String: Double].self, forKey: .benchmarks) ?? [:]
fastMode = try container.decodeIfPresent(HarnModelFastMode.self, forKey: .fastMode)
}
}
public struct HarnModelModalities: Codable, Sendable, Equatable {
public let input: [String]
public let output: [String]
}
public struct HarnModelToolSupport: Codable, Sendable, Equatable {
public let native: Bool
public let text: Bool
public let preferredFormat: String?
public let parity: String?
public let parityNotes: String?
public let empiricalParity: HarnToolEmpiricalParity?
public let toolSearch: [String]
public let maxTools: Int?
enum CodingKeys: String, CodingKey {
case native
case text
case preferredFormat = "preferred_format"
case parity
case parityNotes = "parity_notes"
case empiricalParity = "empirical_parity"
case toolSearch = "tool_search"
case maxTools = "max_tools"
}
}
public struct HarnToolEmpiricalParity: Codable, Sendable, Equatable {
public let verdict: String
public let preferredFormat: String
public let confidence: String
public let sampleSize: Int
public let lastEvaluated: String
public let nativePassRate: Double
public let textPassRate: Double
public let verifierDivergenceRate: Double
enum CodingKeys: String, CodingKey {
case verdict
case preferredFormat = "preferred_format"
case confidence
case sampleSize = "sample_size"
case lastEvaluated = "last_evaluated"
case nativePassRate = "native_pass_rate"
case textPassRate = "text_pass_rate"
case verifierDivergenceRate = "verifier_divergence_rate"
}
}
public struct HarnModelFormatPreferences: Codable, Sendable, Equatable {
public let prefersXMLScaffolding: Bool
public let prefersMarkdownScaffolding: Bool
public let structuredOutputMode: String
public let supportsAssistantPrefill: Bool
public let prefersRoleDeveloper: Bool
public let prefersXMLTools: Bool
public let thinkingBlockStyle: String
enum CodingKeys: String, CodingKey {
case prefersXMLScaffolding = "prefers_xml_scaffolding"
case prefersMarkdownScaffolding = "prefers_markdown_scaffolding"
case structuredOutputMode = "structured_output_mode"
case supportsAssistantPrefill = "supports_assistant_prefill"
case prefersRoleDeveloper = "prefers_role_developer"
case prefersXMLTools = "prefers_xml_tools"
case thinkingBlockStyle = "thinking_block_style"
}
}
public struct HarnModelReasoning: Codable, Sendable, Equatable {
public let modes: [String]
public let effortSupported: Bool
public let noneSupported: Bool
public let interleavedSupported: Bool
public let preserveThinking: Bool
enum CodingKeys: String, CodingKey {
case modes
case effortSupported = "effort_supported"
case noneSupported = "none_supported"
case interleavedSupported = "interleaved_supported"
case preserveThinking = "preserve_thinking"
}
}
public struct HarnModelPricing: Codable, Sendable, Equatable {
public let inputPerMTok: Double
public let outputPerMTok: Double
public let cacheReadPerMTok: Double?
public let cacheWritePerMTok: Double?
enum CodingKeys: String, CodingKey {
case inputPerMTok = "input_per_mtok"
case outputPerMTok = "output_per_mtok"
case cacheReadPerMTok = "cache_read_per_mtok"
case cacheWritePerMTok = "cache_write_per_mtok"
}
}
public struct HarnRateLimits: Codable, Sendable, Equatable {
public let rpm: Int?
public let rph: Int?
public let rpd: Int?
public let tpm: Int?
public let tph: Int?
public let tpd: Int?
public let inputTpm: Int?
public let outputTpm: Int?
public let concurrency: Int?
public let tier: String?
public let sourceURL: String?
public let lastVerified: String?
public let notes: String?
enum CodingKeys: String, CodingKey {
case rpm
case rph
case rpd
case tpm
case tph
case tpd
case inputTpm = "input_tpm"
case outputTpm = "output_tpm"
case concurrency
case tier
case sourceURL = "source_url"
case lastVerified = "last_verified"
case notes
}
}
public struct HarnModelArchitecture: Codable, Sendable, Equatable {
public let parameterCountB: Double?
public let activeParameterCountB: Double?
public let moe: Bool?
public let quantization: String?
public let precision: String?
public let license: String?
public let tokenizer: String?
public let knowledgeCutoff: String?
public let sourceURL: String?
public let lastVerified: String?
enum CodingKeys: String, CodingKey {
case parameterCountB = "parameter_count_b"
case activeParameterCountB = "active_parameter_count_b"
case moe
case quantization
case precision
case license
case tokenizer
case knowledgeCutoff = "knowledge_cutoff"
case sourceURL = "source_url"
case lastVerified = "last_verified"
}
}
public struct HarnLocalMemory: Codable, Sendable, Equatable {
public let measuredResidentGiB: Double?
public let measuredContextWindow: Int?
public let measuredCacheType: String?
public let baseResidentGiB: Double?
public let kvCacheGiBPer1KContext: Double?
public let cacheTypeMultipliers: [String: Double]?
public let defaultCacheType: String?
public let safetyMarginGiB: Double?
public let maxRecommendedContext: Int?
public let sourceURL: String?
public let lastVerified: String?
public let notes: String?
enum CodingKeys: String, CodingKey {
case measuredResidentGiB = "measured_resident_gib"
case measuredContextWindow = "measured_context_window"
case measuredCacheType = "measured_cache_type"
case baseResidentGiB = "base_resident_gib"
case kvCacheGiBPer1KContext = "kv_cache_gib_per_1k_ctx"
case cacheTypeMultipliers = "cache_type_multipliers"
case defaultCacheType = "default_cache_type"
case safetyMarginGiB = "safety_margin_gib"
case maxRecommendedContext = "max_recommended_context"
case sourceURL = "source_url"
case lastVerified = "last_verified"
case notes
}
}
public struct HarnModelDeprecation: Codable, Sendable, Equatable {
public let status: String
public let note: String?
public let supersededBy: String?
enum CodingKeys: String, CodingKey {
case status
case note
case supersededBy = "superseded_by"
}
}
public struct HarnModelFastMode: Codable, Sendable, Equatable {
public let param: String
public let value: String
public let betaHeader: String?
public let otpsSpeedup: Double?
public let status: String?
public let pricing: HarnModelPricing?
public let note: String?
enum CodingKeys: String, CodingKey {
case param
case value
case betaHeader = "beta_header"
case otpsSpeedup = "otps_speedup"
case status
case pricing
case note
}
}
public struct HarnCatalogVariant: Codable, Sendable, Equatable {
public let id: String
public let label: String
public let description: String
public let modelID: String
public let provider: String
public let source: String
enum CodingKeys: String, CodingKey {
case id
case label
case description
case modelID = "model_id"
case provider
case source
}
}
"#;