Merge pull request #1531 from trheyi/main

feat(claude): implement user ID hashing and enhance environment setup
This commit is contained in:
Max 2026-05-06 18:37:56 +08:00 committed by GitHub
commit a01eb869ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 1 deletions

View file

@ -2,6 +2,8 @@ package claude
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"regexp"
@ -26,6 +28,11 @@ var yaoSessionNS = uuid.MustParse("f47ac10b-58cc-4372-a567-0e02b2c3d479")
var safeNameRe = regexp.MustCompile(`[^a-zA-Z0-9_\-.]`)
func hashUserID(raw string) string {
h := sha256.Sum256([]byte(raw))
return hex.EncodeToString(h[:8]) // 16 hex chars — short yet collision-safe
}
func chatIDToSessionUUID(assistantID, chatID string) string {
return uuid.NewSHA1(yaoSessionNS, []byte(assistantID+":"+chatID)).String()
}
@ -234,6 +241,21 @@ func buildEnv(req *types.StreamRequest, p platform) map[string]string {
env["ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES"])
logger.Debug("claude-env: MAX_THINKING_TOKENS=%s", env["MAX_THINKING_TOKENS"])
// Override metadata.user_id with a sanitized value.
// Claude CLI sets metadata.user_id to a JSON object that third-party
// Anthropic-compatible APIs (e.g. DeepSeek) reject because the value
// doesn't match ^[a-zA-Z0-9_-]+$.
if _, ok := env["CLAUDE_CODE_EXTRA_BODY"]; !ok {
uid := "yao-sandbox"
if req.Config != nil && req.Config.Owner != "" {
uid = hashUserID(req.Config.Owner)
} else if assistantID != "" {
uid = hashUserID(assistantID)
}
env["CLAUDE_CODE_EXTRA_BODY"] = fmt.Sprintf(`{"metadata":{"user_id":"%s"}}`, uid)
}
logger.Debug("claude-env: EXTRA_BODY=%s", env["CLAUDE_CODE_EXTRA_BODY"])
return env
}

View file

@ -21,6 +21,7 @@ func GenerateHandler(proc *process.Process) interface{} {
provider := proc.ArgsString(1)
size := proc.ArgsString(2, "1024x1024")
model := proc.ArgsString(3)
authInfo := authorized.ProcessAuthInfo(proc)
if authInfo == nil {
@ -41,6 +42,9 @@ func GenerateHandler(proc *process.Process) interface{} {
}
options := map[string]interface{}{"size": size}
if model != "" {
options["model"] = model
}
resp, err := agentLLM.GenerateImage(conn, prompt, options)
if err != nil {
return map[string]interface{}{"error": fmt.Sprintf("image generation failed: %v", err)}

View file

@ -17,9 +17,13 @@
"type": "string",
"description": "Image dimensions (default: 1024x1024). Common values: 1024x1024, 1024x1792, 1792x1024.",
"default": "1024x1024"
},
"model": {
"type": "string",
"description": "Model name to use (e.g. 'doubao-seedream-4-5-251128', 'dall-e-3'). Overrides the provider's default model. If omitted, the provider's default model is used."
}
},
"required": ["prompt"]
},
"x-process-args": ["$args.prompt", "$args.provider", "$args.size"]
"x-process-args": ["$args.prompt", "$args.provider", "$args.size", "$args.model"]
}