Add projects

This commit is contained in:
Alois 2026-08-24 00:10:41 +02:00
commit 8b607dd700
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
1802 changed files with 503346 additions and 2 deletions

View file

@ -0,0 +1,100 @@
// Package models builds model catalogs for Anthropic clients.
package models
import (
"sort"
"strings"
)
const claudeDDModelPrefix = "claude-fable-5-dd-"
// BuildResponse builds an Anthropic model response from available models.
func BuildResponse(availableModels []map[string]any, disableCloaking bool) map[string]any {
models := make([]map[string]any, len(availableModels))
for i, model := range availableModels {
models[i] = cloneModel(model)
if id, ok := models[i]["id"].(string); ok && !disableCloaking {
models[i]["id"] = EnsureClaudeModelIDPrefix(id)
}
}
sort.SliceStable(models, func(i, j int) bool {
displayNameI, _ := models[i]["display_name"].(string)
displayNameJ, _ := models[j]["display_name"].(string)
if displayNameI != displayNameJ {
return displayNameI < displayNameJ
}
idI, _ := models[i]["id"].(string)
idJ, _ := models[j]["id"].(string)
return idI < idJ
})
firstID := ""
lastID := ""
if len(models) > 0 {
firstID, _ = models[0]["id"].(string)
lastID, _ = models[len(models)-1]["id"].(string)
}
return map[string]any{
"data": models,
"has_more": false,
"first_id": firstID,
"last_id": lastID,
}
}
// EnsureClaudeModelIDPrefix rewrites model IDs for Anthropic model listings.
// IDs that already start with "claude-" are returned unchanged; all other IDs
// become "claude-fable-5-dd-" plus the original ID with its characters reversed.
func EnsureClaudeModelIDPrefix(id string) string {
if id == "" || strings.HasPrefix(id, "claude-") {
return id
}
return claudeDDModelPrefix + reverseModelID(id)
}
// ResolveClaudeModelIDPrefix reverses EnsureClaudeModelIDPrefix for request routing.
// Optional thinking suffixes in model(value) form are preserved.
func ResolveClaudeModelIDPrefix(id string) string {
if id == "" {
return id
}
base, suffix, hasSuffix := splitModelThinkingSuffix(id)
if !strings.HasPrefix(base, claudeDDModelPrefix) {
return id
}
encoded := base[len(claudeDDModelPrefix):]
if encoded == "" {
return id
}
resolved := reverseModelID(encoded)
if hasSuffix {
return resolved + "(" + suffix + ")"
}
return resolved
}
func cloneModel(model map[string]any) map[string]any {
cloned := make(map[string]any, len(model))
for key, value := range model {
cloned[key] = value
}
return cloned
}
func splitModelThinkingSuffix(model string) (base, suffix string, hasSuffix bool) {
lastOpen := strings.LastIndex(model, "(")
if lastOpen == -1 || !strings.HasSuffix(model, ")") {
return model, "", false
}
return model[:lastOpen], model[lastOpen+1 : len(model)-1], true
}
func reverseModelID(id string) string {
runes := []rune(id)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}

View file

