feat(devin): prefix all Devin model IDs with devin/ namespace

This commit is contained in:
sususu
2026-09-11 17:52:29 +08:00
committed by sususu98
parent cbe800aa28
commit eed249072d
6 changed files with 63 additions and 23 deletions

View File

@@ -88,7 +88,7 @@ func GetAntigravityModels() []*ModelInfo {
var staticDevinModels = []*ModelInfo{
{
ID: "swe-2",
ID: "devin/swe-2",
Type: "devin",
OwnedBy: "cognition",
DisplayName: "SWE-2",
@@ -99,7 +99,7 @@ var staticDevinModels = []*ModelInfo{
},
},
{
ID: "claude-fable-5-1",
ID: "devin/claude-fable-5-1",
Type: "devin",
OwnedBy: "anthropic",
DisplayName: "Claude Fable 5.1",
@@ -110,7 +110,7 @@ var staticDevinModels = []*ModelInfo{
},
},
{
ID: "gpt-6-astra",
ID: "devin/gpt-6-astra",
Type: "devin",
OwnedBy: "openai",
DisplayName: "GPT-6 Astra",
@@ -121,7 +121,7 @@ var staticDevinModels = []*ModelInfo{
},
},
{
ID: "swe-1-7-lightning",
ID: "devin/swe-1-7-lightning",
Type: "devin",
OwnedBy: "cognition",
DisplayName: "SWE-1.7 Lightning",
@@ -132,7 +132,7 @@ var staticDevinModels = []*ModelInfo{
},
},
{
ID: "glm-5-2",
ID: "devin/glm-5-2",
Type: "devin",
OwnedBy: "zhipu",
DisplayName: "GLM-5.2",
@@ -143,7 +143,7 @@ var staticDevinModels = []*ModelInfo{
},
},
{
ID: "glm-5-3",
ID: "devin/glm-5-3",
Type: "devin",
OwnedBy: "zhipu",
DisplayName: "GLM-5.3",

View File

@@ -164,21 +164,21 @@ func TestGetDevinModelsFallback(t *testing.T) {
foundSWE2 := false
foundFable := false
for _, m := range devinModels {
if m != nil && m.ID == "swe-2" {
if m != nil && m.ID == "devin/swe-2" {
foundSWE2 = true
if m.Type != "devin" {
t.Errorf("swe-2 Type = %q, want devin", m.Type)
t.Errorf("devin/swe-2 Type = %q, want devin", m.Type)
}
}
if m != nil && m.ID == "claude-fable-5-1" {
if m != nil && m.ID == "devin/claude-fable-5-1" {
foundFable = true
}
}
if !foundSWE2 {
t.Error("expected swe-2 in GetDevinModels()")
t.Error("expected devin/swe-2 in GetDevinModels()")
}
if !foundFable {
t.Error("expected claude-fable-5-1 in GetDevinModels()")
t.Error("expected devin/claude-fable-5-1 in GetDevinModels()")
}
byChannel := GetStaticModelDefinitionsByChannel("devin")
@@ -186,9 +186,9 @@ func TestGetDevinModelsFallback(t *testing.T) {
t.Fatal("GetStaticModelDefinitionsByChannel(\"devin\") returned empty list")
}
info := LookupStaticModelInfo("swe-2")
info := LookupStaticModelInfo("devin/swe-2")
if info == nil {
t.Fatal("LookupStaticModelInfo(\"swe-2\") = nil, want valid model")
t.Fatal("LookupStaticModelInfo(\"devin/swe-2\") = nil, want valid model")
}
if info.DisplayName != "SWE-2" {
t.Errorf("info.DisplayName = %q, want SWE-2", info.DisplayName)

View File

@@ -79,13 +79,19 @@ func ResolveDevinChatModelUID(rawModel string, thinkingLevel string, budgetToken
return "swe-2-high"
}
// 1. If already ends with an exact Devin effort suffix, use directly
if HasDevinEffortSuffix(model) {
return model
// 1. Strip devin/ prefix if present (case-insensitive)
cleanModel := model
if strings.HasPrefix(strings.ToLower(cleanModel), "devin/") {
cleanModel = cleanModel[6:]
}
// 2. Strip CPA colon or parenthesis suffix (suffix overrides body per CPA convention)
parsedSuffix := thinking.ParseSuffix(model)
// 2. If already ends with an exact Devin effort suffix, use directly
if HasDevinEffortSuffix(cleanModel) {
return cleanModel
}
// 3. Strip CPA colon or parenthesis suffix (suffix overrides body per CPA convention)
parsedSuffix := thinking.ParseSuffix(cleanModel)
baseModel := strings.TrimSpace(parsedSuffix.ModelName)
if parsedSuffix.HasSuffix {
thinkingLevel = parsedSuffix.RawSuffix

View File

@@ -88,6 +88,36 @@ func TestResolveDevinChatModelUID(t *testing.T) {
thinkingLevel: "medium",
want: "glm-5-3-high",
},
{
name: "devin prefix lowercase swe-2",
rawModel: "devin/swe-2",
thinkingLevel: "",
want: "swe-2-high",
},
{
name: "Devin prefix capitalized swe-2 with suffix",
rawModel: "Devin/swe-2(max)",
thinkingLevel: "",
want: "swe-2-max",
},
{
name: "devin prefix claude-fable-5-1",
rawModel: "devin/claude-fable-5-1",
thinkingLevel: "",
want: "claude-fable-5-1-medium",
},
{
name: "Devin prefix gpt-6-astra with suffix",
rawModel: "Devin/gpt-6-astra(high)",
thinkingLevel: "",
want: "gpt-6-astra-high",
},
{
name: "devin prefix direct effort UID",
rawModel: "devin/swe-2-high",
thinkingLevel: "",
want: "swe-2-high",
},
}
for _, tt := range tests {

View File

@@ -139,11 +139,10 @@ func WrapConnectEnvelope(protoBytes []byte) []byte {
// WrapConnectEnvelopeWithFlag wraps payload bytes with an explicit Connect flag.
func WrapConnectEnvelopeWithFlag(flag byte, protoBytes []byte) []byte {
out := make([]byte, 5+len(protoBytes))
out[0] = flag
binary.BigEndian.PutUint32(out[1:5], uint32(len(protoBytes)))
copy(out[5:], protoBytes)
return out
header := make([]byte, 5, 5+len(protoBytes))
header[0] = flag
binary.BigEndian.PutUint32(header[1:5], uint32(len(protoBytes)))
return append(header, protoBytes...)
}
// ReadConnectFrame reads a single framed message from a Connect-proto stream.

View File

@@ -65,6 +65,11 @@ func GetProviderName(modelName string) []string {
for _, provider := range registry.GetGlobalRegistry().GetModelProviders(modelName) {
appendProvider(provider)
}
if len(providers) == 0 && strings.ToLower(modelName) != modelName {
for _, provider := range registry.GetGlobalRegistry().GetModelProviders(strings.ToLower(modelName)) {
appendProvider(provider)
}
}
if len(providers) > 0 {
return providers