feat: add Claude Code identity transforms for standalone OAuth usage
When proxying with OAuth (no auth plugin), applies the same body transforms as opencode-anthropic-auth: - Prepend 'You are Claude Code' identity to system prompt - Replace 'OpenCode' with 'Claude Code' in system text - Prefix tool names with 'mcp_' in tools and tool_use blocks These are only applied when ANTHROPIC_AUTH_TOKEN is set.
This commit is contained in:
parent
63307c70be
commit
2c14ec09b2
1 changed files with 63 additions and 1 deletions
|
|
@ -2561,6 +2561,7 @@ def create_app(
|
|||
|
||||
adapter = app.state.adapters[provider]
|
||||
client: httpx.Client = app.state.clients[provider]
|
||||
oauth_token = os.environ.get("ANTHROPIC_AUTH_TOKEN")
|
||||
|
||||
request_id = str(uuid.uuid4())
|
||||
started = time.perf_counter()
|
||||
|
|
@ -2572,6 +2573,68 @@ def create_app(
|
|||
session.token_state["model"] = req.model
|
||||
duplication_score = _duplication_score(req)
|
||||
outgoing_body = adapter.denormalize_request(req)
|
||||
|
||||
# When proxying for OAuth (no auth plugin doing transforms),
|
||||
# apply Claude Code identity transforms to the outbound body.
|
||||
# Ref: rmk40/opencode-anthropic-auth transformRequestBody()
|
||||
if oauth_token and provider == "anthropic":
|
||||
_CLAUDE_CODE_IDENTITY = "You are Claude Code, Anthropic's official CLI for Claude."
|
||||
system = outgoing_body.get("system")
|
||||
if isinstance(system, list):
|
||||
# Strip "OpenCode" identity line, replace OpenCode→Claude Code
|
||||
for i, item in enumerate(system):
|
||||
if isinstance(item, dict) and item.get("type") == "text" and item.get("text"):
|
||||
import re as _re_sys
|
||||
|
||||
text = item["text"]
|
||||
text = _re_sys.sub(
|
||||
r"^You are OpenCode, the best coding agent on the planet\.\n*",
|
||||
"",
|
||||
text,
|
||||
flags=_re_sys.MULTILINE,
|
||||
)
|
||||
text = text.replace("OpenCode", "Claude Code")
|
||||
text = _re_sys.sub(
|
||||
r"(?<!/)opencode", "Claude", text, flags=_re_sys.IGNORECASE
|
||||
)
|
||||
system[i] = {**item, "text": text}
|
||||
# Prepend Claude Code identity if not already there
|
||||
has_identity = any(
|
||||
isinstance(s, str) and s == _CLAUDE_CODE_IDENTITY for s in system
|
||||
)
|
||||
if not has_identity:
|
||||
system.insert(0, _CLAUDE_CODE_IDENTITY)
|
||||
elif isinstance(system, str):
|
||||
system = system.replace("OpenCode", "Claude Code")
|
||||
if not system.startswith(_CLAUDE_CODE_IDENTITY):
|
||||
system = f"{_CLAUDE_CODE_IDENTITY}\n{system}"
|
||||
outgoing_body["system"] = system
|
||||
|
||||
# Prefix tool names with mcp_
|
||||
tools = outgoing_body.get("tools")
|
||||
if isinstance(tools, list):
|
||||
for tool in tools:
|
||||
if (
|
||||
isinstance(tool, dict)
|
||||
and tool.get("name")
|
||||
and not tool["name"].startswith("mcp_")
|
||||
):
|
||||
tool["name"] = f"mcp_{tool['name']}"
|
||||
# Prefix tool_use names in messages
|
||||
messages = outgoing_body.get("messages")
|
||||
if isinstance(messages, list):
|
||||
for msg in messages:
|
||||
content = msg.get("content")
|
||||
if isinstance(content, list):
|
||||
for block in content:
|
||||
if (
|
||||
isinstance(block, dict)
|
||||
and block.get("type") == "tool_use"
|
||||
and block.get("name")
|
||||
and not block["name"].startswith("mcp_")
|
||||
):
|
||||
block["name"] = f"mcp_{block['name']}"
|
||||
|
||||
if endpoint == "count_tokens":
|
||||
outgoing_body.pop("stream", None)
|
||||
outgoing_body.pop("max_tokens", None)
|
||||
|
|
@ -2590,7 +2653,6 @@ def create_app(
|
|||
# Anthropic requires specific beta headers and a Claude-CLI-style
|
||||
# user-agent for OAuth Bearer auth to be accepted.
|
||||
# Ref: rmk40/opencode-anthropic-auth request-headers.mjs
|
||||
oauth_token = os.environ.get("ANTHROPIC_AUTH_TOKEN")
|
||||
if oauth_token and provider == "anthropic":
|
||||
headers.pop("x-api-key", None)
|
||||
headers.pop("X-Api-Key", None)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue