From e3a72fe3f9cd326d3b97d9676e1c54c5b8c72c91 Mon Sep 17 00:00:00 2001 From: Arnav Date: Sat, 25 Apr 2026 17:38:26 -0500 Subject: [PATCH] bare mode to fix 9router --- backend/apps/agents/agents.py | 25 +++++++++++++++---- .../handlers/utils/run_browser_agent.py | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/backend/apps/agents/agents.py b/backend/apps/agents/agents.py index 8da49047..4b86d5c5 100644 --- a/backend/apps/agents/agents.py +++ b/backend/apps/agents/agents.py @@ -65,6 +65,17 @@ def _resolve_nine_router_model(model: str, has_api_key: bool) -> str: return model return NINE_ROUTER_MODEL_MAP.get(model, f"cc/{model}") + +def _resolve_extra_args(has_api_key: bool) -> dict[str, str | None]: + """When routing through 9Router, force the CLI to bypass keychain/OAuth. + + Without ``--bare`` the Claude Code CLI may consult the local Claude.ai + OAuth login and ignore ANTHROPIC_BASE_URL, which sends server-side + tools (WebSearch/WebFetch) to api.anthropic.com over a subscription + token that isn't entitled for them. + """ + return {} if has_api_key else {"bare": None} + AGENT_STORE: PydanticStore[Agent] = PydanticStore[Agent]( model_cls=Agent, data_dir=os.path.join(DB_ROOT, "sessions"), @@ -207,12 +218,15 @@ async def launch_agent( can_use_tool, pre_tool_hook, post_tool_hook = create_sdk_hooks(agent) settings = load_settings() + has_api_key: bool = bool(settings.anthropic_api_key) env = resolve_sdk_env( api_key=settings.anthropic_api_key, - nine_router_port=NINE_ROUTER_PORT if not settings.anthropic_api_key else None, + nine_router_port=NINE_ROUTER_PORT if not has_api_key else None, ) - resolved_model = _resolve_nine_router_model(model, bool(settings.anthropic_api_key)) + resolved_model = _resolve_nine_router_model(model, has_api_key) + extra_args = _resolve_extra_args(has_api_key) + debug("launch_agent backend=%s bare=%s", "api_key" if has_api_key else "9router", not has_api_key) agent.config = ClaudeAgentOptions( env=env, @@ -225,6 +239,7 @@ async def launch_agent( disallowed_tools=resolved_mode_config.disallowed_tools, permission_mode="default", can_use_tool=can_use_tool, + extra_args=extra_args, hooks={ "PreToolUse": [HookMatcher(matcher=None, hooks=[pre_tool_hook])], "PostToolUse": [HookMatcher(matcher=None, hooks=[post_tool_hook])], @@ -311,9 +326,9 @@ async def send_message( agent.config.system_prompt = resolved_mode_config.system_prompt if model_changed: settings = load_settings() - agent.config.model = _resolve_nine_router_model( - agent.model, bool(settings.anthropic_api_key), - ) + has_api_key: bool = bool(settings.anthropic_api_key) + agent.config.model = _resolve_nine_router_model(agent.model, has_api_key) + agent.config.extra_args = _resolve_extra_args(has_api_key) agent.config.allowed_tools = resolved_mode_config.allowed_tools agent.config.disallowed_tools = resolved_mode_config.disallowed_tools if resolved_mode_config.cwd: diff --git a/backend/core/tools/make_builtin_toolkit/open_swarm_toolkits/browser_toolkit/make_browser_delegation_toolkit/handlers/utils/run_browser_agent.py b/backend/core/tools/make_builtin_toolkit/open_swarm_toolkits/browser_toolkit/make_browser_delegation_toolkit/handlers/utils/run_browser_agent.py index ee2a4ee2..6002edb6 100644 --- a/backend/core/tools/make_builtin_toolkit/open_swarm_toolkits/browser_toolkit/make_browser_delegation_toolkit/handlers/utils/run_browser_agent.py +++ b/backend/core/tools/make_builtin_toolkit/open_swarm_toolkits/browser_toolkit/make_browser_delegation_toolkit/handlers/utils/run_browser_agent.py @@ -36,6 +36,7 @@ async def run_browser_agent( browser_config = ClaudeAgentOptions( env=parent.config.env, model=parent.config.model, + extra_args=parent.config.extra_args, system_prompt=BROWSER_AGENT_SYSTEM_PROMPT, tools=tool_names, mcp_servers=mcp_servers,