Add projects
This commit is contained in:
parent
2d3a9ad623
commit
8b607dd700
1802 changed files with 503346 additions and 2 deletions
68
backend/internal/util/claude_tool_id.go
Normal file
68
backend/internal/util/claude_tool_id.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const geminiClaudeToolUseIDPrefix = "cpa_gemini_"
|
||||
|
||||
var (
|
||||
claudeToolUseIDSanitizer = regexp.MustCompile(`[^a-zA-Z0-9_-]`)
|
||||
claudeToolUseIDCounter uint64
|
||||
)
|
||||
|
||||
// SanitizeClaudeToolID ensures the given id conforms to Claude's
|
||||
// tool_use.id regex ^[a-zA-Z0-9_-]+$. Non-conforming characters are
|
||||
// replaced with '_'; an empty result gets a generated fallback.
|
||||
func SanitizeClaudeToolID(id string) string {
|
||||
s := claudeToolUseIDSanitizer.ReplaceAllString(id, "_")
|
||||
if s == "" {
|
||||
s = fmt.Sprintf("toolu_%d_%d", time.Now().UnixNano(), atomic.AddUint64(&claudeToolUseIDCounter, 1))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GeminiClaudeToolUseID returns a stable Claude-facing ID for a provider-native
|
||||
// Gemini function call. The opaque ID lets the executor recover the exact
|
||||
// provider call from its replay ledger instead of trusting client-mutated args.
|
||||
func GeminiClaudeToolUseID(callID, name, argsRaw string) string {
|
||||
callID = strings.TrimSpace(callID)
|
||||
name = strings.TrimSpace(name)
|
||||
if callID == "" || name == "" {
|
||||
return ""
|
||||
}
|
||||
if strings.TrimSpace(argsRaw) != "" {
|
||||
var value any
|
||||
if json.Unmarshal([]byte(argsRaw), &value) == nil {
|
||||
if canonical, errMarshal := json.Marshal(value); errMarshal == nil {
|
||||
argsRaw = string(canonical)
|
||||
}
|
||||
} else {
|
||||
argsRaw = strings.TrimSpace(argsRaw)
|
||||
}
|
||||
}
|
||||
sum := sha256.Sum256([]byte(strings.Join([]string{callID, name, argsRaw}, "\x00")))
|
||||
return geminiClaudeToolUseIDPrefix + hex.EncodeToString(sum[:16])
|
||||
}
|
||||
|
||||
// IsGeminiClaudeToolUseID reports whether id belongs to the reserved
|
||||
// Claude-facing Gemini provenance namespace.
|
||||
func IsGeminiClaudeToolUseID(id string) bool {
|
||||
id = strings.TrimSpace(id)
|
||||
if !strings.HasPrefix(id, geminiClaudeToolUseIDPrefix) {
|
||||
return false
|
||||
}
|
||||
digest := strings.TrimPrefix(id, geminiClaudeToolUseIDPrefix)
|
||||
if len(digest) != 32 {
|
||||
return false
|
||||
}
|
||||
_, errDecode := hex.DecodeString(digest)
|
||||
return errDecode == nil
|
||||
}
|
||||
Loading…
Reference in a new issue