Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions executor/agents/claude_code/claude_code_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,19 +599,32 @@ async def _async_execute(self) -> TaskStatus:
if cached_client:
# Verify the cached client is still valid
# Check if client process is still running
# Note: Claude SDK client structure is: client._transport._process
try:
if hasattr(cached_client, "_process") and cached_client._process:
if cached_client._process.poll() is not None:
process = None
if (
hasattr(cached_client, "_transport")
and cached_client._transport
and hasattr(cached_client._transport, "_process")
and cached_client._transport._process
):
process = cached_client._transport._process
Comment on lines +604 to +611

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check for dependency specifications
find . -type f \( -name "requirements*.txt" -o -name "pyproject.toml" -o -name "setup.py" -o -name "setup.cfg" \) | head -20

Repository: wecode-ai/Wegent

Length of output: 369


🏁 Script executed:

# Read the actual file to verify the code segment
cat -n executor/agents/claude_code/claude_code_agent.py | sed -n '600,650p'

Repository: wecode-ai/Wegent

Length of output: 3179


🏁 Script executed:

# Check for any claude_agent_sdk version references
rg "claude_agent_sdk|claude-agent-sdk" --type py -B2 -A2

Repository: wecode-ai/Wegent

Length of output: 5549


🏁 Script executed:

# Check the executor pyproject.toml for claude_agent_sdk version
cat executor/pyproject.toml | grep -A5 -B5 "claude"

Repository: wecode-ai/Wegent

Length of output: 340


🏁 Script executed:

# Also check executor/requirements.txt
cat executor/requirements.txt | grep "claude"

Repository: wecode-ai/Wegent

Length of output: 83


🏁 Script executed:

# Check the type hints used in the function to see if type annotations are used
cat -n executor/agents/claude_code/claude_code_agent.py | sed -n '450,470p'

Repository: wecode-ai/Wegent

Length of output: 1165


🏁 Script executed:

# Check the function signature and surrounding context for type annotation patterns
cat -n executor/agents/claude_code/claude_code_agent.py | sed -n '440,460p'

Repository: wecode-ai/Wegent

Length of output: 899


🏁 Script executed:

# Let me check what's actually in the pyproject.toml more carefully
cat executor/pyproject.toml

Repository: wecode-ai/Wegent

Length of output: 2452


🌐 Web query:

claude-agent-sdk 0.1.31 _transport _process documentation

💡 Result:

In claude-agent-sdk==0.1.31 (Python), modules named _transport / _process (leading underscore) are private, internal implementation details and aren’t part of the supported/public API, so there isn’t “official documentation” for them the way there is for query() / ClaudeSDKClient / ClaudeAgentOptions. The public docs focus on those supported entry points instead. [1], [2]

What you can do:

  • Use the supported API: claude_agent_sdk.query(...) for simple/streaming runs, or ClaudeSDKClient for interactive sessions, tools, and hooks. [1], [2], [3]
  • Read the source for internals (best-effort, may change between patch versions):
    • Download the 0.1.31 sdist from PyPI and inspect the package code locally. [1]
    • In the repo / installed package, the transport logic is implemented under internal paths such as claude_agent_sdk/_internal/transport/... (for example subprocess_cli.py, referenced in bug reports). [4]

If you tell me what you’re trying to accomplish (e.g., custom transport, embedding, debugging a subprocess hang, replacing the bundled CLI, etc.), I can point to the exact internal files/classes involved and the least-fragile way to extend/patch it for 0.1.31.


🌐 Web query:

claude-agent-sdk changelog version 0.1.6 to 0.1.31 breaking changes

💡 Result:

First: which “claude-agent-sdk”?

  • Python package (pip install claude-agent-sdk): the latest visible release in the official GitHub releases feed is v0.1.29 (Feb 4, 2026)—there is no 0.1.31 shown there. [3]
  • TypeScript package (npm install @anthropic-ai/claude-agent-sdk``) may have different versions; however, your version range 0.1.6 → 0.1.31 does not match the Python release list. [3]

Breaking changes from 0.1.6 upward (Python) — confirmed

