The Agent Router is provider-neutral. You pick the backend on each run() call.
router.run({ provider: 'anthropic', model: 'claude-opus-4-7', … })
router.run({ provider: 'google', model: 'gemini-3.1-pro', … })
Same sandbox, same integrations, same memory. Only the executor changes.
Supported providers
provider | Backend | Models | Extras required |
|---|
anthropic | Claude Managed Agents | claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5 | — |
google | Vertex AI Agent Engine (ADK) | gemini-3.1-pro, gemini-3.1-flash | reasoningEngineId (one-time deploy) |
Anthropic
Anthropic is the zero-setup option. No pre-deployed resources; every run starts from the system + model you pass.
for await (const event of router.run({
provider: 'anthropic',
model: 'claude-opus-4-7',
system: 'You are a support agent.',
message: 'Where is my order?',
endUserId: 'u-123',
})) {
// …
}
Under the hood, the hosted router uses copass-anthropic-agents — the ManagedAgentBackend that talks to Anthropic’s beta.agents / beta.environments / beta.sessions surface. Reuses a per-fingerprint cache of Anthropic agent + environment resources so you don’t bump into their 60-creates/min limit.
Choosing a model
| Model | Best for |
|---|
claude-opus-4-7 | Hardest reasoning, longest contexts, deepest tool use. |
claude-sonnet-4-6 | Balanced — the default for most production agents. |
claude-haiku-4-5 | Fastest, cheapest. Classification, routing, lightweight chat. |
Google
Google’s Agent Engine differs in one important way: ADK agents are pre-deployed resources, and their tools are baked in at deploy time. To preserve the “connect once, use everywhere” model, Copass deploys each ADK agent carrying a single copass_dispatch(tool_name, arguments) proxy tool that calls back into Copass for real tool resolution.
So Google needs a one-time setup: deploy an ADK agent, get a reasoning_engine_id, pass it on every run.
Step 1 — Deploy an ADK agent (one time per agent identity)
from copass_google_agents.deploy import deploy_adk_agent
import os
engine = deploy_adk_agent(
display_name="support-agent",
project=os.environ["GOOGLE_CLOUD_PROJECT"],
system_prompt="You are a support agent…",
copass_api_url="https://ai.copass.id",
copass_api_key=os.environ["COPASS_API_KEY"],
)
print(engine.resource_name)
# → projects/{p}/locations/{l}/reasoningEngines/{id}
Save the resource_name — you’ll thread it into every run. Uses Application Default Credentials (gcloud auth application-default login locally, or a service account in deploy).
Step 2 — Run against the deployed engine
for await (const event of router.run({
provider: 'google',
model: 'gemini-3.1-pro',
reasoningEngineId: process.env.COPASS_REASONING_ENGINE_ID!,
location: 'us-central1', // optional GCP region override
system: 'You are a support agent.',
message: 'Where is my order?',
endUserId: 'u-123',
})) {
// Same event stream as Anthropic.
}
One ADK agent resource can back any number of end users — the endUserId is threaded per run. Deploy once per agent identity (support-agent, scheduling-agent, …), not per user.
Swapping providers mid-conversation
The event stream is identical. Your loop doesn’t change. Your Context Window and integrations stay in the sandbox. The only thing that moves is which provider actually executes the turn.
// Route heavy analysis to Opus, route cheap follow-ups to Gemini Flash.
const provider = needsReasoning ? 'anthropic' : 'google';
const model = needsReasoning ? 'claude-opus-4-7' : 'gemini-3.1-flash';
for await (const event of router.run({ provider, model, system, message, endUserId, reasoningEngineId })) {
// …
}
See Portable Context for why this works without breaking memory.
In-process vs hosted
The router runs the provider backends hosted — Copass executes the turn and streams events back to you. If you want to run a backend in-process (own the loop, own the billing relationship with the provider), install the provider package directly:
| Package | What you get |
|---|
copass-anthropic-agents | ManagedAgentBackend + CopassManagedAgent — run Claude Managed Agents in your own process. |
copass-google-agents | GoogleAgentBackend + CopassGoogleAgent — run Vertex ADK agents in your own process. |
copass-core-agents | The neutral ABCs (BaseAgent, AgentBackend, AgentTool) — implement your own provider. |
The router imports these same packages on the server side — the hosted and in-process paths are a single codepath.
Adding a provider
All backends implement AgentBackend from copass-core-agents. Implementing a new one (OpenAI, Mistral, a local runtime) means:
- Subclass
AgentBackend.
- Implement
run() and stream() — translate provider events into the neutral AgentEvent union.
- Register the backend server-side so a new
provider string routes to it.
That’s the extension point. Portability isn’t a feature — it’s the consequence of this boundary.
Next steps
- Events — the provider-neutral event stream every backend emits.
- Multi-turn — how
session_id threads across providers.
- Portable Context — the first-principles argument.