feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
// PicoClaw - Ultra-lightweight personal AI agent
|
|
|
|
|
// License: MIT
|
|
|
|
|
//
|
|
|
|
|
// Copyright (c) 2026 PicoClaw contributors
|
|
|
|
|
|
|
|
|
|
package providers
|
|
|
|
|
|
|
|
|
|
import (
|
2026-03-23 17:10:56 +00:00
|
|
|
"context"
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
2026-03-23 17:10:56 +00:00
|
|
|
"time"
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
|
|
|
|
"github.com/sipeed/picoclaw/pkg/config"
|
feat: add anthropic-messages protocol for native Anthropic Messages API support Fixes #269 (#1284)
* feat: add anthropic-messages protocol support
Add native Anthropic Messages API format support to enable
compatibility with custom endpoints that only support Anthropic's
native message format (not OpenAI-compatible format).
Changes:
- Add new pkg/providers/anthropic_messages package with HTTP-based provider
- Implement Anthropic Messages API request/response format conversion
- Add anthropic-messages protocol support in factory_provider.go
- Include comprehensive unit tests (64.2% coverage)
Features:
- Support for system, user, assistant, and tool messages
- Support for tool calls (tool_use blocks)
- Proper header handling (x-api-key, anthropic-version)
- Configurable max_tokens and temperature
- Automatic base URL normalization
Configuration example:
model: "anthropic-messages/claude-opus-4-6"
api_base: "https://api.anthropic.com"
api_key: "sk-..."
Tested with actual API endpoint, verified compatibility
with Anthropic Messages API specification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add anthropic-messages protocol examples to README and config
Add configuration examples and documentation for the new
anthropic-messages protocol:
- config.example.json: Add claude-opus-4.6 example with anthropic-messages
- README.md: Add "Anthropic Messages API (native format)" section
- README.zh.md: Add Chinese version of the documentation
This helps users understand when to use anthropic-messages vs
anthropic protocol and fixes issue #269.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format code with gofmt -s
- Align constant definitions in provider.go
- Align struct fields in test cases
- Fix gofmt formatting issues reported in review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: address linter errors
- Fix HTTP header canonical form: "x-api-key" → "X-API-Key"
- Fix HTTP header canonical form: "anthropic-version" → "Anthropic-Version"
- Format imports with gci (standard, default, localmodule order)
- Format code with golines (max line length 120)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve golangci-lint errors in anthropic-messages provider
- add nolint comment for canonicalheader rule on X-API-Key header (Anthropic API requires exact casing)
- fix golines formatting issues in provider_test.go (split long lines under 120 chars)
- fix long comment line in factory_provider.go (split into two lines)
Resolves CI linter failures for the anthropic-messages protocol implementation.
* fix(providers): address review comments in anthropic-messages provider
- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic
Resolves review comments on PR #1284
* fix(providers): remove hardcoded max_tokens in anthropic-messages provider
- remove hardcoded max_tokens value (4096) from buildRequestBody
- read max_tokens directly from options parameter
- add error handling when max_tokens is missing from options
- update test cases to include max_tokens in options
This fix ensures the provider respects the config default value (32768)
or system fallback (8192) instead of always using the hardcoded 4096.
* fix(providers): improve error handling and add edge case tests
- fix ToolCalls nil vs empty slice issue to ensure consistent JSON serialization
- add detailed HTTP error handling for common status codes (401, 429, 400, 404, 500, 503)
- add edge case tests for buildRequestBody and parseResponseBody
- clarify anthropic vs anthropic-messages protocol differences in docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 06:09:40 +00:00
|
|
|
anthropicmessages "github.com/sipeed/picoclaw/pkg/providers/anthropic_messages"
|
2026-03-14 14:52:34 +00:00
|
|
|
"github.com/sipeed/picoclaw/pkg/providers/azure"
|
2026-03-23 17:10:56 +00:00
|
|
|
"github.com/sipeed/picoclaw/pkg/providers/bedrock"
|
feat(web,api): provider selection and model form foundation (#2831)
* feat: improve model configuration workflows
Add model catalog browsing, provider registry with form validation,
model fetch/test dialogs, and enhanced model management UI.
- Add model catalog API and catalog-dialog component for browsing saved models
- Add provider-registry with auto-populated form fields per provider
- Add provider-combobox, fetch-models-dialog, test-model-dialog components
- Add model-validation for provider-aware model ID validation
- Add command and popover UI components
- Enhance edit-model-sheet with tool schema transform support
- Add anthropic to protocolMetaByName for correct default API base
- Apply NormalizeBaseURL to anthropic provider for consistent URL handling
- Add i18n keys for new model management features (en/zh)
* fix(web): prevent auto-fetch when API key is missing in fetch models dialog
When a provider requires an API key but none is set, the dialog now shows
the warning without triggering a doomed fetch attempt. Fetch is deferred
until the user provides a key.
* fix(web): add credential warning for catalog imports from remote providers
When importing models from a catalog entry whose provider requires an API
key, a yellow warning banner now informs users that credentials will need
to be configured after import.
* feat(web,api): test connection with real connectivity verification and unsaved form values
Add POST /api/models/test-inline endpoint that performs actual network
probes (GET /models) instead of just checking config. Frontend Test
Connection now uses current form values (not saved state) and is
available in both Add and Edit model flows.
* style(web): apply linter formatting across model config components
Normalize quote style, import ordering, and class name ordering as
reported by the project linter.
* fix(web,api): fix edit test connection false negative and gate fetch for unsupported providers
- handleTestInlineModel now accepts optional model_index to fall back to stored credentials when api_key is empty, fixing false negatives when testing edited models
- Add supportsFetch to provider registry and FETCHABLE_PROVIDER_KEYS derived set
- Gate Fetch Models button to only show for OpenAI-compatible and Ollama providers
- Add backend guard in handleFetchModels to reject unsupported providers with clear error
* fix: address review feedback on model config workflow
- Send explicit {} for empty extra_body/custom_headers fields so the
backend clears stored values instead of preserving them
- Merge backend provider_options with frontend PROVIDERS registry so
the provider picker reflects backend-supported providers and policy
fields (create_allowed, default_auth_method, auth_method_locked)
- Render provider combobox popover inside the sheet scroll container
to fix wheel events scrolling the sheet instead of the provider list
* feat(web,api): add provider selection, model form foundation, and validation
Split from PR #2752 (part 1 of 3).
Backend:
- CRUD model endpoints (list/add/update/delete/set-default)
- Provider metadata with default API bases and model provider options
- Model ID validation and normalization
- Anthropic default API base normalization
Frontend:
- Provider registry with metadata, labels, icons, and aliases
- Provider combobox with backend option merging
- Model field validation with provider-aware checks
- Redesigned add/edit model sheets with provider selection
- Dynamic imports for fetch/catalog/test dialogs (coming in PR2/PR3)
- i18n support for model configuration UI
2026-05-11 08:57:37 +00:00
|
|
|
"github.com/sipeed/picoclaw/pkg/providers/common"
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
)
|
|
|
|
|
|
2026-02-18 17:30:19 +00:00
|
|
|
// createClaudeAuthProvider creates a Claude provider using OAuth credentials from auth store.
|
|
|
|
|
func createClaudeAuthProvider() (LLMProvider, error) {
|
2026-02-19 16:12:01 +00:00
|
|
|
cred, err := getCredential("anthropic")
|
2026-02-18 17:30:19 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("loading auth credentials: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if cred == nil {
|
|
|
|
|
return nil, fmt.Errorf("no credentials for anthropic. Run: picoclaw auth login --provider anthropic")
|
|
|
|
|
}
|
|
|
|
|
return NewClaudeProviderWithTokenSource(cred.AccessToken, createClaudeTokenSource()), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// createCodexAuthProvider creates a Codex provider using OAuth credentials from auth store.
|
|
|
|
|
func createCodexAuthProvider() (LLMProvider, error) {
|
2026-02-19 16:12:01 +00:00
|
|
|
cred, err := getCredential("openai")
|
2026-02-18 17:30:19 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("loading auth credentials: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if cred == nil {
|
|
|
|
|
return nil, fmt.Errorf("no credentials for openai. Run: picoclaw auth login --provider openai")
|
|
|
|
|
}
|
|
|
|
|
return NewCodexProviderWithTokenSource(cred.AccessToken, cred.AccountID, createCodexTokenSource()), nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-22 03:28:47 +00:00
|
|
|
// ExtractProtocol extracts the effective protocol and model identifier from a
|
|
|
|
|
// model configuration.
|
|
|
|
|
//
|
|
|
|
|
// The explicit Provider field takes precedence. When Provider is empty, the
|
|
|
|
|
// protocol is inferred from Model. Plain model names default to "openai".
|
|
|
|
|
// Provider-prefixed models strip the first slash-separated segment from the
|
|
|
|
|
// returned model ID.
|
|
|
|
|
//
|
|
|
|
|
// The returned protocol is normalized to the provider's canonical spelling.
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
// Examples:
|
2026-04-22 03:28:47 +00:00
|
|
|
// - Model "openai/gpt-4o" -> ("openai", "gpt-4o")
|
|
|
|
|
// - Model "nvidia/z-ai/glm-5.1" -> ("nvidia", "z-ai/glm-5.1")
|
|
|
|
|
// - Provider "nvidia", Model "z-ai/glm-5.1" -> ("nvidia", "z-ai/glm-5.1")
|
|
|
|
|
// - Provider "openai", Model "openai/gpt-4o" -> ("openai", "openai/gpt-4o")
|
|
|
|
|
// - Model "gpt-4o" -> ("openai", "gpt-4o")
|
|
|
|
|
func ExtractProtocol(cfg *config.ModelConfig) (protocol, modelID string) {
|
|
|
|
|
if cfg == nil {
|
|
|
|
|
return "", ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model := strings.TrimSpace(cfg.Model)
|
|
|
|
|
if provider := strings.TrimSpace(cfg.Provider); provider != "" {
|
|
|
|
|
return NormalizeProvider(provider), model
|
|
|
|
|
}
|
2026-05-06 08:06:49 +00:00
|
|
|
return SplitModelProviderAndID(model, "openai")
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-01 04:21:21 +00:00
|
|
|
// ResolveAPIBase returns the configured API base, or the protocol default when
|
|
|
|
|
// the model uses an HTTP-based provider family with a known default endpoint.
|
|
|
|
|
func ResolveAPIBase(cfg *config.ModelConfig) string {
|
|
|
|
|
if cfg == nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
if apiBase := strings.TrimSpace(cfg.APIBase); apiBase != "" {
|
|
|
|
|
return strings.TrimRight(apiBase, "/")
|
|
|
|
|
}
|
2026-04-22 03:28:47 +00:00
|
|
|
protocol, _ := ExtractProtocol(cfg)
|
2026-04-01 04:21:21 +00:00
|
|
|
return strings.TrimRight(getDefaultAPIBase(protocol), "/")
|
|
|
|
|
}
|
|
|
|
|
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
// CreateProviderFromConfig creates a provider based on the ModelConfig.
|
2026-04-22 03:28:47 +00:00
|
|
|
// It uses ExtractProtocol to determine which provider to create.
|
2026-04-10 16:50:24 +00:00
|
|
|
// Supported protocol families include OpenAI-compatible prefixes (e.g., openai, openrouter, groq),
|
2026-03-23 17:10:56 +00:00
|
|
|
// Azure OpenAI, Amazon Bedrock, Anthropic (including messages), and various CLI/compatibility shims.
|
|
|
|
|
// See the switch on protocol in this function for the authoritative list.
|
2026-04-22 03:28:47 +00:00
|
|
|
// Returns the provider, the effective model ID from ExtractProtocol, and any error.
|
2026-02-18 17:03:34 +00:00
|
|
|
func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, error) {
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
if cfg == nil {
|
2026-02-18 17:03:34 +00:00
|
|
|
return nil, "", fmt.Errorf("config is nil")
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if cfg.Model == "" {
|
2026-02-18 17:03:34 +00:00
|
|
|
return nil, "", fmt.Errorf("model is required")
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-22 03:28:47 +00:00
|
|
|
protocol, modelID := ExtractProtocol(cfg)
|
2026-05-06 08:06:49 +00:00
|
|
|
authMethod := strings.ToLower(strings.TrimSpace(cfg.AuthMethod))
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent := cfg.UserAgent
|
|
|
|
|
if userAgent == "" {
|
|
|
|
|
userAgent = fmt.Sprintf("PicoClaw/%s", config.Version)
|
|
|
|
|
}
|
|
|
|
|
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
switch protocol {
|
2026-02-20 02:48:27 +00:00
|
|
|
case "openai":
|
|
|
|
|
// OpenAI with OAuth/token auth (Codex-style)
|
2026-05-06 08:06:49 +00:00
|
|
|
if authMethod == "oauth" || authMethod == "token" {
|
2026-02-20 02:48:27 +00:00
|
|
|
provider, err := createCodexAuthProvider()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
2026-02-20 02:48:27 +00:00
|
|
|
}
|
|
|
|
|
// OpenAI with API key
|
2026-03-21 17:55:00 +00:00
|
|
|
if cfg.APIKey() == "" && cfg.APIBase == "" {
|
2026-02-20 02:48:27 +00:00
|
|
|
return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol)
|
|
|
|
|
}
|
|
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = getDefaultAPIBase(protocol)
|
|
|
|
|
}
|
2026-04-24 13:45:41 +00:00
|
|
|
provider := NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
2026-03-21 17:55:00 +00:00
|
|
|
cfg.APIKey(),
|
2026-02-26 08:08:19 +00:00
|
|
|
apiBase,
|
|
|
|
|
cfg.Proxy,
|
|
|
|
|
cfg.MaxTokensField,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
2026-02-26 08:08:19 +00:00
|
|
|
cfg.RequestTimeout,
|
2026-03-22 07:49:25 +00:00
|
|
|
cfg.ExtraBody,
|
2026-04-07 08:05:21 +00:00
|
|
|
cfg.CustomHeaders,
|
2026-04-24 13:45:41 +00:00
|
|
|
)
|
|
|
|
|
provider.SetProviderName(protocol)
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
2026-03-14 14:52:34 +00:00
|
|
|
|
2026-05-20 03:50:34 +00:00
|
|
|
case "azure":
|
2026-05-30 13:40:29 +00:00
|
|
|
// Azure OpenAI uses deployment-based URLs. Auth is Bearer token via api_key
|
|
|
|
|
// when set; otherwise falls back to Entra ID (DefaultAzureCredential).
|
2026-03-14 14:52:34 +00:00
|
|
|
if cfg.APIBase == "" {
|
|
|
|
|
return nil, "", fmt.Errorf(
|
|
|
|
|
"api_base is required for azure protocol (e.g., https://your-resource.openai.azure.com)",
|
|
|
|
|
)
|
|
|
|
|
}
|
2026-05-30 13:40:29 +00:00
|
|
|
if cfg.APIKey() != "" {
|
|
|
|
|
return finalizeProviderFromConfig(azure.NewProviderWithTimeout(
|
|
|
|
|
cfg.APIKey(),
|
|
|
|
|
cfg.APIBase,
|
|
|
|
|
cfg.Proxy,
|
|
|
|
|
userAgent,
|
|
|
|
|
cfg.RequestTimeout,
|
|
|
|
|
), modelID, cfg)
|
|
|
|
|
}
|
|
|
|
|
provider, err := azure.NewProviderWithIdentityAndTimeout(
|
2026-03-14 14:52:34 +00:00
|
|
|
cfg.APIBase,
|
|
|
|
|
cfg.Proxy,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
2026-03-14 14:52:34 +00:00
|
|
|
cfg.RequestTimeout,
|
2026-05-30 13:40:29 +00:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
2026-02-20 02:48:27 +00:00
|
|
|
|
2026-03-23 17:10:56 +00:00
|
|
|
case "bedrock":
|
|
|
|
|
// AWS Bedrock uses AWS SDK credentials (env vars, profiles, IAM roles, etc.)
|
|
|
|
|
// api_base can be:
|
|
|
|
|
// - A full endpoint URL: https://bedrock-runtime.us-east-1.amazonaws.com
|
|
|
|
|
// - A region name: us-east-1 (AWS SDK resolves endpoint automatically)
|
|
|
|
|
var opts []bedrock.Option
|
|
|
|
|
if cfg.APIBase != "" {
|
|
|
|
|
if !strings.Contains(cfg.APIBase, "://") {
|
|
|
|
|
// Treat as region: let AWS SDK resolve the correct endpoint
|
|
|
|
|
// (supports all AWS partitions: aws, aws-cn, aws-us-gov, etc.)
|
|
|
|
|
opts = append(opts, bedrock.WithRegion(cfg.APIBase))
|
|
|
|
|
} else {
|
|
|
|
|
// Full endpoint URL provided (for custom endpoints or testing)
|
|
|
|
|
opts = append(opts, bedrock.WithBaseEndpoint(cfg.APIBase))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Use a separate timeout for AWS config loading (credential resolution can block)
|
|
|
|
|
initTimeout := 30 * time.Second
|
|
|
|
|
if cfg.RequestTimeout > 0 {
|
|
|
|
|
reqTimeout := time.Duration(cfg.RequestTimeout) * time.Second
|
|
|
|
|
// Set request timeout for API calls
|
|
|
|
|
opts = append(opts, bedrock.WithRequestTimeout(reqTimeout))
|
|
|
|
|
// Ensure init timeout is at least as large as request timeout
|
|
|
|
|
if reqTimeout > initTimeout {
|
|
|
|
|
initTimeout = reqTimeout
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), initTimeout)
|
|
|
|
|
defer cancel()
|
|
|
|
|
// Note: AWS_PROFILE env var is automatically used by AWS SDK
|
|
|
|
|
provider, err := bedrock.NewProvider(ctx, opts...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", fmt.Errorf("creating bedrock provider: %w", err)
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
2026-03-23 17:10:56 +00:00
|
|
|
|
2026-05-21 08:08:46 +00:00
|
|
|
case "litellm", "lmstudio", "gpt4free", "openrouter", "groq", "zhipu", "nvidia", "venice",
|
2026-05-18 02:16:09 +00:00
|
|
|
"ollama", "moonshot", "shengsuanyun", "siliconflow", "deepseek", "cerebras",
|
2026-05-20 03:50:34 +00:00
|
|
|
"vivgrid", "volcengine", "vllm", "qwen-portal", "qwen-intl", "qwen-us", "mistral",
|
|
|
|
|
"avian", "longcat", "modelscope", "novita", "alibaba-coding", "zai", "mimo":
|
2026-02-20 02:48:27 +00:00
|
|
|
// All other OpenAI-compatible HTTP providers
|
2026-03-31 06:48:18 +00:00
|
|
|
if cfg.APIKey() == "" && cfg.APIBase == "" && !isEmptyAPIKeyAllowed(protocol) {
|
2026-02-18 17:03:34 +00:00
|
|
|
return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
}
|
|
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = getDefaultAPIBase(protocol)
|
|
|
|
|
}
|
2026-04-24 13:45:41 +00:00
|
|
|
provider := NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
2026-03-21 17:55:00 +00:00
|
|
|
cfg.APIKey(),
|
2026-02-26 08:08:19 +00:00
|
|
|
apiBase,
|
|
|
|
|
cfg.Proxy,
|
|
|
|
|
cfg.MaxTokensField,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
2026-02-26 08:08:19 +00:00
|
|
|
cfg.RequestTimeout,
|
2026-03-22 07:49:25 +00:00
|
|
|
cfg.ExtraBody,
|
2026-04-07 08:05:21 +00:00
|
|
|
cfg.CustomHeaders,
|
2026-04-24 13:45:41 +00:00
|
|
|
)
|
|
|
|
|
provider.SetProviderName(protocol)
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
2026-04-10 16:50:24 +00:00
|
|
|
case "gemini":
|
|
|
|
|
if cfg.APIKey() == "" && cfg.APIBase == "" {
|
|
|
|
|
return nil, "", fmt.Errorf("api_key or api_base is required for gemini protocol (model: %s)", cfg.Model)
|
|
|
|
|
}
|
|
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = getDefaultAPIBase(protocol)
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(NewGeminiProvider(
|
2026-04-10 16:50:24 +00:00
|
|
|
cfg.APIKey(),
|
|
|
|
|
apiBase,
|
|
|
|
|
cfg.Proxy,
|
|
|
|
|
userAgent,
|
|
|
|
|
cfg.RequestTimeout,
|
|
|
|
|
cfg.ExtraBody,
|
|
|
|
|
cfg.CustomHeaders,
|
2026-04-27 19:10:30 +00:00
|
|
|
), modelID, cfg)
|
2026-04-10 16:50:24 +00:00
|
|
|
|
2026-03-22 12:37:06 +00:00
|
|
|
case "minimax":
|
|
|
|
|
// Minimax requires reasoning_split: true in the request body
|
2026-03-23 07:51:13 +00:00
|
|
|
if cfg.APIKey() == "" && cfg.APIBase == "" {
|
2026-03-22 12:37:06 +00:00
|
|
|
return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol)
|
|
|
|
|
}
|
|
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = getDefaultAPIBase(protocol)
|
|
|
|
|
}
|
|
|
|
|
extraBody := cfg.ExtraBody
|
|
|
|
|
if extraBody == nil {
|
|
|
|
|
extraBody = make(map[string]any)
|
|
|
|
|
}
|
|
|
|
|
if _, ok := extraBody["reasoning_split"]; !ok {
|
|
|
|
|
extraBody["reasoning_split"] = true
|
|
|
|
|
}
|
2026-04-24 13:45:41 +00:00
|
|
|
provider := NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
2026-03-23 07:51:13 +00:00
|
|
|
cfg.APIKey(),
|
2026-03-22 12:37:06 +00:00
|
|
|
apiBase,
|
|
|
|
|
cfg.Proxy,
|
|
|
|
|
cfg.MaxTokensField,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
2026-03-22 12:37:06 +00:00
|
|
|
cfg.RequestTimeout,
|
|
|
|
|
extraBody,
|
2026-04-07 08:05:21 +00:00
|
|
|
cfg.CustomHeaders,
|
2026-04-24 13:45:41 +00:00
|
|
|
)
|
|
|
|
|
provider.SetProviderName(protocol)
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
2026-03-22 12:37:06 +00:00
|
|
|
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
case "anthropic":
|
2026-05-06 08:06:49 +00:00
|
|
|
if authMethod == "oauth" || authMethod == "token" {
|
2026-02-18 17:30:19 +00:00
|
|
|
// Use OAuth credentials from auth store
|
|
|
|
|
provider, err := createClaudeAuthProvider()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
}
|
2026-02-18 17:30:19 +00:00
|
|
|
// Use API key with HTTP API
|
feat(web,api): provider selection and model form foundation (#2831)
* feat: improve model configuration workflows
Add model catalog browsing, provider registry with form validation,
model fetch/test dialogs, and enhanced model management UI.
- Add model catalog API and catalog-dialog component for browsing saved models
- Add provider-registry with auto-populated form fields per provider
- Add provider-combobox, fetch-models-dialog, test-model-dialog components
- Add model-validation for provider-aware model ID validation
- Add command and popover UI components
- Enhance edit-model-sheet with tool schema transform support
- Add anthropic to protocolMetaByName for correct default API base
- Apply NormalizeBaseURL to anthropic provider for consistent URL handling
- Add i18n keys for new model management features (en/zh)
* fix(web): prevent auto-fetch when API key is missing in fetch models dialog
When a provider requires an API key but none is set, the dialog now shows
the warning without triggering a doomed fetch attempt. Fetch is deferred
until the user provides a key.
* fix(web): add credential warning for catalog imports from remote providers
When importing models from a catalog entry whose provider requires an API
key, a yellow warning banner now informs users that credentials will need
to be configured after import.
* feat(web,api): test connection with real connectivity verification and unsaved form values
Add POST /api/models/test-inline endpoint that performs actual network
probes (GET /models) instead of just checking config. Frontend Test
Connection now uses current form values (not saved state) and is
available in both Add and Edit model flows.
* style(web): apply linter formatting across model config components
Normalize quote style, import ordering, and class name ordering as
reported by the project linter.
* fix(web,api): fix edit test connection false negative and gate fetch for unsupported providers
- handleTestInlineModel now accepts optional model_index to fall back to stored credentials when api_key is empty, fixing false negatives when testing edited models
- Add supportsFetch to provider registry and FETCHABLE_PROVIDER_KEYS derived set
- Gate Fetch Models button to only show for OpenAI-compatible and Ollama providers
- Add backend guard in handleFetchModels to reject unsupported providers with clear error
* fix: address review feedback on model config workflow
- Send explicit {} for empty extra_body/custom_headers fields so the
backend clears stored values instead of preserving them
- Merge backend provider_options with frontend PROVIDERS registry so
the provider picker reflects backend-supported providers and policy
fields (create_allowed, default_auth_method, auth_method_locked)
- Render provider combobox popover inside the sheet scroll container
to fix wheel events scrolling the sheet instead of the provider list
* feat(web,api): add provider selection, model form foundation, and validation
Split from PR #2752 (part 1 of 3).
Backend:
- CRUD model endpoints (list/add/update/delete/set-default)
- Provider metadata with default API bases and model provider options
- Model ID validation and normalization
- Anthropic default API base normalization
Frontend:
- Provider registry with metadata, labels, icons, and aliases
- Provider combobox with backend option merging
- Model field validation with provider-aware checks
- Redesigned add/edit model sheets with provider selection
- Dynamic imports for fetch/catalog/test dialogs (coming in PR2/PR3)
- i18n support for model configuration UI
2026-05-11 08:57:37 +00:00
|
|
|
apiBase := common.NormalizeBaseURL(cfg.APIBase, "https://api.anthropic.com/v1", true)
|
2026-03-21 17:55:00 +00:00
|
|
|
if cfg.APIKey() == "" {
|
2026-02-18 17:30:19 +00:00
|
|
|
return nil, "", fmt.Errorf("api_key is required for anthropic protocol (model: %s)", cfg.Model)
|
|
|
|
|
}
|
2026-04-24 13:45:41 +00:00
|
|
|
provider := NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
2026-03-21 17:55:00 +00:00
|
|
|
cfg.APIKey(),
|
2026-02-26 08:08:19 +00:00
|
|
|
apiBase,
|
|
|
|
|
cfg.Proxy,
|
|
|
|
|
cfg.MaxTokensField,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
2026-02-26 08:08:19 +00:00
|
|
|
cfg.RequestTimeout,
|
2026-03-22 07:49:25 +00:00
|
|
|
cfg.ExtraBody,
|
2026-04-07 08:05:21 +00:00
|
|
|
cfg.CustomHeaders,
|
2026-04-24 13:45:41 +00:00
|
|
|
)
|
|
|
|
|
provider.SetProviderName(protocol)
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
feat: add anthropic-messages protocol for native Anthropic Messages API support Fixes #269 (#1284)
* feat: add anthropic-messages protocol support
Add native Anthropic Messages API format support to enable
compatibility with custom endpoints that only support Anthropic's
native message format (not OpenAI-compatible format).
Changes:
- Add new pkg/providers/anthropic_messages package with HTTP-based provider
- Implement Anthropic Messages API request/response format conversion
- Add anthropic-messages protocol support in factory_provider.go
- Include comprehensive unit tests (64.2% coverage)
Features:
- Support for system, user, assistant, and tool messages
- Support for tool calls (tool_use blocks)
- Proper header handling (x-api-key, anthropic-version)
- Configurable max_tokens and temperature
- Automatic base URL normalization
Configuration example:
model: "anthropic-messages/claude-opus-4-6"
api_base: "https://api.anthropic.com"
api_key: "sk-..."
Tested with actual API endpoint, verified compatibility
with Anthropic Messages API specification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add anthropic-messages protocol examples to README and config
Add configuration examples and documentation for the new
anthropic-messages protocol:
- config.example.json: Add claude-opus-4.6 example with anthropic-messages
- README.md: Add "Anthropic Messages API (native format)" section
- README.zh.md: Add Chinese version of the documentation
This helps users understand when to use anthropic-messages vs
anthropic protocol and fixes issue #269.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format code with gofmt -s
- Align constant definitions in provider.go
- Align struct fields in test cases
- Fix gofmt formatting issues reported in review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: address linter errors
- Fix HTTP header canonical form: "x-api-key" → "X-API-Key"
- Fix HTTP header canonical form: "anthropic-version" → "Anthropic-Version"
- Format imports with gci (standard, default, localmodule order)
- Format code with golines (max line length 120)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve golangci-lint errors in anthropic-messages provider
- add nolint comment for canonicalheader rule on X-API-Key header (Anthropic API requires exact casing)
- fix golines formatting issues in provider_test.go (split long lines under 120 chars)
- fix long comment line in factory_provider.go (split into two lines)
Resolves CI linter failures for the anthropic-messages protocol implementation.
* fix(providers): address review comments in anthropic-messages provider
- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic
Resolves review comments on PR #1284
* fix(providers): remove hardcoded max_tokens in anthropic-messages provider
- remove hardcoded max_tokens value (4096) from buildRequestBody
- read max_tokens directly from options parameter
- add error handling when max_tokens is missing from options
- update test cases to include max_tokens in options
This fix ensures the provider respects the config default value (32768)
or system fallback (8192) instead of always using the hardcoded 4096.
* fix(providers): improve error handling and add edge case tests
- fix ToolCalls nil vs empty slice issue to ensure consistent JSON serialization
- add detailed HTTP error handling for common status codes (401, 429, 400, 404, 500, 503)
- add edge case tests for buildRequestBody and parseResponseBody
- clarify anthropic vs anthropic-messages protocol differences in docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 06:09:40 +00:00
|
|
|
case "anthropic-messages":
|
|
|
|
|
// Anthropic Messages API with native format (HTTP-based, no SDK)
|
|
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = "https://api.anthropic.com/v1"
|
|
|
|
|
}
|
2026-03-21 17:55:00 +00:00
|
|
|
if cfg.APIKey() == "" {
|
feat: add anthropic-messages protocol for native Anthropic Messages API support Fixes #269 (#1284)
* feat: add anthropic-messages protocol support
Add native Anthropic Messages API format support to enable
compatibility with custom endpoints that only support Anthropic's
native message format (not OpenAI-compatible format).
Changes:
- Add new pkg/providers/anthropic_messages package with HTTP-based provider
- Implement Anthropic Messages API request/response format conversion
- Add anthropic-messages protocol support in factory_provider.go
- Include comprehensive unit tests (64.2% coverage)
Features:
- Support for system, user, assistant, and tool messages
- Support for tool calls (tool_use blocks)
- Proper header handling (x-api-key, anthropic-version)
- Configurable max_tokens and temperature
- Automatic base URL normalization
Configuration example:
model: "anthropic-messages/claude-opus-4-6"
api_base: "https://api.anthropic.com"
api_key: "sk-..."
Tested with actual API endpoint, verified compatibility
with Anthropic Messages API specification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add anthropic-messages protocol examples to README and config
Add configuration examples and documentation for the new
anthropic-messages protocol:
- config.example.json: Add claude-opus-4.6 example with anthropic-messages
- README.md: Add "Anthropic Messages API (native format)" section
- README.zh.md: Add Chinese version of the documentation
This helps users understand when to use anthropic-messages vs
anthropic protocol and fixes issue #269.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format code with gofmt -s
- Align constant definitions in provider.go
- Align struct fields in test cases
- Fix gofmt formatting issues reported in review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: address linter errors
- Fix HTTP header canonical form: "x-api-key" → "X-API-Key"
- Fix HTTP header canonical form: "anthropic-version" → "Anthropic-Version"
- Format imports with gci (standard, default, localmodule order)
- Format code with golines (max line length 120)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve golangci-lint errors in anthropic-messages provider
- add nolint comment for canonicalheader rule on X-API-Key header (Anthropic API requires exact casing)
- fix golines formatting issues in provider_test.go (split long lines under 120 chars)
- fix long comment line in factory_provider.go (split into two lines)
Resolves CI linter failures for the anthropic-messages protocol implementation.
* fix(providers): address review comments in anthropic-messages provider
- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic
Resolves review comments on PR #1284
* fix(providers): remove hardcoded max_tokens in anthropic-messages provider
- remove hardcoded max_tokens value (4096) from buildRequestBody
- read max_tokens directly from options parameter
- add error handling when max_tokens is missing from options
- update test cases to include max_tokens in options
This fix ensures the provider respects the config default value (32768)
or system fallback (8192) instead of always using the hardcoded 4096.
* fix(providers): improve error handling and add edge case tests
- fix ToolCalls nil vs empty slice issue to ensure consistent JSON serialization
- add detailed HTTP error handling for common status codes (401, 429, 400, 404, 500, 503)
- add edge case tests for buildRequestBody and parseResponseBody
- clarify anthropic vs anthropic-messages protocol differences in docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 06:09:40 +00:00
|
|
|
return nil, "", fmt.Errorf("api_key is required for anthropic-messages protocol (model: %s)", cfg.Model)
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(anthropicmessages.NewProviderWithTimeout(
|
2026-03-21 17:55:00 +00:00
|
|
|
cfg.APIKey(),
|
feat: add anthropic-messages protocol for native Anthropic Messages API support Fixes #269 (#1284)
* feat: add anthropic-messages protocol support
Add native Anthropic Messages API format support to enable
compatibility with custom endpoints that only support Anthropic's
native message format (not OpenAI-compatible format).
Changes:
- Add new pkg/providers/anthropic_messages package with HTTP-based provider
- Implement Anthropic Messages API request/response format conversion
- Add anthropic-messages protocol support in factory_provider.go
- Include comprehensive unit tests (64.2% coverage)
Features:
- Support for system, user, assistant, and tool messages
- Support for tool calls (tool_use blocks)
- Proper header handling (x-api-key, anthropic-version)
- Configurable max_tokens and temperature
- Automatic base URL normalization
Configuration example:
model: "anthropic-messages/claude-opus-4-6"
api_base: "https://api.anthropic.com"
api_key: "sk-..."
Tested with actual API endpoint, verified compatibility
with Anthropic Messages API specification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add anthropic-messages protocol examples to README and config
Add configuration examples and documentation for the new
anthropic-messages protocol:
- config.example.json: Add claude-opus-4.6 example with anthropic-messages
- README.md: Add "Anthropic Messages API (native format)" section
- README.zh.md: Add Chinese version of the documentation
This helps users understand when to use anthropic-messages vs
anthropic protocol and fixes issue #269.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format code with gofmt -s
- Align constant definitions in provider.go
- Align struct fields in test cases
- Fix gofmt formatting issues reported in review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: address linter errors
- Fix HTTP header canonical form: "x-api-key" → "X-API-Key"
- Fix HTTP header canonical form: "anthropic-version" → "Anthropic-Version"
- Format imports with gci (standard, default, localmodule order)
- Format code with golines (max line length 120)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve golangci-lint errors in anthropic-messages provider
- add nolint comment for canonicalheader rule on X-API-Key header (Anthropic API requires exact casing)
- fix golines formatting issues in provider_test.go (split long lines under 120 chars)
- fix long comment line in factory_provider.go (split into two lines)
Resolves CI linter failures for the anthropic-messages protocol implementation.
* fix(providers): address review comments in anthropic-messages provider
- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic
Resolves review comments on PR #1284
* fix(providers): remove hardcoded max_tokens in anthropic-messages provider
- remove hardcoded max_tokens value (4096) from buildRequestBody
- read max_tokens directly from options parameter
- add error handling when max_tokens is missing from options
- update test cases to include max_tokens in options
This fix ensures the provider respects the config default value (32768)
or system fallback (8192) instead of always using the hardcoded 4096.
* fix(providers): improve error handling and add edge case tests
- fix ToolCalls nil vs empty slice issue to ensure consistent JSON serialization
- add detailed HTTP error handling for common status codes (401, 429, 400, 404, 500, 503)
- add edge case tests for buildRequestBody and parseResponseBody
- clarify anthropic vs anthropic-messages protocol differences in docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 06:09:40 +00:00
|
|
|
apiBase,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
feat: add anthropic-messages protocol for native Anthropic Messages API support Fixes #269 (#1284)
* feat: add anthropic-messages protocol support
Add native Anthropic Messages API format support to enable
compatibility with custom endpoints that only support Anthropic's
native message format (not OpenAI-compatible format).
Changes:
- Add new pkg/providers/anthropic_messages package with HTTP-based provider
- Implement Anthropic Messages API request/response format conversion
- Add anthropic-messages protocol support in factory_provider.go
- Include comprehensive unit tests (64.2% coverage)
Features:
- Support for system, user, assistant, and tool messages
- Support for tool calls (tool_use blocks)
- Proper header handling (x-api-key, anthropic-version)
- Configurable max_tokens and temperature
- Automatic base URL normalization
Configuration example:
model: "anthropic-messages/claude-opus-4-6"
api_base: "https://api.anthropic.com"
api_key: "sk-..."
Tested with actual API endpoint, verified compatibility
with Anthropic Messages API specification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add anthropic-messages protocol examples to README and config
Add configuration examples and documentation for the new
anthropic-messages protocol:
- config.example.json: Add claude-opus-4.6 example with anthropic-messages
- README.md: Add "Anthropic Messages API (native format)" section
- README.zh.md: Add Chinese version of the documentation
This helps users understand when to use anthropic-messages vs
anthropic protocol and fixes issue #269.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format code with gofmt -s
- Align constant definitions in provider.go
- Align struct fields in test cases
- Fix gofmt formatting issues reported in review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: address linter errors
- Fix HTTP header canonical form: "x-api-key" → "X-API-Key"
- Fix HTTP header canonical form: "anthropic-version" → "Anthropic-Version"
- Format imports with gci (standard, default, localmodule order)
- Format code with golines (max line length 120)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve golangci-lint errors in anthropic-messages provider
- add nolint comment for canonicalheader rule on X-API-Key header (Anthropic API requires exact casing)
- fix golines formatting issues in provider_test.go (split long lines under 120 chars)
- fix long comment line in factory_provider.go (split into two lines)
Resolves CI linter failures for the anthropic-messages protocol implementation.
* fix(providers): address review comments in anthropic-messages provider
- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic
Resolves review comments on PR #1284
* fix(providers): remove hardcoded max_tokens in anthropic-messages provider
- remove hardcoded max_tokens value (4096) from buildRequestBody
- read max_tokens directly from options parameter
- add error handling when max_tokens is missing from options
- update test cases to include max_tokens in options
This fix ensures the provider respects the config default value (32768)
or system fallback (8192) instead of always using the hardcoded 4096.
* fix(providers): improve error handling and add edge case tests
- fix ToolCalls nil vs empty slice issue to ensure consistent JSON serialization
- add detailed HTTP error handling for common status codes (401, 429, 400, 404, 500, 503)
- add edge case tests for buildRequestBody and parseResponseBody
- clarify anthropic vs anthropic-messages protocol differences in docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 06:09:40 +00:00
|
|
|
cfg.RequestTimeout,
|
2026-04-27 19:10:30 +00:00
|
|
|
), modelID, cfg)
|
feat: add anthropic-messages protocol for native Anthropic Messages API support Fixes #269 (#1284)
* feat: add anthropic-messages protocol support
Add native Anthropic Messages API format support to enable
compatibility with custom endpoints that only support Anthropic's
native message format (not OpenAI-compatible format).
Changes:
- Add new pkg/providers/anthropic_messages package with HTTP-based provider
- Implement Anthropic Messages API request/response format conversion
- Add anthropic-messages protocol support in factory_provider.go
- Include comprehensive unit tests (64.2% coverage)
Features:
- Support for system, user, assistant, and tool messages
- Support for tool calls (tool_use blocks)
- Proper header handling (x-api-key, anthropic-version)
- Configurable max_tokens and temperature
- Automatic base URL normalization
Configuration example:
model: "anthropic-messages/claude-opus-4-6"
api_base: "https://api.anthropic.com"
api_key: "sk-..."
Tested with actual API endpoint, verified compatibility
with Anthropic Messages API specification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs: add anthropic-messages protocol examples to README and config
Add configuration examples and documentation for the new
anthropic-messages protocol:
- config.example.json: Add claude-opus-4.6 example with anthropic-messages
- README.md: Add "Anthropic Messages API (native format)" section
- README.zh.md: Add Chinese version of the documentation
This helps users understand when to use anthropic-messages vs
anthropic protocol and fixes issue #269.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: format code with gofmt -s
- Align constant definitions in provider.go
- Align struct fields in test cases
- Fix gofmt formatting issues reported in review
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: address linter errors
- Fix HTTP header canonical form: "x-api-key" → "X-API-Key"
- Fix HTTP header canonical form: "anthropic-version" → "Anthropic-Version"
- Format imports with gci (standard, default, localmodule order)
- Format code with golines (max line length 120)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve golangci-lint errors in anthropic-messages provider
- add nolint comment for canonicalheader rule on X-API-Key header (Anthropic API requires exact casing)
- fix golines formatting issues in provider_test.go (split long lines under 120 chars)
- fix long comment line in factory_provider.go (split into two lines)
Resolves CI linter failures for the anthropic-messages protocol implementation.
* fix(providers): address review comments in anthropic-messages provider
- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic
Resolves review comments on PR #1284
* fix(providers): remove hardcoded max_tokens in anthropic-messages provider
- remove hardcoded max_tokens value (4096) from buildRequestBody
- read max_tokens directly from options parameter
- add error handling when max_tokens is missing from options
- update test cases to include max_tokens in options
This fix ensures the provider respects the config default value (32768)
or system fallback (8192) instead of always using the hardcoded 4096.
* fix(providers): improve error handling and add edge case tests
- fix ToolCalls nil vs empty slice issue to ensure consistent JSON serialization
- add detailed HTTP error handling for common status codes (401, 429, 400, 404, 500, 503)
- add edge case tests for buildRequestBody and parseResponseBody
- clarify anthropic vs anthropic-messages protocol differences in docs
---------
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 06:09:40 +00:00
|
|
|
|
2026-05-20 03:50:34 +00:00
|
|
|
case "alibaba-coding-anthropic":
|
2026-03-19 14:07:30 +00:00
|
|
|
// Alibaba Coding Plan with Anthropic-compatible API
|
|
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = getDefaultAPIBase(protocol)
|
|
|
|
|
}
|
2026-03-21 18:45:09 +00:00
|
|
|
if cfg.APIKey() == "" {
|
2026-03-19 14:07:30 +00:00
|
|
|
return nil, "", fmt.Errorf("api_key is required for %q protocol (model: %s)", protocol, cfg.Model)
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(anthropicmessages.NewProviderWithTimeout(
|
2026-03-21 18:45:09 +00:00
|
|
|
cfg.APIKey(),
|
2026-03-19 14:07:30 +00:00
|
|
|
apiBase,
|
2026-04-02 03:44:13 +00:00
|
|
|
userAgent,
|
2026-03-19 14:07:30 +00:00
|
|
|
cfg.RequestTimeout,
|
2026-04-27 19:10:30 +00:00
|
|
|
), modelID, cfg)
|
2026-03-19 14:07:30 +00:00
|
|
|
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
case "antigravity":
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(NewAntigravityProvider(), modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
2026-05-20 03:50:34 +00:00
|
|
|
case "claude-cli":
|
2026-02-18 17:30:19 +00:00
|
|
|
workspace := cfg.Workspace
|
|
|
|
|
if workspace == "" {
|
|
|
|
|
workspace = "."
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(NewClaudeCliProvider(workspace), modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
2026-05-20 03:50:34 +00:00
|
|
|
case "codex-cli":
|
2026-02-18 17:30:19 +00:00
|
|
|
workspace := cfg.Workspace
|
|
|
|
|
if workspace == "" {
|
|
|
|
|
workspace = "."
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(NewCodexCliProvider(workspace), modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
2026-05-20 03:50:34 +00:00
|
|
|
case "github-copilot":
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
apiBase := cfg.APIBase
|
|
|
|
|
if apiBase == "" {
|
|
|
|
|
apiBase = "localhost:4321"
|
|
|
|
|
}
|
|
|
|
|
connectMode := cfg.ConnectMode
|
|
|
|
|
if connectMode == "" {
|
|
|
|
|
connectMode = "grpc"
|
|
|
|
|
}
|
2026-02-18 17:03:34 +00:00
|
|
|
provider, err := NewGitHubCopilotProvider(apiBase, connectMode, modelID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
2026-04-27 19:10:30 +00:00
|
|
|
return finalizeProviderFromConfig(provider, modelID, cfg)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
|
|
|
|
|
default:
|
2026-02-18 17:03:34 +00:00
|
|
|
return nil, "", fmt.Errorf("unknown protocol %q in model %q", protocol, cfg.Model)
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-27 19:10:30 +00:00
|
|
|
func finalizeProviderFromConfig(
|
|
|
|
|
provider LLMProvider,
|
|
|
|
|
modelID string,
|
|
|
|
|
cfg *config.ModelConfig,
|
|
|
|
|
) (LLMProvider, string, error) {
|
|
|
|
|
wrapped, err := wrapProviderWithToolSchemaTransform(provider, cfg.ToolSchemaTransform)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return wrapped, modelID, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 06:48:18 +00:00
|
|
|
func isEmptyAPIKeyAllowed(protocol string) bool {
|
2026-05-20 03:50:34 +00:00
|
|
|
option, ok := modelProviderOptionForName(protocol)
|
|
|
|
|
return ok && option.EmptyAPIKeyAllowed
|
2026-03-31 06:48:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsEmptyAPIKeyAllowedForProtocol reports whether a protocol allows requests
|
|
|
|
|
// without api_key when using its default local endpoint.
|
|
|
|
|
func IsEmptyAPIKeyAllowedForProtocol(protocol string) bool {
|
|
|
|
|
protocol = strings.ToLower(strings.TrimSpace(protocol))
|
|
|
|
|
return isEmptyAPIKeyAllowed(protocol)
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-20 03:50:34 +00:00
|
|
|
// IsHTTPAPIProtocol reports whether a provider uses an HTTP API base in the
|
|
|
|
|
// model configuration path. This excludes providers such as Bedrock, CLI
|
|
|
|
|
// bridges, and OAuth-only managed providers even if they do not require an
|
|
|
|
|
// explicit api_key field.
|
|
|
|
|
func IsHTTPAPIProtocol(protocol string) bool {
|
|
|
|
|
protocol = NormalizeProvider(protocol)
|
|
|
|
|
option, ok := modelProviderOptionsByName[protocol]
|
|
|
|
|
return ok && option.httpAPI
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 06:48:18 +00:00
|
|
|
// DefaultAPIBaseForProtocol returns the configured default API base for a protocol.
|
|
|
|
|
// It returns empty string if the protocol has no default base.
|
|
|
|
|
func DefaultAPIBaseForProtocol(protocol string) string {
|
|
|
|
|
protocol = strings.ToLower(strings.TrimSpace(protocol))
|
|
|
|
|
return getDefaultAPIBase(protocol)
|
|
|
|
|
}
|
|
|
|
|
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
// getDefaultAPIBase returns the default API base URL for a given protocol.
|
|
|
|
|
func getDefaultAPIBase(protocol string) string {
|
2026-05-20 03:50:34 +00:00
|
|
|
option, ok := modelProviderOptionForName(protocol)
|
2026-03-31 06:48:18 +00:00
|
|
|
if !ok {
|
feat: add model_list configuration for zero-code provider addition
- Add ModelConfig struct with protocol prefix support (openai/, anthropic/, etc.)
- Implement GetModelConfig with round-robin load balancing
- Add CreateProviderFromConfig factory for protocol-based routing
- Add ModelRegistry for thread-safe endpoint selection
- Maintain full backward compatibility with legacy providers config
- Update README.md and README.zh.md with model_list documentation
- Add migration guide at docs/migration/model-list-migration.md
Supported protocols: openai, anthropic, antigravity, claude-cli, codex-cli,
github-copilot, openrouter, groq, deepseek, cerebras, qwen, zhipu, gemini
Closes #283
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:26:00 +00:00
|
|
|
return ""
|
|
|
|
|
}
|
2026-05-20 03:50:34 +00:00
|
|
|
return option.DefaultAPIBase
|
2026-05-06 08:06:49 +00:00
|
|
|
}
|