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,228 @@
// Claude thinking signature validation wrappers for Antigravity bypass mode.
package claude
import (
"encoding/base64"
"strings"
"github.com/router-for-me/CLIProxyAPI/v7/internal/cache"
"github.com/router-for-me/CLIProxyAPI/v7/internal/signature"
translatorcommon "github.com/router-for-me/CLIProxyAPI/v7/internal/translator/common"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
const (
maxBypassSignatureLen = signature.MaxClaudeThinkingSignatureLen
// Gemini carrier envelopes exist only on the Claude-facing wire. The request
// translator validates and unwraps them before writing native Gemini parts.
geminiClaudeCarrierPrefix = "cpa-gemini-carrier-v1:"
geminiClaudeCarrierNext = "next"
geminiClaudeCarrierPrevious = "previous"
geminiClaudeCarrierStandalone = "standalone"
geminiClaudeCarrierText = "text"
geminiClaudeCarrierFunction = "function"
geminiClaudeCarrierAny = "any"
)
type claudeSignatureTree = signature.ClaudeSignatureTree
func encodeGeminiClaudeCarrierSignature(rawSignature, direction, targetKind string) string {
rawSignature = strings.TrimSpace(rawSignature)
if rawSignature == "" {
return ""
}
return geminiClaudeCarrierPrefix + direction + ":" + targetKind + ":" + base64.RawStdEncoding.EncodeToString([]byte(rawSignature))
}
func decodeGeminiClaudeCarrierSignature(rawSignature string) (signatureValue, direction, targetKind string, marked, ok bool) {
rawSignature = strings.TrimSpace(rawSignature)
if !strings.HasPrefix(rawSignature, geminiClaudeCarrierPrefix) {
return rawSignature, "", "", false, true
}
marked = true
if len(rawSignature) > (signature.MaxGeminiThoughtSignatureLen*4/3)+1024 {
return "", "", "", true, false
}
fields := strings.SplitN(strings.TrimPrefix(rawSignature, geminiClaudeCarrierPrefix), ":", 3)
if len(fields) != 3 {
return "", "", "", true, false
}
direction, targetKind = fields[0], fields[1]
switch direction {
case geminiClaudeCarrierNext, geminiClaudeCarrierPrevious, geminiClaudeCarrierStandalone:
default:
return "", "", "", true, false
}
switch targetKind {
case geminiClaudeCarrierText, geminiClaudeCarrierFunction, geminiClaudeCarrierAny:
default:
return "", "", "", true, false
}
decoded, errDecode := base64.RawStdEncoding.DecodeString(fields[2])
if errDecode != nil || len(decoded) == 0 || strings.HasPrefix(string(decoded), geminiClaudeCarrierPrefix) {
return "", "", "", true, false
}
blockKind := signature.SignatureBlockKindGeminiModelPart
if targetKind == geminiClaudeCarrierFunction {
blockKind = signature.SignatureBlockKindGeminiFunctionCall
}
normalized, compatible := signature.CompatibleSignatureForProviderBlock(signature.SignatureProviderGemini, string(decoded), blockKind)
if !compatible || signature.IsGeminiThoughtSignatureBypass(signature.SignaturePayloadWithoutProviderPrefix(normalized)) {
return "", "", "", true, false
}
return normalized, direction, targetKind, true, true
}
func geminiClaudeSemanticTargetKind(block gjson.Result) string {
switch block.Get("type").String() {
case "text":
return geminiClaudeCarrierText
case "tool_use":
return geminiClaudeCarrierFunction
case "thinking":
if strings.TrimSpace(block.Get("thinking").String()) != "" {
return geminiClaudeCarrierText
}
}
return ""
}
func geminiClaudeCarrierMatchesAdjacent(blocks []gjson.Result, index int, direction, targetKind string) bool {
step := 1
if direction == geminiClaudeCarrierPrevious {
step = -1
}
for adjacent := index + step; adjacent >= 0 && adjacent < len(blocks); adjacent += step {
if kind := geminiClaudeSemanticTargetKind(blocks[adjacent]); kind != "" {
return targetKind == geminiClaudeCarrierAny || targetKind == kind
}
if blocks[adjacent].Get("type").String() != "thinking" || strings.TrimSpace(blocks[adjacent].Get("thinking").String()) != "" {
return false
}
}
return false
}
// StripEmptySignatureThinkingBlocks removes thinking blocks whose signatures
// are empty or not valid Claude thinking signatures. These usually come from
// proxy-generated responses where no real Claude signature exists.
func StripEmptySignatureThinkingBlocks(payload []byte) []byte {
return signature.StripInvalidClaudeThinkingBlocks(payload, signature.ClaudeSignatureValidationOptions{PrefixOnly: true})
}
// StripInvalidGeminiSignatureThinkingBlocks preserves only thinking carriers
// whose signatures can be replayed to Gemini. Claude Code uses these carriers
// to return provider-native signatures from prior translated responses.
func StripInvalidGeminiSignatureThinkingBlocks(payload []byte) []byte {
messages := gjson.GetBytes(payload, "messages")
if !messages.IsArray() {
return payload
}
changed := false
messageItems := make([][]byte, 0, len(messages.Array()))
for _, message := range messages.Array() {
messageJSON := []byte(message.Raw)
content := message.Get("content")
if !content.IsArray() {
messageItems = append(messageItems, messageJSON)
continue
}
contentChanged := false
assistantMessage := strings.EqualFold(message.Get("role").String(), "assistant")
contentBlocks := content.Array()
contentItems := make([][]byte, 0, len(contentBlocks))
pendingCarrierTargetKind := ""
for blockIndex, block := range contentBlocks {
if block.Get("type").String() == "thinking" {
rawSignature := strings.TrimSpace(block.Get("signature").String())
thinkingText := strings.TrimSpace(block.Get("thinking").String())
if rawSignature == "" && thinkingText != "" && (pendingCarrierTargetKind == geminiClaudeCarrierAny || pendingCarrierTargetKind == geminiClaudeCarrierText) {
pendingCarrierTargetKind = ""
contentItems = append(contentItems, []byte(block.Raw))
continue
}
innerSignature, direction, targetKind, marked, okCarrier := decodeGeminiClaudeCarrierSignature(rawSignature)
blockKind := signature.SignatureBlockKindGeminiModelPart
if marked && targetKind == geminiClaudeCarrierFunction {
blockKind = signature.SignatureBlockKindGeminiFunctionCall
}
invalidMarkedPlacement := false
if marked {
switch direction {
case geminiClaudeCarrierNext, geminiClaudeCarrierPrevious:
invalidMarkedPlacement = !geminiClaudeCarrierMatchesAdjacent(contentBlocks, blockIndex, direction, targetKind)
case geminiClaudeCarrierStandalone:
invalidMarkedPlacement = thinkingText != "" && targetKind == geminiClaudeCarrierFunction
}
if thinkingText != "" && direction == geminiClaudeCarrierPrevious {
invalidMarkedPlacement = true
}
}
if !okCarrier || !assistantMessage || invalidMarkedPlacement {
pendingCarrierTargetKind = ""
contentChanged = true
continue
}
if !marked {
innerSignature = rawSignature
}
if _, ok := signature.CompatibleSignatureForProviderBlock(signature.SignatureProviderGemini, innerSignature, blockKind); !ok {
pendingCarrierTargetKind = ""
contentChanged = true
continue
}
if marked && direction == geminiClaudeCarrierNext {
pendingCarrierTargetKind = targetKind
} else {
pendingCarrierTargetKind = ""
}
} else {
pendingCarrierTargetKind = ""
}
contentItems = append(contentItems, []byte(block.Raw))
}
if contentChanged {
messageJSON, _ = sjson.SetRawBytes(messageJSON, "content", translatorcommon.JoinRawArray(contentItems))
changed = true
}
messageItems = append(messageItems, messageJSON)
}
if !changed {
return payload
}
updated, errSet := sjson.SetRawBytes(payload, "messages", translatorcommon.JoinRawArray(messageItems))
if errSet != nil {
return payload
}
return updated
}
func StripInvalidBypassSignatureThinkingBlocks(payload []byte) []byte {
return signature.StripInvalidClaudeThinkingBlocks(payload, claudeBypassSignatureValidationOptions())
}
func ValidateClaudeBypassSignatures(inputRawJSON []byte) error {
return signature.ValidateClaudeThinkingSignatures(inputRawJSON, claudeBypassSignatureValidationOptions())
}
func normalizeClaudeBypassSignature(rawSignature string) (string, error) {
return signature.NormalizeClaudeThinkingSignature(rawSignature, claudeBypassSignatureValidationOptions())
}
func inspectDoubleLayerSignature(sig string) (*claudeSignatureTree, error) {
return signature.InspectClaudeDoubleLayerSignature(sig)
}
func inspectSingleLayerSignature(sig string) (*claudeSignatureTree, error) {
return signature.InspectClaudeSingleLayerSignature(sig)
}
func inspectClaudeSignaturePayload(payload []byte, encodingLayers int) (*claudeSignatureTree, error) {
return signature.InspectClaudeSignaturePayload(payload, encodingLayers)
}
func claudeBypassSignatureValidationOptions() signature.ClaudeSignatureValidationOptions {
return signature.ClaudeSignatureValidationOptions{Strict: cache.SignatureBypassStrictMode()}
}