Files
CLIProxyAPI/internal/runtime/executor/helps/devin_models_test.go
sususu f94752762b feat(devin): add Devin/Cognition provider integration and CLI OAuth
Implement the full Devin/Cognition Connect-RPC provider support across all CPA endpoints (/v1/chat/completions, /v1/messages, /v1/responses), complete with binary protobuf wire framing, streaming tools/arguments delta handling, thinking/reasoning replay, and CLI OAuth authentication.

Key highlights:
- Wire Protocol & Streaming:
  * Implemented Connect-RPC uncompressed 5-byte framing (0x00 + 4-byte length + protobuf) for ApiServerService/GetChatMessage.
  * Implemented Devin protobuf encoder/decoder in internal/runtime/executor/helps/devin_wire.go, including ClientMetadata, prompts, tools, completion_config, and multimodal image handling (Prompt Field #10).
  * Stream frame consumption via interactions protocol, correctly mapping arguments_delta and tracking multiple sequential tool calls (currentToolCallActive).
  * Streaming thought summary and sealed.v1 signature deltas targeting the thinking step.

- Model Registration & Thinking Clamping:
  * Registered static fallback models in model_definitions.go (swe-2, claude-fable-5-1, gpt-6-astra, swe-1-7-lightning, glm-5-2, glm-5-3).
  * Configured ThinkingSupport with discrete levels per model family.
  * Implemented CPA-standard nearest-neighbor clamping for thinking levels (minimal/low -> medium, xhigh -> max for swe-2).
  * Mapped thinking effort to Devin upstream model UID (e.g. swe-2-medium, swe-2-high, swe-2-max).

- Sensitive Words & System Prompt Sanitization:
  * Added devin.sensitive-words configuration in internal/config/config_types.go and config.go, matching Antigravity conventions.
  * Supported zero-width space (\u200b) obfuscation in prompts, tools, and system instructions via SensitiveWordMatcher.
  * Stripped Claude Code billing headers (x-anthropic-billing-header:) and CLI identity signatures from system instructions and tool descriptions to avoid upstream content filter rejections.

- Signature Compatibility:
  * Added SignatureProviderSWE = "swe" recognizing sealed.v1.* reasoning signatures in internal/signature/provider_compatibility.go.
  * Propagated reasoning.encrypted_content on Responses API and thinking.signature on Messages API.

- Authentication:
  * Implemented Devin PKCE OAuth flow with loopback callback server and headless manual token/code paste (--no-browser).
  * Registered Devin authenticator in SDK and CLI (-devin-login flag).
  * Integrated with management OAuth session endpoints and credentials manager.
2026-09-13 23:34:43 +08:00

102 lines
2.4 KiB
Go

package helps
import (
"testing"
)
func TestResolveDevinChatModelUID(t *testing.T) {
tests := []struct {
name string
rawModel string
thinkingLevel string
budgetTokens int
want string
}{
{
name: "direct full UID unchanged",
rawModel: "claude-fable-5-1-max",
want: "claude-fable-5-1-max",
},
{
name: "direct swe-2-high unchanged",
rawModel: "swe-2-high",
want: "swe-2-high",
},
{
name: "swe-2 default to high when no effort",
rawModel: "swe-2",
thinkingLevel: "",
want: "swe-2-high",
},
{
name: "swe-2 clamp minimal to medium",
rawModel: "swe-2",
thinkingLevel: "minimal",
want: "swe-2-medium",
},
{
name: "swe-2 clamp low to medium",
rawModel: "swe-2",
thinkingLevel: "low",
want: "swe-2-medium",
},
{
name: "swe-2 with xhigh maps to max",
rawModel: "swe-2",
thinkingLevel: "xhigh",
want: "swe-2-max",
},
{
name: "swe-2 request max",
rawModel: "swe-2",
thinkingLevel: "max",
want: "swe-2-max",
},
{
name: "swe-2 suffix overrides body thinkingLevel",
rawModel: "swe-2(max)",
thinkingLevel: "medium",
want: "swe-2-max",
},
{
name: "fable-5-1 budget tokens maps to max",
rawModel: "claude-fable-5-1",
budgetTokens: 64000,
want: "claude-fable-5-1-max",
},
{
name: "fable-5-1 budget tokens maps to low",
rawModel: "claude-fable-5-1",
budgetTokens: 2048,
want: "claude-fable-5-1-low",
},
{
name: "fable-5-1 with xhigh",
rawModel: "claude-fable-5-1",
thinkingLevel: "xhigh",
want: "claude-fable-5-1-xhigh",
},
{
name: "astra with suffix in parenthesis",
rawModel: "gpt-6-astra(high)",
thinkingLevel: "",
want: "gpt-6-astra-high",
},
{
name: "glm-5-3 clamp medium to high",
rawModel: "glm-5-3",
thinkingLevel: "medium",
want: "glm-5-3-high",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ResolveDevinChatModelUID(tt.rawModel, tt.thinkingLevel, tt.budgetTokens)
if got != tt.want {
t.Errorf("ResolveDevinChatModelUID(%q, %q, %d) = %q, want %q", tt.rawModel, tt.thinkingLevel, tt.budgetTokens, got, tt.want)
}
})
}
}