Skip to content

fix(claude-agent-sdk): test against 0.1.18 after older releases left PyPI - #987

Merged
Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
abhi/claude-agent-sdk-0.1.18-matrix
Oct 20, 2026
Merged

Abhijeet Prasad (AbhiPrasad) merged 3 commits into
mainfrom
abhi/claude-agent-sdk-0.1.18-matrix

Conversation

@AbhiPrasad

@AbhiPrasad Abhijeet Prasad (AbhiPrasad) commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

claude-agent-sdk 0.1.9–0.1.17 were deleted from PyPI, so test_claude_agent_sdk(0.1.10) can no longer install and fails every nox shard (seen on #986; main breaks the same way on its next run). The exclude-newer cutoff in the logs is not the cause.

Matrix

  • Swap the old-version entry from 0.1.10 to 0.1.18, the oldest installable release. Re-recorded cassettes/0.1.18/ and removed cassettes/0.1.10/.
  • min_version stays 0.1.10; comments explain why the tested floor is higher.
  • 0.1.18 still needs the mcp 1.x constraint (Server.list_tools()).

Tracing fix (old CLIs)
CLIs bundled before 2.1 (2.0.72 in SDK 0.1.18) call the subagent tool Task and emit no task_started / task_notification messages, so subagent runs produced no task spans. Both tool names are now recognised. When a subagent message arrives with no task span yet, a task span is synthesized from the tool call under its Task/Agent tool span. It ends when the orchestrator gets that tool's result. In every latest cassette task_started arrives before the subagent's messages, so the fallback doesn't fire there.

Tests

  • Version gates assumed only 0.1.10 vs latest. Bisecting PyPI sdists gave the real versions: string prompts over stream-json in 0.1.31, top-level assistant error parsing in 0.1.29.
  • SDK API fields (verbatim_prompts, AssistantMessage.usage, ResultMessage.model_usage) are feature-detected instead of version-pinned.
  • Removed dead 0.1.10 branches, including silent early returns that reported passes without asserting.
  • The bundled-subagent tests now run on 0.1.18. The background-agent case skips only when the run streamed no subagent messages or task events.
  • The cassette transport won't save a recording with no result message, so a failed or hung recording can't leave a truncated cassette. Gate waits use transport.wait_timeout (short on replay, long when recording).

Test consolidation

  • Merged the interleaved and five-parallel subagent cassette tests into the concurrent subagent test. It now also asserts per-subagent tool pairing, task-to-Agent-tool parenting and end ordering, and that parallel Agent calls share one orchestrator LLM span despite relay user messages.
  • Dropped four FakeClaudeSDKClient subagent tests whose claims those cassettes now assert on real streams.

Span ordering fix
A subagent's last LLM span stayed open until request cleanup after its TASK span closed. This happened on the existing task_notification path (latest) and on the synthesized path. The LLM span is now finalized first.

Orchestrator parenting fix
_llm_parent_for_message fell back to the most recent open task span for any assistant message without a parent_tool_use_id. Every supported SDK tags subagent messages, so the fallback only caught orchestrator turns (e.g. TaskOutput polling while background subagents run) and nested them under a subagent's task. Those turns now parent to the root, asserted in test_multiple_bundled_subagents_keep_outer_orchestration_separate. That made the llm_parent_export merge guard and _message_starts_subagent_tool dead, so they're removed.

Validation

  • nox -s "test_claude_agent_sdk(0.1.18)" (CI mode): 37 passed, 6 skipped
  • nox -s "test_claude_agent_sdk(latest)" (CI mode): 43 passed
  • make check-stale-cassettes, make check-unused-cassettes INTEGRATIONS=claude_agent_sdk, pre-commit, pylint: clean

Separate from #986's Anthropic speed change.

🤖 Generated with Claude Code

…PyPI

claude-agent-sdk 0.1.9-0.1.17 were deleted from PyPI, so the
test_claude_agent_sdk(0.1.10) session could no longer install and failed
every nox shard. Move the old-version matrix entry to 0.1.18, the oldest
installable release, and re-record its cassettes. The integration still
supports >=0.1.10.

Testing 0.1.18 exposed that CLIs bundled before 2.1 call the subagent tool
"Task" and emit no task_* system messages, so subagent runs produced no
task spans. Recognise both tool names and synthesize a task span from the
subagent tool call when no task events arrive.

Tests:
- correct version gates that assumed only 0.1.10 vs latest
- feature-detect SDK API fields instead of pinning versions
- drop dead 0.1.10 branches, including silent early returns
- run the bundled-subagent tests on 0.1.18
- do not save a recording without a result message, and size gate waits
  for replay vs live recording

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T19:09:37.705030Z 7e9ea6a New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 27298384a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

ctx = self._contexts.get(str(tool_use_id)) if tool_use_id is not None else None
if ctx is None or not ctx.task_synthesized or ctx.task_span is None:
continue
ctx.task_span.end()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Close delegated LLM spans before synthesized task spans

When an older CLI completes a synthesized subagent, the delegated context can still have an open ctx.llm_span (as in the new 0.1.18 concurrent-subagent cassette, where each subagent's final tool-use assistant message is followed by the outer Task result). This line ends the parent TASK span immediately, while the child LLM span remains open until request cleanup after the overall result, producing a child whose end time is later than its parent's. Finalize the delegated LLM span, including its pending output/usage state, before ending the synthesized task.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 57a25bd. A delegated context's open LLM span is now finalized (pending output + usage-unknown marker) before its TASK span ends. This applied to the existing task_notification path too: the new assertion in test_concurrent_subagents_produce_parallel_llm_spans_with_correct_parenting (delegated LLM span must end no later than its task) failed on both 0.1.18 and latest before the fix.

…coverage

Merge the interleaved and five-parallel subagent cassette tests into the
concurrent subagent test, which now also asserts per-subagent tool pairing,
task-to-Agent-tool parenting and end ordering, and that parallel Agent
calls share one orchestrator LLM span despite relay user messages.

Drop four FakeClaudeSDKClient subagent tests whose claims those cassettes
now assert on real streams. Across 0.1.18 and latest this loses 1 of 1558
covered branches, reachable only from the fakes' unrealistic message shape.

Also end a subagent's open LLM span before its TASK span closes. Both the
task_notification path and the synthesized-task path left the last
delegated LLM span open until request cleanup, so it outlived its parent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt tasks

_llm_parent_for_message fell back to the most recent open task span for any
assistant message without a parent_tool_use_id. Every supported SDK tags
subagent messages with parent_tool_use_id, so the fallback only ever caught
orchestrator turns, e.g. TaskOutput polling while background subagents run,
and nested them under a subagent's task. Parent those turns to the root.

The fallback was the only source of an LLM parent changing within one
provider message, so the llm_parent_export merge guard and its field are now
dead, as is _message_starts_subagent_tool. Remove them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) merged commit 357d741 into main Oct 20, 2026
98 checks passed
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) deleted the abhi/claude-agent-sdk-0.1.18-matrix branch October 20, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant