69 lines
1.9 KiB
Go
69 lines
1.9 KiB
Go
package util
|
|
|
|
import (
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/sjson"
|
|
)
|
|
|
|
const claudeCodeAttributionSystemPrefix = "x-anthropic-billing-header:"
|
|
|
|
// IsClaudeCodeAttributionSystemText reports whether text is the Claude Code
|
|
// attribution block that carries per-request billing and prompt fingerprint data.
|
|
func IsClaudeCodeAttributionSystemText(text string) bool {
|
|
text = strings.TrimLeftFunc(text, unicode.IsSpace)
|
|
return strings.HasPrefix(text, claudeCodeAttributionSystemPrefix)
|
|
}
|
|
|
|
// StripClaudeCodeAttributionSystem removes Claude Code billing/CCH attribution
|
|
// blocks from a Messages body. Other system content is kept. Providers such as
|
|
// Kimi and Antigravity may treat this block as prompt text, so callers use this
|
|
// helper when the active policy has not explicitly opted into a full CLI profile.
|
|
func StripClaudeCodeAttributionSystem(payload []byte) []byte {
|
|
system := gjson.GetBytes(payload, "system")
|
|
if !system.Exists() {
|
|
return payload
|
|
}
|
|
if system.Type == gjson.String {
|
|
if !IsClaudeCodeAttributionSystemText(system.String()) {
|
|
return payload
|
|
}
|
|
updated, errDelete := sjson.DeleteBytes(payload, "system")
|
|
if errDelete != nil {
|
|
return payload
|
|
}
|
|
return updated
|
|
}
|
|
if !system.IsArray() {
|
|
return payload
|
|
}
|
|
kept := make([]string, 0, len(system.Array()))
|
|
removed := false
|
|
system.ForEach(func(_, block gjson.Result) bool {
|
|
if block.Get("type").String() == "text" && IsClaudeCodeAttributionSystemText(block.Get("text").String()) {
|
|
removed = true
|
|
return true
|
|
}
|
|
if block.Raw != "" {
|
|
kept = append(kept, block.Raw)
|
|
}
|
|
return true
|
|
})
|
|
if !removed {
|
|
return payload
|
|
}
|
|
if len(kept) == 0 {
|
|
updated, errDelete := sjson.DeleteBytes(payload, "system")
|
|
if errDelete != nil {
|
|
return payload
|
|
}
|
|
return updated
|
|
}
|
|
updated, errSet := sjson.SetRawBytes(payload, "system", []byte("["+strings.Join(kept, ",")+"]"))
|
|
if errSet != nil {
|
|
return payload
|
|
}
|
|
return updated
|
|
}
|