mirror of
https://github.com/oxynote/oxynote.git
synced 2026-10-17 10:59:20 +02:00
use aliases for claude and gemini providers
This commit is contained in:
parent
a17c91b4be
commit
41975ebc71
|
|
@ -65,7 +65,7 @@ by picking a provider in `docker/env/core.local.env`; the model is
|
|||
optional and defaults to the provider's strongest supported one:
|
||||
|
||||
```sh
|
||||
OXYNOTE_CORE_ASSISTANT_PROVIDER=claude
|
||||
OXYNOTE_CORE_ASSISTANT_PROVIDER=anthropic
|
||||
OXYNOTE_CORE_ASSISTANT_MODEL=claude-opus-4-6
|
||||
OXYNOTE_CORE_ASSISTANT_API_KEY=sk-...
|
||||
```
|
||||
|
|
@ -74,9 +74,9 @@ Switching providers is an env change and a restart — no rebuild.
|
|||
|
||||
| provider | credentials | supported models |
|
||||
| --- | --- | --- |
|
||||
| `claude` | `ASSISTANT_API_KEY`, or `ASSISTANT_BEDROCK_*` / `ASSISTANT_VERTEX_*` | `claude-fable-5`, `claude-opus-5` (default), `claude-opus-4-6`, `claude-sonnet-5`, `claude-sonnet-4-6`, `claude-haiku-4-5` |
|
||||
| `openai` | `ASSISTANT_API_KEY` (+ `ASSISTANT_AZURE_API_VERSION` for Azure) | `gpt-5.1` (default), `gpt-5`, `gpt-5-mini`, `gpt-5-nano` |
|
||||
| `gemini` | `ASSISTANT_API_KEY` | `gemini-3-pro-preview`, `gemini-2.5-pro` (default), `gemini-2.5-flash`, `gemini-2.5-flash-lite` |
|
||||
| `anthropic` | `ASSISTANT_API_KEY`, or `ASSISTANT_BEDROCK_*` / `ASSISTANT_VERTEX_*` | `claude-fable-5`, `claude-opus-5` (default), `claude-opus-4-6`, `claude-sonnet-5`, `claude-sonnet-4-6` |
|
||||
| `openai` | `ASSISTANT_API_KEY` (+ `ASSISTANT_AZURE_API_VERSION` for Azure) | `gpt-5.1` (default), `gpt-5`, `gpt-5-mini` |
|
||||
| `google` | `ASSISTANT_API_KEY` | `gemini-3-pro-preview`, `gemini-2.5-pro` (default), `gemini-2.5-flash` |
|
||||
| `ollama` | none; set `ASSISTANT_BASE_URL` to your server | `llama3.3:70b` (default), `qwen3:32b` |
|
||||
| `openrouter` | `ASSISTANT_API_KEY` | the models above behind their vendor prefix (`anthropic/claude-opus-5` (default), `openai/gpt-5`, `google/gemini-2.5-pro`, …) |
|
||||
|
||||
|
|
|
|||
6
docker/env/core.example.env
vendored
6
docker/env/core.example.env
vendored
|
|
@ -60,7 +60,7 @@ OXYNOTE_CORE_SLACK_REDIRECT_URL=http://localhost:8080/slack
|
|||
OXYNOTE_CORE_SLACK_INSTALLATION_SIGNING_SECRET=
|
||||
# AI assistant. An empty PROVIDER disables the assistant: core boots,
|
||||
# the chat endpoint refuses, and the MCP surface keeps working. To
|
||||
# enable it, set PROVIDER to the vendor (claude, openai, gemini, ollama,
|
||||
# enable it, set PROVIDER to the vendor (anthropic, openai, google, ollama,
|
||||
# or openrouter) and the credentials the vendor needs (an API key for
|
||||
# every provider except ollama); a set provider with missing pieces is a
|
||||
# boot error. MODEL is the vendor's own model identifier and is
|
||||
|
|
@ -85,13 +85,13 @@ OXYNOTE_CORE_ASSISTANT_REQUEST_TIMEOUT=10m
|
|||
OXYNOTE_CORE_ASSISTANT_SUMMARY_MODEL=
|
||||
# optional, PROVIDER=openai only: set to target Azure OpenAI.
|
||||
OXYNOTE_CORE_ASSISTANT_AZURE_API_VERSION=
|
||||
# optional, PROVIDER=claude only: set REGION to reach Claude via AWS
|
||||
# optional, PROVIDER=anthropic only: set REGION to reach Claude via AWS
|
||||
# Bedrock. Leave the keys empty to use the ambient AWS credential chain.
|
||||
OXYNOTE_CORE_ASSISTANT_BEDROCK_REGION=
|
||||
OXYNOTE_CORE_ASSISTANT_BEDROCK_ACCESS_KEY=
|
||||
OXYNOTE_CORE_ASSISTANT_BEDROCK_SECRET_ACCESS_KEY=
|
||||
OXYNOTE_CORE_ASSISTANT_BEDROCK_SESSION_TOKEN=
|
||||
# optional, PROVIDER=claude only: set PROJECT_ID to reach Claude via
|
||||
# optional, PROVIDER=anthropic only: set PROJECT_ID to reach Claude via
|
||||
# Google Vertex. Leave the service account empty to use application
|
||||
# default credentials.
|
||||
OXYNOTE_CORE_ASSISTANT_VERTEX_PROJECT_ID=
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ func assistantProviderOptions() (provider.Options, error) {
|
|||
Enabled: buildinfo.Getenv("ASSISTANT_AZURE_API_VERSION") != "",
|
||||
APIVersion: buildinfo.Getenv("ASSISTANT_AZURE_API_VERSION"),
|
||||
}
|
||||
case provider.ProviderClaude:
|
||||
case provider.ProviderAnthropic:
|
||||
opts.Bedrock = provider.BedrockOptions{
|
||||
Enabled: buildinfo.Getenv("ASSISTANT_BEDROCK_REGION") != "",
|
||||
Region: buildinfo.Getenv("ASSISTANT_BEDROCK_REGION"),
|
||||
|
|
@ -558,7 +558,7 @@ func assistantProviderOptions() (provider.Options, error) {
|
|||
Region: buildinfo.Getenv("ASSISTANT_VERTEX_REGION"),
|
||||
ServiceAccountJSON: []byte(buildinfo.Getenv("ASSISTANT_VERTEX_SERVICE_ACCOUNT_JSON")),
|
||||
}
|
||||
case provider.ProviderGemini, provider.ProviderOllama, provider.ProviderOpenRouter:
|
||||
case provider.ProviderGoogle, provider.ProviderOllama, provider.ProviderOpenRouter:
|
||||
// no vendor-specific settings beyond the common ones.
|
||||
}
|
||||
|
||||
|
|
@ -597,13 +597,13 @@ func assistantModels(ctx context.Context, log *slog.Logger) (
|
|||
}
|
||||
|
||||
switch status {
|
||||
case provider.StatusActive:
|
||||
case provider.StatusActive, provider.StatusInactive:
|
||||
// nothing to warn about: full strength needs no caveat, and
|
||||
// inactive only arrives alongside an error handled above.
|
||||
case provider.StatusActiveButWeak:
|
||||
log.Warn("assistant model is weaker than recommended", slog.String("model", opts.Model))
|
||||
case provider.StatusInactiveTooWeak:
|
||||
log.Warn("assistant model is too weak to run the assistant", slog.String("model", opts.Model))
|
||||
case provider.StatusInactive:
|
||||
log.Warn("assistant model is not supported", slog.String("model", opts.Model))
|
||||
}
|
||||
|
||||
if !status.Active() {
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ func Test_newClaude(t *testing.T) {
|
|||
}{
|
||||
"Direct with api key": {
|
||||
Opts: Options{
|
||||
Provider: ProviderClaude,
|
||||
Provider: ProviderAnthropic,
|
||||
Model: "claude-opus-4-6",
|
||||
APIKey: "k",
|
||||
},
|
||||
},
|
||||
"Bedrock needs no api key": {
|
||||
Opts: Options{
|
||||
Provider: ProviderClaude,
|
||||
Provider: ProviderAnthropic,
|
||||
Model: "anthropic.claude-opus-4-6",
|
||||
Bedrock: BedrockOptions{
|
||||
Enabled: true,
|
||||
|
|
@ -37,11 +37,11 @@ func Test_newClaude(t *testing.T) {
|
|||
},
|
||||
},
|
||||
"Optional tuning": {
|
||||
Opts: tunedOptions(ProviderClaude, "claude-opus-4-6"),
|
||||
Opts: tunedOptions(ProviderAnthropic, "claude-opus-4-6"),
|
||||
},
|
||||
"Vertex without a project id": {
|
||||
Opts: Options{
|
||||
Provider: ProviderClaude,
|
||||
Provider: ProviderAnthropic,
|
||||
Model: "claude-opus-4-6",
|
||||
Vertex: VertexOptions{Enabled: true, Region: "us-east5"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ func Test_newGemini(t *testing.T) {
|
|||
}{
|
||||
"Defaults": {
|
||||
Opts: Options{
|
||||
Provider: ProviderGemini,
|
||||
Provider: ProviderGoogle,
|
||||
Model: "gemini-2.5-pro",
|
||||
APIKey: "k",
|
||||
},
|
||||
|
|
@ -38,7 +38,7 @@ func Test_newGemini(t *testing.T) {
|
|||
Config: &gemini.Config{Model: "gemini-2.5-pro"},
|
||||
},
|
||||
"Optional tuning": {
|
||||
Opts: tunedOptions(ProviderGemini, "gemini-2.5-pro"),
|
||||
Opts: tunedOptions(ProviderGoogle, "gemini-2.5-pro"),
|
||||
Client: &genai.ClientConfig{
|
||||
APIKey: "k",
|
||||
Backend: genai.BackendGeminiAPI,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"claude": {
|
||||
"anthropic": {
|
||||
"default": "claude-opus-5",
|
||||
"models": {
|
||||
"active": [
|
||||
|
|
@ -10,9 +10,6 @@
|
|||
"active-but-weak": [
|
||||
"claude-sonnet-5",
|
||||
"claude-sonnet-4-6"
|
||||
],
|
||||
"inactive-too-weak": [
|
||||
"claude-haiku-4-5"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
@ -25,13 +22,10 @@
|
|||
],
|
||||
"active-but-weak": [
|
||||
"gpt-5-mini"
|
||||
],
|
||||
"inactive-too-weak": [
|
||||
"gpt-5-nano"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gemini": {
|
||||
"google": {
|
||||
"default": "gemini-2.5-pro",
|
||||
"models": {
|
||||
"active": [
|
||||
|
|
@ -40,9 +34,6 @@
|
|||
],
|
||||
"active-but-weak": [
|
||||
"gemini-2.5-flash"
|
||||
],
|
||||
"inactive-too-weak": [
|
||||
"gemini-2.5-flash-lite"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
@ -72,11 +63,6 @@
|
|||
"anthropic/claude-sonnet-4-6",
|
||||
"openai/gpt-5-mini",
|
||||
"google/gemini-2.5-flash"
|
||||
],
|
||||
"inactive-too-weak": [
|
||||
"anthropic/claude-haiku-4-5",
|
||||
"openai/gpt-5-nano",
|
||||
"google/gemini-2.5-flash-lite"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ type Options struct {
|
|||
Azure AzureOptions
|
||||
|
||||
// Bedrock holds AWS Bedrock settings, read only when Provider is
|
||||
// ProviderClaude.
|
||||
// ProviderAnthropic.
|
||||
Bedrock BedrockOptions
|
||||
|
||||
// Vertex holds Google Vertex settings, read only when Provider is
|
||||
// ProviderClaude.
|
||||
// ProviderAnthropic.
|
||||
Vertex VertexOptions
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ func (o Options) requiresAPIKey() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if o.Provider == ProviderClaude {
|
||||
if o.Provider == ProviderAnthropic {
|
||||
return !o.Bedrock.Enabled && !o.Vertex.Enabled
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func Test_Options_validate(t *testing.T) {
|
|||
Err: ErrMissingAPIKey,
|
||||
},
|
||||
"Gemini without api key": {
|
||||
Opts: Options{Provider: ProviderGemini, Model: "gemini-2.5-pro"},
|
||||
Opts: Options{Provider: ProviderGoogle, Model: "gemini-2.5-pro"},
|
||||
Err: ErrMissingAPIKey,
|
||||
},
|
||||
"OpenRouter without api key": {
|
||||
|
|
@ -40,22 +40,22 @@ func Test_Options_validate(t *testing.T) {
|
|||
Err: ErrMissingAPIKey,
|
||||
},
|
||||
"Claude without api key or cloud credentials": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-opus-4-6"},
|
||||
Opts: Options{Provider: ProviderAnthropic, Model: "claude-opus-4-6"},
|
||||
Err: ErrMissingAPIKey,
|
||||
},
|
||||
"Claude with api key": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-opus-4-6", APIKey: "k"},
|
||||
Opts: Options{Provider: ProviderAnthropic, Model: "claude-opus-4-6", APIKey: "k"},
|
||||
},
|
||||
"Claude via bedrock": {
|
||||
Opts: Options{
|
||||
Provider: ProviderClaude,
|
||||
Provider: ProviderAnthropic,
|
||||
Model: "claude-opus-4-6",
|
||||
Bedrock: BedrockOptions{Enabled: true},
|
||||
},
|
||||
},
|
||||
"Claude via vertex": {
|
||||
Opts: Options{
|
||||
Provider: ProviderClaude,
|
||||
Provider: ProviderAnthropic,
|
||||
Model: "claude-opus-4-6",
|
||||
Vertex: VertexOptions{Enabled: true},
|
||||
},
|
||||
|
|
@ -89,11 +89,11 @@ func Test_Options_requiresAPIKey(t *testing.T) {
|
|||
}{
|
||||
"Ollama never does": {Opts: Options{Provider: ProviderOllama}},
|
||||
"OpenAI does": {Opts: Options{Provider: ProviderOpenAI}, Result: true},
|
||||
"Gemini does": {Opts: Options{Provider: ProviderGemini}, Result: true},
|
||||
"Gemini does": {Opts: Options{Provider: ProviderGoogle}, Result: true},
|
||||
"OpenRouter does": {Opts: Options{Provider: ProviderOpenRouter}, Result: true},
|
||||
"Claude does when direct": {Opts: Options{Provider: ProviderClaude}, Result: true},
|
||||
"Claude does not with bedrock": {Opts: Options{Provider: ProviderClaude, Bedrock: BedrockOptions{Enabled: true}}},
|
||||
"Claude does not with vertex": {Opts: Options{Provider: ProviderClaude, Vertex: VertexOptions{Enabled: true}}},
|
||||
"Claude does when direct": {Opts: Options{Provider: ProviderAnthropic}, Result: true},
|
||||
"Claude does not with bedrock": {Opts: Options{Provider: ProviderAnthropic, Bedrock: BedrockOptions{Enabled: true}}},
|
||||
"Claude does not with vertex": {Opts: Options{Provider: ProviderAnthropic, Vertex: VertexOptions{Enabled: true}}},
|
||||
}
|
||||
|
||||
for cn, c := range cc {
|
||||
|
|
|
|||
|
|
@ -15,16 +15,16 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// ProviderClaude specifies Anthropic's Claude, reachable directly or
|
||||
// through AWS Bedrock and Google Vertex.
|
||||
ProviderClaude Provider = "claude"
|
||||
// ProviderAnthropic specifies Anthropic's Claude models, reachable
|
||||
// directly or through AWS Bedrock and Google Vertex.
|
||||
ProviderAnthropic Provider = "anthropic"
|
||||
|
||||
// ProviderOpenAI specifies OpenAI, Azure OpenAI, and any endpoint
|
||||
// speaking the OpenAI chat-completions protocol.
|
||||
ProviderOpenAI Provider = "openai"
|
||||
|
||||
// ProviderGemini specifies Google's Gemini models.
|
||||
ProviderGemini Provider = "gemini"
|
||||
// ProviderGoogle specifies Google's Gemini models.
|
||||
ProviderGoogle Provider = "google"
|
||||
|
||||
// ProviderOllama specifies a self-hosted Ollama server.
|
||||
ProviderOllama Provider = "ollama"
|
||||
|
|
@ -44,9 +44,9 @@ var ErrInvalidProvider = errors.New("invalid assistant provider")
|
|||
// _providers lists every supported provider in the order they are
|
||||
// reported to the user, so the error message reads the same every time.
|
||||
var _providers = []Provider{
|
||||
ProviderClaude,
|
||||
ProviderAnthropic,
|
||||
ProviderOpenAI,
|
||||
ProviderGemini,
|
||||
ProviderGoogle,
|
||||
ProviderOllama,
|
||||
ProviderOpenRouter,
|
||||
}
|
||||
|
|
@ -89,11 +89,11 @@ func New(ctx context.Context, opts Options) (model.ToolCallingChatModel, error)
|
|||
}
|
||||
|
||||
switch opts.Provider {
|
||||
case ProviderClaude:
|
||||
case ProviderAnthropic:
|
||||
return newClaude(ctx, opts)
|
||||
case ProviderOpenAI:
|
||||
return newOpenAI(ctx, opts)
|
||||
case ProviderGemini:
|
||||
case ProviderGoogle:
|
||||
return newGemini(ctx, opts)
|
||||
case ProviderOllama:
|
||||
return newOllama(ctx, opts)
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ func Test_Provider_Validate(t *testing.T) {
|
|||
Provider Provider
|
||||
Err error
|
||||
}{
|
||||
"Claude is supported": {Provider: ProviderClaude},
|
||||
"Anthropic is supported": {Provider: ProviderAnthropic},
|
||||
"OpenAI is supported": {Provider: ProviderOpenAI},
|
||||
"Gemini is supported": {Provider: ProviderGemini},
|
||||
"Google is supported": {Provider: ProviderGoogle},
|
||||
"Ollama is supported": {Provider: ProviderOllama},
|
||||
"OpenRouter is supported": {Provider: ProviderOpenRouter},
|
||||
"Unknown provider": {
|
||||
|
|
@ -68,9 +68,9 @@ func Test_ParseProvider(t *testing.T) {
|
|||
Inp string
|
||||
Result Provider
|
||||
}{
|
||||
"Exact match": {Inp: "claude", Result: ProviderClaude},
|
||||
"Exact match": {Inp: "anthropic", Result: ProviderAnthropic},
|
||||
"Mixed case": {Inp: "OpenAI", Result: ProviderOpenAI},
|
||||
"Surrounding spaces": {Inp: " gemini ", Result: ProviderGemini},
|
||||
"Surrounding spaces": {Inp: " google ", Result: ProviderGoogle},
|
||||
"Upper case and tabs": {Inp: "\tOLLAMA\n", Result: ProviderOllama},
|
||||
"Unknown passes through": {
|
||||
Inp: "cohere",
|
||||
|
|
@ -91,7 +91,7 @@ func Test_ParseProvider(t *testing.T) {
|
|||
func Test_supported(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert.Equal(t, "claude, openai, gemini, ollama, openrouter", supported())
|
||||
assert.Equal(t, "anthropic, openai, google, ollama, openrouter", supported())
|
||||
}
|
||||
|
||||
func Test_New(t *testing.T) {
|
||||
|
|
@ -108,7 +108,7 @@ func Test_New(t *testing.T) {
|
|||
ErrContains: "not supported",
|
||||
},
|
||||
"Missing model": {
|
||||
Opts: Options{Provider: ProviderClaude, APIKey: "k"},
|
||||
Opts: Options{Provider: ProviderAnthropic, APIKey: "k"},
|
||||
Err: ErrMissingModel,
|
||||
},
|
||||
"Missing api key": {
|
||||
|
|
@ -117,7 +117,7 @@ func Test_New(t *testing.T) {
|
|||
},
|
||||
"Claude": {
|
||||
Opts: Options{
|
||||
Provider: ProviderClaude,
|
||||
Provider: ProviderAnthropic,
|
||||
Model: "claude-opus-4-6",
|
||||
APIKey: "k",
|
||||
},
|
||||
|
|
@ -131,7 +131,7 @@ func Test_New(t *testing.T) {
|
|||
},
|
||||
"Gemini": {
|
||||
Opts: Options{
|
||||
Provider: ProviderGemini,
|
||||
Provider: ProviderGoogle,
|
||||
Model: "gemini-2.5-pro",
|
||||
APIKey: "k",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@ const (
|
|||
// assistant, but with limitations the operator should expect.
|
||||
StatusActiveButWeak Status = "active-but-weak"
|
||||
|
||||
// StatusInactiveTooWeak specifies that the configured model is too
|
||||
// weak to run the assistant, which is therefore disabled.
|
||||
// StatusInactiveTooWeak specifies that the configured model is not
|
||||
// known to be strong enough to run the assistant — it is either
|
||||
// listed as too weak or not listed at all — so the assistant is
|
||||
// disabled.
|
||||
StatusInactiveTooWeak Status = "inactive-too-weak"
|
||||
|
||||
// StatusInactive specifies that the assistant is disabled: either
|
||||
// no provider is configured or the configured model is not one this
|
||||
// build supports.
|
||||
// StatusInactive specifies that the assistant is disabled because
|
||||
// no provider is configured.
|
||||
StatusInactive Status = "inactive"
|
||||
)
|
||||
|
||||
|
|
@ -42,13 +43,14 @@ type modelList struct {
|
|||
Default string `json:"default"`
|
||||
|
||||
// Models groups the supported model ids by the status running the
|
||||
// assistant on them yields. A model in no group is not supported
|
||||
// and reports StatusInactive.
|
||||
// assistant on them yields. Only the two active tiers are listed:
|
||||
// a model in no group is StatusInactiveTooWeak.
|
||||
Models map[Status][]string `json:"models"`
|
||||
}
|
||||
|
||||
// status returns the status running the assistant on the given model
|
||||
// yields, or StatusInactive when the model is not on the list.
|
||||
// yields. A model outside the list is not known to be strong enough,
|
||||
// so it reports StatusInactiveTooWeak.
|
||||
func (ml modelList) status(model string) Status {
|
||||
for status, ids := range ml.Models {
|
||||
if slices.Contains(ids, model) {
|
||||
|
|
@ -56,7 +58,7 @@ func (ml modelList) status(model string) Status {
|
|||
}
|
||||
}
|
||||
|
||||
return StatusInactive
|
||||
return StatusInactiveTooWeak
|
||||
}
|
||||
|
||||
// _modelsJSON is the embedded per-provider model list: every supported
|
||||
|
|
@ -75,7 +77,7 @@ var _models, _modelsErr = parseModels(_modelsJSON)
|
|||
// ModelStatus validates the options and classifies the configured
|
||||
// model against the provider's supported list: whether the assistant
|
||||
// runs at full strength, runs with limitations, or does not run at
|
||||
// all. A model outside the list reports StatusInactive.
|
||||
// all. A model outside the list reports StatusInactiveTooWeak.
|
||||
func (o Options) ModelStatus() (Status, error) {
|
||||
if _modelsErr != nil {
|
||||
// NOCOV: the embedded file is pinned valid by the parse test.
|
||||
|
|
|
|||
|
|
@ -40,23 +40,19 @@ func Test_Options_ModelStatus(t *testing.T) {
|
|||
Err error
|
||||
}{
|
||||
"Invalid options": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-opus-5"},
|
||||
Opts: Options{Provider: ProviderAnthropic, Model: "claude-opus-5"},
|
||||
Err: ErrMissingAPIKey,
|
||||
},
|
||||
"Unsupported model": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-2", APIKey: "k"},
|
||||
Result: StatusInactive,
|
||||
},
|
||||
"Full strength model": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-opus-5", APIKey: "k"},
|
||||
Opts: Options{Provider: ProviderAnthropic, Model: "claude-opus-5", APIKey: "k"},
|
||||
Result: StatusActive,
|
||||
},
|
||||
"Weaker model": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-sonnet-5", APIKey: "k"},
|
||||
Opts: Options{Provider: ProviderAnthropic, Model: "claude-sonnet-5", APIKey: "k"},
|
||||
Result: StatusActiveButWeak,
|
||||
},
|
||||
"Too weak model": {
|
||||
Opts: Options{Provider: ProviderClaude, Model: "claude-haiku-4-5", APIKey: "k"},
|
||||
"Unlisted model": {
|
||||
Opts: Options{Provider: ProviderAnthropic, Model: "claude-haiku-4-5", APIKey: "k"},
|
||||
Result: StatusInactiveTooWeak,
|
||||
},
|
||||
"Supported ollama model": {
|
||||
|
|
@ -96,9 +92,9 @@ func Test_Provider_DefaultModel(t *testing.T) {
|
|||
Provider Provider
|
||||
Result string
|
||||
}{
|
||||
"Claude": {Provider: ProviderClaude, Result: "claude-opus-5"},
|
||||
"Claude": {Provider: ProviderAnthropic, Result: "claude-opus-5"},
|
||||
"OpenAI": {Provider: ProviderOpenAI, Result: "gpt-5.1"},
|
||||
"Gemini": {Provider: ProviderGemini, Result: "gemini-2.5-pro"},
|
||||
"Gemini": {Provider: ProviderGoogle, Result: "gemini-2.5-pro"},
|
||||
"Ollama": {Provider: ProviderOllama, Result: "llama3.3:70b"},
|
||||
"OpenRouter": {Provider: ProviderOpenRouter, Result: "anthropic/claude-opus-5"},
|
||||
"Unknown provider": {Provider: "cohere"},
|
||||
|
|
@ -117,7 +113,7 @@ func Test_Provider_DefaultModel(t *testing.T) {
|
|||
|
||||
// a default that is not on its provider's supported list
|
||||
// would disable the assistant instead of enabling it.
|
||||
assert.NotEqual(t, StatusInactive, _models[c.Provider].status(result))
|
||||
assert.True(t, _models[c.Provider].status(result).Active())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -145,14 +141,14 @@ func Test_parseModels(t *testing.T) {
|
|||
|
||||
for p, ml := range models {
|
||||
require.NoError(t, p.Validate())
|
||||
assert.NotEqual(t, StatusInactive, ml.status(ml.Default), p)
|
||||
assert.True(t, ml.status(ml.Default).Active(), p)
|
||||
|
||||
seen := make(map[string]bool)
|
||||
|
||||
for status, ids := range ml.Models {
|
||||
assert.Contains(
|
||||
t,
|
||||
[]Status{StatusActive, StatusActiveButWeak, StatusInactiveTooWeak},
|
||||
[]Status{StatusActive, StatusActiveButWeak},
|
||||
status,
|
||||
string(p),
|
||||
)
|
||||
|
|
@ -171,9 +167,8 @@ func Test_modelList_status(t *testing.T) {
|
|||
|
||||
ml := modelList{
|
||||
Models: map[Status][]string{
|
||||
StatusActive: {"strong"},
|
||||
StatusActiveButWeak: {"medium"},
|
||||
StatusInactiveTooWeak: {"small"},
|
||||
StatusActive: {"strong"},
|
||||
StatusActiveButWeak: {"medium"},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -183,8 +178,7 @@ func Test_modelList_status(t *testing.T) {
|
|||
}{
|
||||
"Full strength model": {Model: "strong", Result: StatusActive},
|
||||
"Weaker model": {Model: "medium", Result: StatusActiveButWeak},
|
||||
"Too weak model": {Model: "small", Result: StatusInactiveTooWeak},
|
||||
"Unlisted model": {Model: "unknown", Result: StatusInactive},
|
||||
"Unlisted model": {Model: "unknown", Result: StatusInactiveTooWeak},
|
||||
}
|
||||
|
||||
for cn, c := range cc {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user