MCPcopy
hub / github.com/anthropics/claude-agent-sdk-python / InternalClient

Class InternalClient

src/claude_agent_sdk/_internal/client.py:28–230  ·  view source on GitHub ↗

Internal client implementation.

Source from the content-addressed store, hash-verified

26
27
28class InternalClient:
29 """Internal client implementation."""
30
31 def __init__(self) -> None:
32 """Initialize the internal client."""
33
34 def _convert_hooks_to_internal_format(
35 self, hooks: dict[HookEvent, list[HookMatcher]]
36 ) -> dict[str, list[dict[str, Any]]]:
37 """Convert HookMatcher format to internal Query format."""
38 internal_hooks: dict[str, list[dict[str, Any]]] = {}
39 for event, matchers in hooks.items():
40 internal_hooks[event] = []
41 for matcher in matchers:
42 # Convert HookMatcher to internal dict format
43 internal_matcher: dict[str, Any] = {
44 "matcher": matcher.matcher if hasattr(matcher, "matcher") else None,
45 "hooks": matcher.hooks if hasattr(matcher, "hooks") else [],
46 }
47 if hasattr(matcher, "timeout") and matcher.timeout is not None:
48 internal_matcher["timeout"] = matcher.timeout
49 internal_hooks[event].append(internal_matcher)
50 return internal_hooks
51
52 async def process_query(
53 self,
54 prompt: str | AsyncIterable[dict[str, Any]],
55 options: ClaudeAgentOptions,
56 transport: Transport | None = None,
57 ) -> AsyncIterator[Message]:
58 """Process a query through transport and Query."""
59
60 # Fail fast on invalid session_store option combinations before
61 # spawning the subprocess.
62 validate_session_store_options(options)
63
64 # resume/continue + session_store: load the session from the store
65 # into a temp CLAUDE_CONFIG_DIR for the subprocess to resume from.
66 # Skipped when a custom transport was supplied — the materialized
67 # options never reach a pre-constructed transport, so loading the
68 # store and writing .credentials.json to a temp dir would be wasted.
69 materialized = (
70 await materialize_resume_session(options) if transport is None else None
71 )
72 inner = self._process_query_inner(prompt, options, transport, materialized)
73 try:
74 async for msg in inner:
75 yield msg
76 finally:
77 # ``async for`` does NOT close its iterator when the loop body
78 # raises (PEP 533 was deferred). Explicitly aclose the inner
79 # generator first so its ``finally: await query.close()`` runs —
80 # i.e. the subprocess is terminated — *before* we remove the temp
81 # CLAUDE_CONFIG_DIR it is reading/writing.
82 try:
83 await inner.aclose()
84 finally:
85 # The temp dir holds a .credentials.json copy — remove it on

Calls

no outgoing calls