Compare commits

..

3 commits

Author SHA1 Message Date
rene
643efdabb6 feat: add multi-key support with automatic rate-limit rotation
Support multiple API keys via `api_keys` array in config or `OCGO_API_KEYS`
env var. On HTTP 429, automatically rotate to the next key and retry.
Key index persisted to `~/.config/ocgo/key-index` for restart safety.
Backward compatible with existing single-key `api_key` configs.

Fixes #115

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 17:39:33 +08:00
1b685002b8 Merge pull request 'feat: add --model flag, isKnownModelID routing, [1M] context tag' (#10) from renekv/ocgo:main into main
Reviewed-on: #10
2026-05-26 03:50:20 +00:00
db1dd25a9b feat: add --model flag, isKnownModelID routing, [1M] context tag 2026-05-26 11:48:44 +08:00

View file

@ -197,6 +197,16 @@ func knownModelIDs() []string {
return []string{"glm-5.1", "glm-5", "kimi-k2.6", "kimi-k2.5", "mimo-v2.5-pro", "mimo-v2.5", "mimo-v2-pro", "mimo-v2-omni", "minimax-m2.7", "minimax-m2.5", "deepseek-v4-pro[1M]", "deepseek-v4-flash[1M]", "qwen3.6-plus", "qwen3.5-plus"}
}
func isKnownModelID(model string) bool {
cleaned := cleanModelName(model)
for _, m := range knownModelIDs() {
if cleanModelName(m) == cleaned {
return true
}
}
return false
}
func cleanModelName(model string) string {
model = strings.TrimSuffix(model, "[1M]")
model = strings.TrimSuffix(model, "[128K]")
@ -450,7 +460,7 @@ func proxyChatCompletions(w http.ResponseWriter, r *http.Request, cfg Config) {
dm := cleanModelName(cfg.Model)
var reqMap map[string]any
if json.Unmarshal(body, &reqMap) == nil {
if m, _ := reqMap["model"].(string); m == "" || strings.HasPrefix(m, "claude-") {
if m, _ := reqMap["model"].(string); m == "" || !isKnownModelID(m) {
reqMap["model"] = dm
body, _ = json.Marshal(reqMap)
}
@ -615,7 +625,7 @@ func stripRawChatImageDetails(req map[string]any) bool {
func convertRequest(ar AnthropicRequest, defaultModel string) OAIRequest {
model := cleanModelName(ar.Model)
if model == "" || strings.HasPrefix(model, "claude-") || defaultModel != "" {
if model == "" || !isKnownModelID(model) {
model = cleanModelName(defaultModel)
}
if model == "" {
@ -636,7 +646,7 @@ func convertRequest(ar AnthropicRequest, defaultModel string) OAIRequest {
func responsesToChat(rr ResponsesRequest, defaultModel string) OAIRequest {
model := cleanModelName(rr.Model)
if model == "" || defaultModel != "" {
if model == "" || !isKnownModelID(model) {
model = cleanModelName(defaultModel)
}
if model == "" {