Skip to content

Bring Your Own Stack

Coactra is a composition shell. These pieces are intentionally not bundled — use the mature library for each concern and wire it through Coactra's seams.

Model Routing

Use Team.local(...) for one default model route:

import os

from coactra import Team

team = Team.local(
    tenant_id="acme",
    namespace="ops",
    capability="cheap-chat",
    model="openai/deepseek-v4-pro",
    api_base="https://opencode.ai/zen/go/v1",
    api_key=os.environ["OC_KEY"],
)
agent = await team.add_agent(
    name="sre-agent",
    instructions="Be terse.",
)

For multiple named routes, use team.add_model(...) and select one with model_capability=. For deterministic or fully local development, point the route at TestModel() or FunctionModel(...) instead of a live provider.

OAuth / MCP gateway auth

Coactra ships StaticToken for dev and pre-fetched bearer tokens:

import os

from coactra import StaticToken, Team

team = Team.local(
    tenant_id="acme",
    namespace="tools",
    capability="tool-agent",
    model="openai/deepseek-v4-pro",
    api_base="https://opencode.ai/zen/go/v1",
    api_key=os.environ["OC_KEY"],
)
agent = await team.add_agent(
    name="tool-agent",
    gateway="https://gateway.example/mcp",
    auth=StaticToken("your-token"),
)

For OAuth 2.1 client-credentials fetch and refresh, use authlib or httpx-oauth and pass any object implementing async def token() -> str to auth=.

Inbound A2A serving

Coactra does not assemble Starlette A2A apps. Use the official a2a-sdk server APIs and call your agent handler directly:

async def handle_message(text: str) -> str:
    return await agent.run(text)

Outbound A2A delegation

Use peers= with local agents or RemotePeer:

import os

from coactra import ModelProfile, ModelResolver, ModelRoute, Policy, RemotePeer, Scope, Team

team = Team(
    scope=Scope(tenant_id="acme", namespace="delegation"),
    policy=Policy.permissive(),
    model_resolver=ModelResolver([
        ModelRoute(
            capability="orchestrator",
            profile=ModelProfile(
                name="orchestrator",
                model="openai/deepseek-v4-pro",
                api_base="https://opencode.ai/zen/go/v1",
                api_key=os.environ["OC_KEY"],
            ),
        )
    ]),
)
agent = await team.add_agent(
    model_capability="orchestrator",
    name="orchestrator",
    peers=[RemotePeer(
        name="security-agent",
        endpoint="https://security.example/a2a",
        audience="security-agent",
    )],
)

Token exchange (RFC 8693)

For delegated identity without token passthrough, use KeycloakExchanger from coactra.agent.adapters (optional coactra[oauth] extra).

What Coactra owns

Keep in Coactra Bring your own
Team, Workflow, Run, Policy, Scope LiteLLM/OpenAI-compatible gateway deployment
Model routing contract (ModelResolver) provider credentials and key rotation
Peer delegation policy and wiring OAuth client-credentials (authlib)
Memory/workspace connectors inbound A2A Starlette app (a2a-sdk)