refactor: limit OpenCode keyword replacement to tool descriptions

This commit is contained in:
cyhhao
2026-01-31 01:40:38 +08:00
parent 602bf9c017
commit fe17058700
2 changed files with 21 additions and 7 deletions

View File

@@ -9,12 +9,12 @@ import (
func TestSanitizeOpenCodeText_RewritesCanonicalSentence(t *testing.T) { func TestSanitizeOpenCodeText_RewritesCanonicalSentence(t *testing.T) {
in := "You are OpenCode, the best coding agent on the planet." in := "You are OpenCode, the best coding agent on the planet."
got := sanitizeOpenCodeText(in) got := sanitizeSystemText(in)
require.Equal(t, strings.TrimSpace(claudeCodeSystemPrompt), got) require.Equal(t, strings.TrimSpace(claudeCodeSystemPrompt), got)
} }
func TestSanitizeOpenCodeText_RewritesOpenCodeKeywords(t *testing.T) { func TestSanitizeToolText_RewritesOpenCodeKeywords(t *testing.T) {
in := "OpenCode and opencode are mentioned." in := "OpenCode and opencode are mentioned."
got := sanitizeOpenCodeText(in) got := sanitizeToolText(in)
require.Equal(t, "Claude Code and Claude are mentioned.", got) require.Equal(t, "Claude Code and Claude are mentioned.", got)
} }

View File

@@ -697,7 +697,10 @@ func normalizeParamNameForOpenCode(name string, cache map[string]string) string
return name return name
} }
func sanitizeOpenCodeText(text string) string { // sanitizeSystemText rewrites only the fixed OpenCode identity sentence (if present).
// We intentionally avoid broad keyword replacement in system prompts to prevent
// accidentally changing user-provided instructions.
func sanitizeSystemText(text string) string {
if text == "" { if text == "" {
return text return text
} }
@@ -709,6 +712,17 @@ func sanitizeOpenCodeText(text string) string {
"You are OpenCode, the best coding agent on the planet.", "You are OpenCode, the best coding agent on the planet.",
strings.TrimSpace(claudeCodeSystemPrompt), strings.TrimSpace(claudeCodeSystemPrompt),
) )
return text
}
// sanitizeToolText is intentionally more aggressive than sanitizeSystemText because
// tool descriptions are not user chat content, and some upstreams may flag "opencode"
// strings as non-Claude-Code fingerprints.
func sanitizeToolText(text string) string {
if text == "" {
return text
}
text = sanitizeSystemText(text)
text = strings.ReplaceAll(text, "OpenCode", "Claude Code") text = strings.ReplaceAll(text, "OpenCode", "Claude Code")
text = opencodeTextRe.ReplaceAllString(text, "Claude") text = opencodeTextRe.ReplaceAllString(text, "Claude")
return text return text
@@ -720,7 +734,7 @@ func sanitizeToolDescription(description string) string {
} }
description = toolDescAbsPathRe.ReplaceAllString(description, "[path]") description = toolDescAbsPathRe.ReplaceAllString(description, "[path]")
description = toolDescWinPathRe.ReplaceAllString(description, "[path]") description = toolDescWinPathRe.ReplaceAllString(description, "[path]")
return sanitizeOpenCodeText(description) return sanitizeToolText(description)
} }
func normalizeToolInputSchema(inputSchema any, cache map[string]string) { func normalizeToolInputSchema(inputSchema any, cache map[string]string) {
@@ -795,7 +809,7 @@ func normalizeClaudeOAuthRequestBody(body []byte, modelID string, opts claudeOAu
if system, ok := req["system"]; ok { if system, ok := req["system"]; ok {
switch v := system.(type) { switch v := system.(type) {
case string: case string:
sanitized := sanitizeOpenCodeText(v) sanitized := sanitizeSystemText(v)
if sanitized != v { if sanitized != v {
req["system"] = sanitized req["system"] = sanitized
} }
@@ -812,7 +826,7 @@ func normalizeClaudeOAuthRequestBody(body []byte, modelID string, opts claudeOAu
if !ok || text == "" { if !ok || text == "" {
continue continue
} }
sanitized := sanitizeOpenCodeText(text) sanitized := sanitizeSystemText(text)
if sanitized != text { if sanitized != text {
block["text"] = sanitized block["text"] = sanitized
} }