Skip to main content
Most agent stacks bundle four things into a single vendor runtime:
┌──────────────────────────────────────────┐
│   VENDOR RUNTIME (Anthropic, OpenAI, …)  │
│                                          │
│   • the model                            │
│   • the tool schemas                     │
│   • the memory / session state           │
│   • the OAuth'd integrations             │
└──────────────────────────────────────────┘
It ships fast. It also means the day you want to try a different provider, you re-OAuth every integration, re-build every tool adapter, and leave your conversation history behind. Copass inverts the diagram. The sandbox owns the durable state. The provider becomes an execution backend.
┌──────────────────────────────────────────┐
│   COPASS SANDBOX (durable, your control) │
│                                          │
│   • integrations (OAuth connections)     │
│   • Context Window (agent memory)        │
│   • knowledge graph (entities, embeds)   │
│   • vault (raw bytes)                    │
└──────────────────────────────────────────┘
               ▲            ▲
               │            │
      ┌────────┴────┐   ┌───┴──────────┐
      │  Anthropic  │   │   Google     │   …any backend
      │   runtime   │   │   runtime    │   implementing AgentBackend
      └─────────────┘   └──────────────┘
Both runtimes read the same integrations, the same window, the same graph. Switching providers is a provider: flag change, not a migration.

Three things this unlocks

Swap providers without losing memory

The Context Window lives in the sandbox. Turn 12 with Anthropic and turn 13 with Google see the same history — no export/import, no re-prompting.

Connect once, run everywhere

OAuth a user’s GitHub through router.integrations.connect('github', …) once. Every runtime — today’s and tomorrow’s — gets it as a tool automatically.

Compare providers on identical ground

Same tools, same context, same user. The only variable is the model. Benchmark Anthropic vs. Google on your workload, not on a vendor’s demo script.

The three primitives that make it work

Portable context is not a feature — it’s the consequence of where Copass draws its boundaries.

1. The sandbox is the tenancy boundary, not the runtime

Sandboxes are durable. They outlive any single run, any single conversation, any single provider. They hold your vault prefix, your encryption keys, your quotas. Providers don’t have a notion like this — their session objects are short-lived and vendor-shaped. See Secure Storage.

2. Integrations are data sources, not vendor features

When you call router.integrations.connect('github', …), Copass registers the resulting OAuth connection as a data source inside the sandbox. That data source has the same shape as a filesystem data source or a manual custom source. It gets tagged on every byte of ingested data; its tools get exposed to every runtime. The integration is attached to your tenancy, not to Anthropic’s session. That’s the piece that makes it portable.

3. The Context Window is a data source, not a prompt

Conventional “agent memory” is prompt text the vendor glues into the system message on your behalf. It lives in the vendor’s session store. Copass stores the window as an ephemeral data source in the sandbox. Retrieval reads from it. The next turn — on any provider — sees it. See Window-Aware Retrieval for how the window shapes each retrieval call across turns.

Compared to the alternatives

  Vendor-native memory                    Portable context

  • Lives inside the vendor's session     • Lives in your sandbox
  • Locked to one model family            • Any runtime reads it
  • Re-OAuth on provider switch           • Connect once, reuse everywhere
  • "Migration" is a custom project       • Migration is a config flag
  • Benchmarks are apples-to-oranges      • Benchmarks are apples-to-apples

What this looks like in code

The boundary shows up cleanly in the Agent Router API. The same router switches providers on a per-call basis; the sandbox it points at never changes.
const router = new AgentRouter({
  auth: { type: 'api-key', key: process.env.COPASS_API_KEY! },
  sandboxId: 'sb_...',
});

// Connect the integration once, against the sandbox.
await router.integrations.connect('github', { onConnectUrl: open });

// Run turn 1 on Anthropic.
for await (const e of router.run({ provider: 'anthropic', model: 'claude-opus-4-7', system, message: '...', endUserId: 'u-123' })) { /* … */ }

// Run turn 2 on Google. Same window, same integrations, same graph.
for await (const e of router.run({ provider: 'google', model: 'gemini-3.1-pro', reasoningEngineId, system, message: '...', endUserId: 'u-123' })) { /* … */ }
The provider flag is the only thing that changes. The tools GitHub exposes, the previous turn’s retrievals, the user’s prior conversation — all of it stays live.

Why this matters for product decisions

Provider costs move. Model capabilities move. If your memory and integrations are in the sandbox, you can route cheap turns to one provider and expensive reasoning to another — or flip the whole fleet when the price curve inverts. Vendor-native memory makes that decision a migration project; portable context makes it a config change.
Split traffic 50/50, A/B test, dark-launch a new model. Each cohort sees the same user context. You’re measuring the model, not the plumbing.
Integrations land in your sandbox. Tokens, metadata, and ingested bytes are encrypted at rest under your sandbox prefix. No provider session object ever holds the auth.
When the next frontier model ships, adding it is implementing AgentBackend and registering the provider string. Your product surface doesn’t change. Your users don’t re-onboard.

Where to go next

  • Agent Router — the execution surface that makes portability a one-line flag.
  • Multi-tenancy — how one sandbox holds many end users alongside this provider-portable context.
  • Secure Storage — the sandbox model that owns the durable state.
  • Window-Aware Retrieval — how the Context Window stays sharp across runtimes and turns.
  • Progressive Disclosure — the retrieval gradient every runtime inherits for free.