@ -0,0 +1,138 @@
package models
import "testing"
func TestBuildResponse(t *testing.T) {
availableModels := []map[string]any{
{"id": "claude-z", "display_name": "Zebra", "max_tokens": 64000},
{"id": "gpt-4o", "display_name": "Alpha"},
{"id": "claude-c", "display_name": "Alpha"},
{"id": "claude-b", "display_name": "Beta"},
}
response := BuildResponse(availableModels, false)
models, ok := response["data"].([]map[string]any)
if !ok {
t.Fatalf("data type = %T, want []map[string]any", response["data"])
}
wantIDs := []string{
"claude-c",
"claude-fable-5-dd-o4-tpg",
"claude-b",
"claude-z",
}
if len(models) != len(wantIDs) {
t.Fatalf("len(data) = %d, want %d", len(models), len(wantIDs))
}
for i, want := range wantIDs {
if got, _ := models[i]["id"].(string); got != want {
t.Fatalf("data[%d].id = %q, want %q", i, got, want)
}
}
if got := models[3]["max_tokens"]; got != 64000 {
t.Fatalf("max_tokens = %v, want 64000", got)
}
if got := response["has_more"]; got != false {
t.Fatalf("has_more = %v, want false", got)
}
if got := response["first_id"]; got != wantIDs[0] {
t.Fatalf("first_id = %v, want %q", got, wantIDs[0])
}
if got := response["last_id"]; got != wantIDs[len(wantIDs)-1] {
t.Fatalf("last_id = %v, want %q", got, wantIDs[len(wantIDs)-1])
}
if got := availableModels[1]["id"]; got != "gpt-4o" {
t.Fatalf("BuildResponse mutated input id to %v", got)
}
if got := availableModels[0]["id"]; got != "claude-z" {
t.Fatalf("BuildResponse reordered input: first id = %v", got)
}
}
func TestBuildResponseWithCloakingDisabled(t *testing.T) {
availableModels := []map[string]any{
{"id": "gpt-4o", "display_name": "GPT-4o"},
}
response := BuildResponse(availableModels, true)
models, ok := response["data"].([]map[string]any)
if !ok {
t.Fatalf("data type = %T, want []map[string]any", response["data"])
}
if len(models) != 1 {
t.Fatalf("len(data) = %d, want 1", len(models))
}
if got := models[0]["id"]; got != "gpt-4o" {
t.Fatalf("data[0].id = %v, want gpt-4o", got)
}
if got := response["first_id"]; got != "gpt-4o" {
t.Fatalf("first_id = %v, want gpt-4o", got)
}
if got := response["last_id"]; got != "gpt-4o" {
t.Fatalf("last_id = %v, want gpt-4o", got)
}
}
func TestBuildResponseEmpty(t *testing.T) {
response := BuildResponse(nil, false)
models, ok := response["data"].([]map[string]any)
if !ok {
t.Fatalf("data type = %T, want []map[string]any", response["data"])
}
if len(models) != 0 {
t.Fatalf("len(data) = %d, want 0", len(models))
}
if response["first_id"] != "" || response["last_id"] != "" {
t.Fatalf("empty response IDs = (%v, %v), want empty", response["first_id"], response["last_id"])
}
}
func TestEnsureClaudeModelIDPrefix(t *testing.T) {
tests := []struct {
name string
id string
want string
}{
{"empty", "", ""},
{"already has claude prefix", "claude-sonnet-4-6", "claude-sonnet-4-6"},
{"contains claude mid-string is reversed", "my-claude-custom", "claude-fable-5-dd-motsuc-edualc-ym"},
{"uppercase Claude prefix is reversed", "Claude-Opus-4", "claude-fable-5-dd-4-supO-edualC"},
{"gpt model is reversed", "gpt-4o", "claude-fable-5-dd-o4-tpg"},
{"gemini model is reversed", "gemini-2.5-pro", "claude-fable-5-dd-orp-5.2-inimeg"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := EnsureClaudeModelIDPrefix(tt.id); got != tt.want {
t.Fatalf("EnsureClaudeModelIDPrefix(%q) = %q, want %q", tt.id, got, tt.want)
}
})
}
}
func TestResolveClaudeModelIDPrefix(t *testing.T) {
tests := []struct {
name string
id string
want string
}{
{"empty", "", ""},
{"plain claude id unchanged", "claude-sonnet-4-6", "claude-sonnet-4-6"},
{"non encoded id unchanged", "gpt-4o", "gpt-4o"},
{"encoded gpt model", "claude-fable-5-dd-o4-tpg", "gpt-4o"},
{"encoded gemini model", "claude-fable-5-dd-orp-5.2-inimeg", "gemini-2.5-pro"},
{"empty encoded body unchanged", "claude-fable-5-dd-", "claude-fable-5-dd-"},
{"preserves thinking suffix", "claude-fable-5-dd-o4-tpg(high)", "gpt-4o(high)"},
{"round trip", EnsureClaudeModelIDPrefix("custom-model-x"), "custom-model-x"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ResolveClaudeModelIDPrefix(tt.id); got != tt.want {
t.Fatalf("ResolveClaudeModelIDPrefix(%q) = %q, want %q", tt.id, got, tt.want)
}
})
}
}