anthropics / anthropics/claude-agent-sdk-python

ClaudeSDKClient Cannot Be Shared Across Async Runtime Contexts

Aperta
#925 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug duplicate
Lingua principale
Python
Stelle
8.1k
Fork
1.3k
Merge medio
2g 31m
PR unite (30g)
1

Descrizione

## Bug: `ClaudeSDKClient` Cannot Be Shared Across Async Runtime Contexts

**Affected version:** v0.0.20+
**File:** `src/claude_agent_sdk/client.py`, line 55

---

### Description

`ClaudeSDKClient` instances are currently tied to the async context in which they were connected. Once `connect()` is called, the client spawns a persistent internal `anyio` task group responsible for reading incoming messages. This task group lives for the entire lifetime of the connection — from `connect()` through `disconnect()` — and cannot be safely accessed or reused from a different async runtime context.

This means the client **cannot** be passed to, or reused across:
- Different `trio` nurseries
- Different `asyncio` task groups
- Any other concurrent async scope that was not the original caller of `connect()`

---

### Why This Is a Problem

This constraint makes it difficult to build real-world applications where a single connected client needs to be shared or handed off between independent async workers, background tasks, or structured concurrency scopes. Common use cases that break under this limitation include:

- Connecting once at startup and reusing the client in multiple task groups
- Delegating work to a worker pool where individual tasks weren't the ones that called `connect()`
- Using the client inside frameworks that manage their own async lifecycles (e.g., FastAPI, Starlette, or Hypercorn with Trio)

---

### Expected Behavior

A connected `ClaudeSDKClient` instance should be usable from any async context, not just the one in which it was originally connected. The internal message-reading task group should either:

1. Be scoped independently of any caller-owned nursery/task group, or
2. Support safe cross-context handoff via a well-defined mechanism

---

### Suggested Fix

Consider running the internal `anyio` task group in a dedicated background thread or a standalone top-level task scope that is not a child of the caller's nursery. This would decouple the client's lifetime from the async scope of the connecting caller.

---

### References

- [`client.py` line 55](https://github.com/anthropics/claude-agent-sdk-python/blob/main/src/claude_agent_sdk/client.py#L55)
- anyio structured concurrency docs: https://anyio.readthedocs.io/en/stable/tasks.html

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.