{"repo": "bhodgens/meept", "files": {"internal/llm/provider_registry.go": {"8ed9301a24b87b5c6ef3299de347fbee76c03836": {"t": 1785745630.0015566, "n": 9272, "h": "9d599bb050ca9753", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n\t{\n\t\tID: \"github-models\",\n\t\tName: \"GitHub Models\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://models.github.ai/inference\",\n\t\tDocURL: \"https://docs.github.com/en/github-models\",\n\t\tSupports: []string{CapStreaming, CapTools, CapCode},\n\t},\n\t{\n\t\tID: \"google-oauth\",\n\t\tName: \"Google AI (OAuth)\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\tresult := make([]ProviderDef, len(CanonicalProviders))\n\t\tcopy(result, CanonicalProviders)\n\t\treturn result\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n\n// ProvidersFromConfig builds ProviderDef entries from a ProvidersConfig (models.json5).\n// Each key in cfg.Providers that doesn't match a canonical provider ID is treated\n// as a user-defined OpenAI-compatible provider. Canonical providers get their\n// BaseURL/APIKey overridden from config if present.\nfunc ProvidersFromConfig(cfg *ProvidersConfig) []ProviderDef {\n\tif cfg == nil || len(cfg.Providers) == 0 {\n\t\treturn nil\n\t}\n\n\t// Build lookup of canonical providers for override detection\n\tcanonical := make(map[string]ProviderDef, len(CanonicalProviders))\n\tfor _, p := range CanonicalProviders {\n\t\tcanonical[p.ID] = p\n\t}\n\n\t// Disabled providers set\n\tdisabled := make(map[string]bool, len(cfg.DisabledProviders))\n\tfor _, d := range cfg.DisabledProviders {\n\t\tdisabled[d] = true\n\t}\n\n\tvar result []ProviderDef\n\tfor id, pc := range cfg.Providers {\n\t\tif disabled[id] {\n\t\t\tcontinue\n\t\t}\n\n\t\tif c, ok := canonical[id]; ok {\n\t\t\t// Override base URL / API key from config\n\t\t\tif pc.Options.BaseURL != \"\" {\n\t\t\t\tc.BaseURL = pc.Options.BaseURL\n\t\t\t}\n\t\t\tif pc.Options.APIKey != \"\" {\n\t\t\t\tc.APIKeyEnvVar = \"\" // clear env var, use direct key\n\t\t\t}\n\t\t\tresult = append(result, c)\n\t\t\tcontinue\n\t\t}\n\n\t\t// User-defined provider — synthesize a ProviderDef\n\t\tdef := ProviderDef{\n\t\t\tID: id,\n\t\t\tName: id, // Use the config key as display name\n\t\t\tTransport: TransportOpenAIChat,\n\t\t\tAuthType: AuthEnvVar,\n\t\t\tBaseURL: pc.Options.BaseURL,\n\t\t\tSupports: []string{CapStreaming},\n\t\t}\n\t\tif pc.Options.APIKey != \"\" {\n\t\t\tdef.AuthType = AuthAPIKey\n\t\t}\n\t\t// Detect lifecycle (local LLM)\n\t\tif pc.Lifecycle != nil {\n\t\t\tdef.Supports = append(def.Supports, \"local\")\n\t\t}\n\t\tresult = append(result, def)\n\t}\n\n\treturn result\n}\n"}, "7f211ca3175ec40efc8642d14cbdf0878c5c9953": {"t": 1785755054.0514884, "n": 9272, "h": "9d599bb050ca9753", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n\t{\n\t\tID: \"github-models\",\n\t\tName: \"GitHub Models\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://models.github.ai/inference\",\n\t\tDocURL: \"https://docs.github.com/en/github-models\",\n\t\tSupports: []string{CapStreaming, CapTools, CapCode},\n\t},\n\t{\n\t\tID: \"google-oauth\",\n\t\tName: \"Google AI (OAuth)\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\tresult := make([]ProviderDef, len(CanonicalProviders))\n\t\tcopy(result, CanonicalProviders)\n\t\treturn result\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n\n// ProvidersFromConfig builds ProviderDef entries from a ProvidersConfig (models.json5).\n// Each key in cfg.Providers that doesn't match a canonical provider ID is treated\n// as a user-defined OpenAI-compatible provider. Canonical providers get their\n// BaseURL/APIKey overridden from config if present.\nfunc ProvidersFromConfig(cfg *ProvidersConfig) []ProviderDef {\n\tif cfg == nil || len(cfg.Providers) == 0 {\n\t\treturn nil\n\t}\n\n\t// Build lookup of canonical providers for override detection\n\tcanonical := make(map[string]ProviderDef, len(CanonicalProviders))\n\tfor _, p := range CanonicalProviders {\n\t\tcanonical[p.ID] = p\n\t}\n\n\t// Disabled providers set\n\tdisabled := make(map[string]bool, len(cfg.DisabledProviders))\n\tfor _, d := range cfg.DisabledProviders {\n\t\tdisabled[d] = true\n\t}\n\n\tvar result []ProviderDef\n\tfor id, pc := range cfg.Providers {\n\t\tif disabled[id] {\n\t\t\tcontinue\n\t\t}\n\n\t\tif c, ok := canonical[id]; ok {\n\t\t\t// Override base URL / API key from config\n\t\t\tif pc.Options.BaseURL != \"\" {\n\t\t\t\tc.BaseURL = pc.Options.BaseURL\n\t\t\t}\n\t\t\tif pc.Options.APIKey != \"\" {\n\t\t\t\tc.APIKeyEnvVar = \"\" // clear env var, use direct key\n\t\t\t}\n\t\t\tresult = append(result, c)\n\t\t\tcontinue\n\t\t}\n\n\t\t// User-defined provider — synthesize a ProviderDef\n\t\tdef := ProviderDef{\n\t\t\tID: id,\n\t\t\tName: id, // Use the config key as display name\n\t\t\tTransport: TransportOpenAIChat,\n\t\t\tAuthType: AuthEnvVar,\n\t\t\tBaseURL: pc.Options.BaseURL,\n\t\t\tSupports: []string{CapStreaming},\n\t\t}\n\t\tif pc.Options.APIKey != \"\" {\n\t\t\tdef.AuthType = AuthAPIKey\n\t\t}\n\t\t// Detect lifecycle (local LLM)\n\t\tif pc.Lifecycle != nil {\n\t\t\tdef.Supports = append(def.Supports, \"local\")\n\t\t}\n\t\tresult = append(result, def)\n\t}\n\n\treturn result\n}\n"}, "1f3820cd4a79623885dd11f8c0b2bad87505ba80": {"t": 1785755057.8648486, "n": 9314, "h": "35e95b6d498588ec", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n\t{\n\t\tID: \"github-models\",\n\t\tName: \"GitHub Models\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://models.github.ai/inference\",\n\t\tDocURL: \"https://docs.github.com/en/github-models\",\n\t\tSupports: []string{CapStreaming, CapTools, CapCode},\n\t},\n\t{\n\t\tID: \"google-oauth\",\n\t\tName: \"Google AI (OAuth)\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\tresult := make([]ProviderDef, len(CanonicalProviders))\n\t\tcopy(result, CanonicalProviders)\n\t\treturn result\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n\n// ProvidersFromConfig builds ProviderDef entries from a ProvidersConfig (models.json5).\n// Each key in cfg.Providers that doesn't match a canonical provider ID is treated\n// as a user-defined OpenAI-compatible provider. Canonical providers get their\n// BaseURL/APIKey overridden from config if present.\nfunc ProvidersFromConfig(cfg *ProvidersConfig) []ProviderDef {\n\tif cfg == nil || len(cfg.Providers) == 0 {\n\t\treturn nil\n\t}\n\n\t// Build lookup of canonical providers for override detection\n\tcanonical := make(map[string]ProviderDef, len(CanonicalProviders))\n\tfor _, p := range CanonicalProviders {\n\t\tcanonical[p.ID] = p\n\t}\n\n\t// Disabled providers set\n\tdisabled := make(map[string]bool, len(cfg.DisabledProviders))\n\tfor _, d := range cfg.DisabledProviders {\n\t\tdisabled[d] = true\n\t}\n\n\tvar result []ProviderDef\n\tfor id, pc := range cfg.Providers {\n\t\tif disabled[id] {\n\t\t\tcontinue\n\t\t}\n\n\t\tif c, ok := canonical[id]; ok {\n\t\t\t// Override base URL / API key from config\n\t\t\tif pc.Options.BaseURL != \"\" {\n\t\t\t\tc.BaseURL = pc.Options.BaseURL\n\t\t\t}\n\t\t\tif pc.Options.APIKey != \"\" {\n\t\t\t\tc.APIKeyEnvVar = \"\" // clear env var, use direct key\n\t\t\t}\n\t\t\tresult = append(result, c)\n\t\t\tcontinue\n\t\t}\n\n\t\t// User-defined provider — synthesize a ProviderDef\n\t\tdef := ProviderDef{\n\t\t\tID: id,\n\t\t\tName: id, // Use the config key as display name\n\t\t\tTransport: TransportOpenAIChat,\n\t\t\tAuthType: AuthEnvVar,\n\t\t\tBaseURL: pc.Options.BaseURL,\n\t\t\tSupports: []string{CapStreaming},\n\t\t}\n\t\tif pc.Options.APIKey != \"\" {\n\t\t\tdef.AuthType = AuthAPIKey\n\t\t}\n\t\t// Detect lifecycle (local LLM)\n\t\tif pc.Lifecycle != nil {\n\t\t\tdef.Supports = append(def.Supports, \"local\")\n\t\t}\n\t\tresult = append(result, def)\n\t}\n\n\treturn result\n}\n"}, "1e2706c574aab0c2cc22fcb3ab8904fecec02dcb": {"t": 1785755059.2862482, "n": 7620, "h": "37562b16344c001c", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n\t{\n\t\tID: \"github-models\",\n\t\tName: \"GitHub Models\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://models.github.ai/inference\",\n\t\tDocURL: \"https://docs.github.com/en/github-models\",\n\t\tSupports: []string{CapStreaming, CapTools, CapCode},\n\t},\n\t{\n\t\tID: \"google-oauth\",\n\t\tName: \"Google AI (OAuth)\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthOAuthDevice,\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\tresult := make([]ProviderDef, len(CanonicalProviders))\n\t\tcopy(result, CanonicalProviders)\n\t\treturn result\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "cfb863d6bfec390fa378da896f561f3e67e16722": {"t": 1785755060.7149713, "n": 6981, "h": "0d47e5e4a13e292d", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\tresult := make([]ProviderDef, len(CanonicalProviders))\n\t\tcopy(result, CanonicalProviders)\n\t\treturn result\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "f683850c95a23918112c4ece34caf48c5597ee69": {"t": 1785755062.0846498, "n": 7080, "h": "2e83bf77c7d6c52a", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Budget exceeded error message.\n\tErrBudgetExceeded = \"Token budget exceeded - request blocked\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\tresult := make([]ProviderDef, len(CanonicalProviders))\n\t\tcopy(result, CanonicalProviders)\n\t\treturn result\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "bab8915e108db1a54dc32992d11f95633cca1205": {"t": 1785755063.3002114, "n": 7000, "h": "873e8509a0faec6b", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Budget exceeded error message.\n\tErrBudgetExceeded = \"Token budget exceeded - request blocked\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\treturn CanonicalProviders\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "e85894967516fefea601136333a671983638f176": {"t": 1785755064.6257896, "n": 7040, "h": "66fc65d99b3d1496", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Budget exceeded error message.\n\tErrBudgetExceeded = \"Token budget exceeded - request blocked\"\n\n\t// Metrics dimension keys.\n\tKeyLevel = \"level\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{CapStreaming, CapTools},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, CapTools, CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{CapStreaming, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{CapStreaming, \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{CapStreaming, \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{CapStreaming, CapTools, \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\treturn CanonicalProviders\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "92c2676f34517281f74e85defa26af82aa0b2c33": {"t": 1785755065.8305452, "n": 6978, "h": "d6a1f4c120be54e6", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// Provider ID constants used across catalog, registry, and broker.\nconst (\n\tProviderIDAnthropic = \"anthropic\"\n\tProviderIDOpenAI = \"openai\"\n\tProviderIDOllama = \"ollama\"\n\tProviderIDZAI = \"zai\"\n\tProviderIDGoogle = \"google\"\n\tProviderIDDeepSeek = \"deepseek\"\n\tProviderIDBedrock = \"bedrock\"\n)\n\n// Content type constants for API response parsing.\nconst (\n\tContentTypeText = \"text\"\n\tContentTypeToolUse = \"tool_use\"\n\tContentTypeThinking = \"thinking\"\n\tContentTypeFunction = \"function\"\n\n\t// Capability strings used in model definitions.\n\tCapCode = \"code\"\n\tCapReasoning = \"reasoning\"\n\tCapToolUse = \"tool_use\"\n\tCapThinking = \"thinking\"\n\tCapImages = \"images\"\n\tCapStreaming = \"streaming\"\n\tCapCompletion = \"completion\"\n\tCapTools = \"tools\"\n\n\t// Budget exceeded error message.\n\tErrBudgetExceeded = \"Token budget exceeded - request blocked\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDAnthropic,\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{CapStreaming, \"tools\", CapImages, CapThinking},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{CapStreaming, \"tools\", CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDOpenAI,\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{CapStreaming, \"tools\", CapImages, \"responses\"},\n\t},\n\t{\n\t\tID: ProviderIDOllama,\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{\"streaming\", \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDZAI,\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{\"streaming\", \"tools\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDGoogle,\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{CapStreaming, \"tools\", CapImages},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: ProviderIDDeepSeek,\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{CapStreaming, CapCode, CapReasoning},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{\"streaming\", \"reasoning\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{\"streaming\", \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{\"streaming\", \"models\"},\n\t},\n\t{\n\t\tID: ProviderIDBedrock,\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\treturn CanonicalProviders\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "07589230ee997e9ae4ea79f963de289fe11512f5": {"t": 1785755087.3961105, "n": 6042, "h": "48ddd7c9f7b28d12", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"anthropic\",\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\", \"thinking\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"openai\",\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\", \"responses\"},\n\t},\n\t{\n\t\tID: \"ollama\",\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{\"streaming\", \"local\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"zai\",\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{\"streaming\", \"tools\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"google\",\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"deepseek\",\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{\"streaming\", \"code\", \"reasoning\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{\"streaming\", \"reasoning\"},\n\t},\n\t//nolint:gosec // field name, not a secret\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{\"streaming\", \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{\"streaming\", \"models\"},\n\t},\n\t{\n\t\tID: \"bedrock\",\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\treturn CanonicalProviders\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}, "35995a6ef88977cd7d662704c579479afb8b5592": {"t": 1785755088.79123, "n": 5690, "h": "b8a31eef61b438c9", "c": "package llm\n\n// ProviderTransport defines the API wire protocol type.\ntype ProviderTransport string\n\nconst (\n\tTransportOpenAIChat ProviderTransport = \"openai_chat\"\n\tTransportAnthropicMessages ProviderTransport = \"anthropic_messages\"\n\tTransportCodexResponses ProviderTransport = \"codex_responses\"\n\tTransportBedrockConverse ProviderTransport = \"bedrock_converse\"\n)\n\n// AuthType defines how authentication is performed.\ntype AuthType string\n\nconst (\n\tAuthAPIKey AuthType = \"api_key\"\n\tAuthOAuthDevice AuthType = \"oauth_device_code\"\n\tAuthOAuthExternal AuthType = \"oauth_external\"\n\tAuthEnvVar AuthType = \"env\"\n)\n\n// ProviderDef defines a provider with all its metadata.\ntype ProviderDef struct {\n\tID string // Canonical provider ID (e.g., \"anthropic\", \"openrouter\")\n\tName string // Human-readable name (e.g., \"Anthropic\", \"OpenRouter\")\n\tTransport ProviderTransport // API wire protocol\n\tAuthType AuthType // How to authenticate\n\tAPIKeyEnvVar string // Environment variable for API key (e.g., \"ANTHROPIC_API_KEY\")\n\tBaseURL string // Default base URL (empty = use provider default)\n\tBaseURLOverride string // Override base URL if needed\n\tDocURL string // Documentation URL\n\tSupports []string // Capabilities: streaming, tools, images, etc.\n}\n\n// CanonicalProviders is the master list of supported providers.\nvar CanonicalProviders = []ProviderDef{\n\t{\n\t\tID: \"anthropic\",\n\t\tName: \"Anthropic\",\n\t\tTransport: TransportAnthropicMessages,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ANTHROPIC_API_KEY\",\n\t\tBaseURL: \"https://api.anthropic.com\",\n\t\tDocURL: \"https://docs.anthropic.com\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\", \"thinking\"},\n\t},\n\t{\n\t\tID: \"openrouter\",\n\t\tName: \"OpenRouter\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENROUTER_API_KEY\",\n\t\tBaseURL: \"https://openrouter.ai/api/v1\",\n\t\tDocURL: \"https://openrouter.ai/docs\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\"},\n\t},\n\t{\n\t\tID: \"openai\",\n\t\tName: \"OpenAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"OPENAI_API_KEY\",\n\t\tBaseURL: \"https://api.openai.com/v1\",\n\t\tDocURL: \"https://platform.openai.com/docs\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\", \"responses\"},\n\t},\n\t{\n\t\tID: \"ollama\",\n\t\tName: \"Ollama\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"http://localhost:11434/v1\",\n\t\tDocURL: \"https://ollama.ai/docs\",\n\t\tSupports: []string{\"streaming\", \"local\"},\n\t},\n\t{\n\t\tID: \"zai\",\n\t\tName: \"Z.ai\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"ZAI_API_KEY\",\n\t\tBaseURL: \"https://api.z.ai/api/coding/paas/v4\",\n\t\tDocURL: \"https://docs.z.ai\",\n\t\tSupports: []string{\"streaming\", \"tools\"},\n\t},\n\t{\n\t\tID: \"google\",\n\t\tName: \"Google AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GOOGLE_API_KEY\",\n\t\tBaseURL: \"https://generativelanguage.googleapis.com/v1beta/openai\",\n\t\tDocURL: \"https://ai.google.dev\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"images\"},\n\t},\n\t{\n\t\tID: \"deepseek\",\n\t\tName: \"DeepSeek\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"DEEPSEEK_API_KEY\",\n\t\tBaseURL: \"https://api.deepseek.com/v1\",\n\t\tDocURL: \"https://platform.deepseek.com/docs\",\n\t\tSupports: []string{\"streaming\", \"code\", \"reasoning\"},\n\t},\n\t{\n\t\tID: \"xai\",\n\t\tName: \"xAI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"XAI_API_KEY\",\n\t\tBaseURL: \"https://api.x.ai/v1\",\n\t\tDocURL: \"https://docs.x.ai\",\n\t\tSupports: []string{\"streaming\", \"reasoning\"},\n\t},\n\t{\n\t\tID: \"groq\",\n\t\tName: \"Groq\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"GROQ_API_KEY\",\n\t\tBaseURL: \"https://api.groq.com/openai/v1\",\n\t\tDocURL: \"https://console.groq.com/docs\",\n\t\tSupports: []string{\"streaming\", \"fast\"},\n\t},\n\t{\n\t\tID: \"together\",\n\t\tName: \"Together AI\",\n\t\tTransport: TransportOpenAIChat,\n\t\tAuthType: AuthAPIKey,\n\t\tAPIKeyEnvVar: \"TOGETHER_API_KEY\",\n\t\tBaseURL: \"https://api.together.xyz/v1\",\n\t\tDocURL: \"https://docs.together.ai\",\n\t\tSupports: []string{\"streaming\", \"models\"},\n\t},\n\t{\n\t\tID: \"bedrock\",\n\t\tName: \"AWS Bedrock\",\n\t\tTransport: TransportBedrockConverse,\n\t\tAuthType: AuthEnvVar,\n\t\tBaseURL: \"\",\n\t\tDocURL: \"https://docs.aws.amazon.com/bedrock\",\n\t\tSupports: []string{\"streaming\", \"tools\", \"aws\"},\n\t},\n}\n\n// GetProviderByID looks up a provider by its canonical ID.\nfunc GetProviderByID(id string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.ID == id {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// GetProviderByEnvVar looks up a provider by its API key environment variable.\nfunc GetProviderByEnvVar(envVar string) (*ProviderDef, bool) {\n\tfor _, p := range CanonicalProviders {\n\t\tif p.APIKeyEnvVar == envVar {\n\t\t\treturn &p, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// ListProviders returns all providers, optionally filtered by transport type.\nfunc ListProviders(transport ProviderTransport) []ProviderDef {\n\tif transport == \"\" {\n\t\treturn CanonicalProviders\n\t}\n\tvar result []ProviderDef\n\tfor _, p := range CanonicalProviders {\n\t\tif p.Transport == transport {\n\t\t\tresult = append(result, p)\n\t\t}\n\t}\n\treturn result\n}\n"}}}}