Skip to content

[Bug] Launcher sends Claude Code's background requests to the agent route, running it twice per question #258

Description

@xinyu-dev

Environment

  • Repo: NVIDIA-NeMo/Switchyard @ main
  • Claude Code 2.1.220, macOS
  • Route bundle: examples/gym_biology_agent/routes.yaml

Description

Claude Code makes two API calls per question: one to answer it, one to name the
session. switchyard launch claude points both at whatever route you pass to
--model. When that route can reach an agent, the naming request runs the agent
too — the title request contains the user's own text, so the classifier reads it
and routes it exactly where the real question went.

The result is that every question runs the agent twice.

Steps to Reproduce

  1. bash examples/gym_biology_agent/run_agent_stack.sh
  2. switchyard launch claude --model demo/biomni-agent --config examples/gym_biology_agent/routes.yaml
  3. Ask one biology question, e.g. annotate the scFv of keytruda
  4. Read /v1/stats on the proxy port from the launch banner

Actual Result

Two agent runs for one question, both successful:

classifier requests: 2
gym/biomni-agent: calls=2  errors=0

The stack log shows the title run finishing on its own:

BioMni completed; trace_steps=18 tokens=169774

It ignored "write a title" and produced a full antibody annotation — 18 steps and
169,774 tokens to name a chat.

Expected Result

One agent run per question. Background work goes somewhere small.

Suggested Fix

_claude_env sets ANTHROPIC_SMALL_FAST_MODEL to the same value as
ANTHROPIC_MODEL, and because the launcher's overrides are merged on top of the
environment, that wins even if the user sets the variable themselves. Honouring an
existing value lets background traffic be pointed elsewhere.

Worth noting for anyone fixing this: simply dropping the variable does not work.
Claude Code would fall back to its own default (claude-haiku-4-5), and route
tables match on exact ids with no catch-all, so that request fails with
model_not_found. A bundle needs a small passthrough route for background work,
and the launcher needs to stop forcing the variable so it can be selected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions