ASB

Merged
SA
9h ago
+426-3

Adds logfire.agent_sandboxes(), which returns a pydantic_monty.AsyncMontyWebsocket pool connected to Logfire Agent Sandboxes.

async with logfire.agent_sandboxes() as pool:
    async with pool.checkout() as session:
        result = await session.feed_run('1 + 1')
  • It's a plain def returning the pool, which is already an async context manager, so async with logfire.agent_sandboxes() works without an await.
  • The API key comes from the api_key argument, then configure(api_key=...), then LOGFIRE_API_KEY. Without one it raises LogfireConfigError.
  • The URL is wss://<region host>/monty-ws/, derived from the key's region through advanced.generate_base_url(), so advanced.base_url for self-hosted is respected. url= overrides it.
  • It sends Authorization: Bearer <key>. A user-supplied connect_headers is merged in and wins on conflicts.
  • It calls instrument_monty() by default; pass instrument=False to skip it.
  • The other AsyncMontyWebsocket kwargs are inlined with Monty's defaults.
  • Requires the new agent-sandboxes extra (pydantic-monty-client>=1.0.0), which is also forwarded by the logfire meta package.
  • The logfire-api shim raises RuntimeError, because there's no no-op pool it could return.

Docs are in #2670 so this can be released for beta testing first. agent_sandboxes is filtered out of reference/api/logfire.md until then.

Tests in tests/test_agent_sandboxes.py use a local WebSocket relay to a real monty subprocess, so code actually runs end to end. I haven't run the full suite locally; CI will tell.

🤖 Generated with Claude Code

https://claude.ai/code/session_01N2BkYWq7LvMK571ryZbia3