diff --git a/internal/runtime/executor/claude_executor.go b/internal/runtime/executor/claude_executor.go index 1680f6f1..74988bc3 100644 --- a/internal/runtime/executor/claude_executor.go +++ b/internal/runtime/executor/claude_executor.go @@ -62,7 +62,7 @@ func (e *ClaudeExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, r body = e.injectThinkingConfig(req.Model, body) if !strings.HasPrefix(modelForUpstream, "claude-3-5-haiku") { - // body, _ = sjson.SetRawBytes(body, "system", []byte(misc.ClaudeCodeInstructions)) + body = checkSystemInstructions(body) } body = applyPayloadConfig(e.cfg, req.Model, body) @@ -162,7 +162,7 @@ func (e *ClaudeExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.A } // Inject thinking config based on model suffix for thinking variants body = e.injectThinkingConfig(req.Model, body) - // body, _ = sjson.SetRawBytes(body, "system", []byte(misc.ClaudeCodeInstructions)) + body = checkSystemInstructions(body) body = applyPayloadConfig(e.cfg, req.Model, body) // Extract betas from body and convert to header @@ -295,7 +295,7 @@ func (e *ClaudeExecutor) CountTokens(ctx context.Context, auth *cliproxyauth.Aut } if !strings.HasPrefix(modelForUpstream, "claude-3-5-haiku") { - // body, _ = sjson.SetRawBytes(body, "system", []byte(misc.ClaudeCodeInstructions)) + body = checkSystemInstructions(body) } // Extract betas from body and convert to header (for count_tokens too) @@ -676,3 +676,22 @@ func claudeCreds(a *cliproxyauth.Auth) (apiKey, baseURL string) { } return } + +func checkSystemInstructions(payload []byte) []byte { + system := gjson.GetBytes(payload, "system") + claudeCodeInstructions := `[{"type":"text","text":"You are Claude Code, Anthropic's official CLI for Claude.","cache_control":{"type":"ephemeral"}}]` + if system.IsArray() { + if gjson.GetBytes(payload, "system.0.text").String() != "You are Claude Code, Anthropic's official CLI for Claude." { + system.ForEach(func(_, part gjson.Result) bool { + if part.Get("type").String() == "text" { + claudeCodeInstructions, _ = sjson.SetRaw(claudeCodeInstructions, "-1", part.Raw) + } + return true + }) + payload, _ = sjson.SetRawBytes(payload, "system", []byte(claudeCodeInstructions)) + } + } else { + payload, _ = sjson.SetRawBytes(payload, "system", []byte(claudeCodeInstructions)) + } + return payload +}