1) CLI distribution / install requirements changed (potentially breaking operationally)

  • In 0.1.6, the PyPI page lists Node.js as a prerequisite and instructs installing Claude Code via npm (npm install -g @anthropic-ai/claude-code``). [1]
  • The current PyPI page states the Claude Code CLI is bundled with the package (no separate install), and you can optionally point to a custom CLI path via ClaudeAgentOptions(cli_path=...). [2]

Why this can be “breaking” in practice: deployments that relied on a system/global CLI (or on Node being present, or on small wheels) may need changes (e.g., slimmer containers now pulling large wheels; different CLI selection/override behavior). [1][2]

What I can’t confirm from official sources here

I couldn’t access an official, complete per-version changelog that enumerates all breaking changes specifically between 0.1.6 and 0.1.31, and for Python specifically 0.1.31 doesn’t appear to exist in the official Python releases listing. [3]

If you tell me whether you mean Python or TypeScript, and (for TS) share the exact package name + a link to the changelog page you’re using, I can narrow this to a definitive “breaking changes only” list.


🏁 Script executed:

# Check if there are any other version pins or if this is a known configuration
cat executor/requirements.txt | head -20

Repository: wecode-ai/Wegent

Length of output: 422


🏁 Script executed:

# Look for any build or CI configuration that might explain the version discrepancy
find . -type f \( -name "*.yml" -o -name "*.yaml" -o -name "*.md" \) | grep -i "build\|ci\|readme" | head -10

Repository: wecode-ai/Wegent

Length of output: 324


Resolve the version mismatch in claude-agent-sdk dependencies before relying on private SDK internals.

executor/requirements.txt pins claude_agent_sdk==0.1.6 while executor/pyproject.toml pins claude-agent-sdk==0.1.31. This inconsistency must be resolved first, as accessing private internals like _transport._process is inherently fragile and will break across SDK versions. Once the versions are aligned, consider adding a brief comment linking to the SDK source or changelog that documents the structure being relied upon, since future maintainers will need to re-verify this if the SDK updates.

Minor: process could benefit from a type annotation (process: Any = None) for clarity, though the existing defensive hasattr checks and try-except wrapper provide appropriate mitigations.

🤖 Prompt for AI Agents
In `@executor/agents/claude_code/claude_code_agent.py` around lines 604 - 611,
Align the claude-agent-sdk version pins (resolve the mismatch between
executor/requirements.txt and executor/pyproject.toml) before touching private
internals; after aligning versions, replace or guard direct access to
cached_client._transport._process (used in claude_code_agent.py) by either using
a supported public API from the SDK or wrapping that access with a stable
compatibility helper, add a brief comment referencing the SDK source/changelog
location that documents _transport/_process structure, and add a type annotation
for process (e.g., process: Any = None) to clarify intent.


if process is not None:
poll_result = process.poll()
if poll_result is not None:
# Process has terminated, remove from cache
logger.warning(
f"Cached client process terminated for session_id: {self.session_id}, creating new client"
f"Cached client process terminated for session_id: {self.session_id}, "
f"exit_code={poll_result}, creating new client"
)
SessionManager.remove_client(self.session_id)
# Proceed to create new client
else:
# Process is still running, reuse client
logger.info(
f"Reusing existing Claude client for session_id: {self.session_id}"
f"Reusing existing Claude client for session_id: {self.session_id}, "
f"process_pid={process.pid}"
)
self.add_thinking_step(
title="Reuse Existing Client",
Expand All @@ -621,11 +634,13 @@ async def _async_execute(self) -> TaskStatus:
)
self.client = cached_client
else:
# No process info available, assume client is valid
logger.info(
f"Reusing existing Claude client for session_id: {self.session_id}"
# No process info available, client may be invalid
# Remove from cache and create new client to be safe
logger.warning(
f"No process info available for cached client session_id: {self.session_id}, "
"removing from cache and creating new client"
)
self.client = cached_client
SessionManager.remove_client(self.session_id)
except Exception as e:
logger.warning(
f"Error checking client validity: {e}, creating new client"
Expand Down