first commit

This commit is contained in:
2026-08-14 23:41:57 +08:00
commit 086803a8dd
471 changed files with 91938 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
// This file implements model-name → provider inference (US: auto-infer provider
// from --model alone). When a user supplies only --model, with no --provider,
// --protocol, or --base-url, pigo tries to guess the owning provider from the
// model id's well-known name prefix (e.g. "claude-*" → anthropic, "deepseek-*"
// → deepseek). This lets `pigo -m claude-opus-4-8` reach the Anthropic API
// without the user spelling out the provider or its wire protocol.
//
// The mapping is deliberately conservative: only names that unambiguously
// identify a single built-in provider are inferred. Ambiguous families served
// by many gateways (notably "llama-*", "qwq-*", "gemma-*", "mixtral-*") are NOT
// inferred — they return ok=false so the caller falls through to its existing
// default (OpenRouter), which is the safe, unchanged behavior.
//
// Every provider name returned here is guaranteed to exist in providerRegistry
// (enforced by a test), so callers can hand the result straight to the
// registry-driven resolution path.
package provider
import "strings"
// modelPrefixProvider maps a lowercase model-name prefix to the built-in
// provider name that serves that family. Order matters: the table is scanned
// top-to-bottom and the FIRST matching prefix wins, so list more specific
// prefixes before shorter ones that would also match.
//
// Each provider name here must be present in providerRegistry (registry.go).
var modelPrefixProvider = []struct {
prefix string
provider string
}{
{"claude-", "anthropic"},
{"gpt-", "openai"},
{"o1-", "openai"},
{"o3-", "openai"},
{"o4-", "openai"},
{"gemini-", "google"},
{"deepseek-", "deepseek"},
{"glm-", "zai"},
{"kimi-", "moonshotai"},
{"moonshot-", "moonshotai"},
{"qwen-", "dashscope"},
{"ernie-", "qianfan"},
{"doubao-", "volcengine"},
{"grok-", "xai"},
{"mistral-", "mistral"},
{"codestral-", "mistral"},
{"devstral-", "mistral"},
{"hunyuan-", "hunyuan"},
{"minimax-", "minimax"},
{"mimo-", "xiaomi"},
}
// InferProviderFromModel guesses the built-in provider name that serves a given
// model id, based on the id's well-known name prefix. It returns the provider
// name and ok=true on a confident match, or ("", false) when the id is unknown
// or ambiguous (served by multiple gateways). Matching is case-insensitive.
//
// The returned name is always a valid entry in providerRegistry. Callers should
// use it only when no explicit --provider/--protocol/--base-url was given; those
// flags take precedence over any inference.
func InferProviderFromModel(model string) (string, bool) {
id := strings.ToLower(strings.TrimSpace(model))
if id == "" {
return "", false
}
// A "provider/model" style id (e.g. "openai/gpt-4o") is an OpenRouter-style
// routed id, not a bare model name — leave those to the caller's preset/
// prefix handling rather than inferring from the leading segment.
if strings.Contains(id, "/") {
return "", false
}
for _, m := range modelPrefixProvider {
if strings.HasPrefix(id, m.prefix) {
return m.provider, true
}
}
return "", false
}