chore: release main#443
Conversation
…g handler (#430) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ing handler (#431) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
38f3e69 to
c26eb73
Compare
…ort (#432) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: OpenAI <openai@example.com>
c26eb73 to
6665513
Compare
6665513 to
beee3cc
Compare
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
beee3cc to
d470497
Compare
…435) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d470497 to
2b2856c
Compare
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2b2856c to
764d347
Compare
…alStreamingModel (#442) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
764d347 to
9e9e3fa
Compare
9e9e3fa to
23bb002
Compare
| if seen_tool_output: | ||
| # This is the final text message after tool execution | ||
| message_index += 1 | ||
| item_id_to_index[item_id] = message_index | ||
| else: | ||
| item_id_to_index[item_id] = message_index | ||
|
|
There was a problem hiding this comment.
The first text item reuses the current message_index unless seen_tool_output is true. For a reasoning-model stream, the reasoning delta above creates an index first; when the answer text arrives with a new item_id, it is mapped to that same index. This can send two Start events with the same index, route text deltas into the still-open reasoning context, or overwrite the reasoning context in auto_send's ctx_map, leaving the reasoning message unfinalized and attaching the final answer to the wrong message. Reserve a fresh index for every new text item_id, not only after tool output, or close and advance the reasoning item before starting text.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/adk/_modules/_openai_sync.py
Line: 299-305
Comment:
**Text reuses index**
The first text item reuses the current `message_index` unless `seen_tool_output` is true. For a reasoning-model stream, the reasoning delta above creates an index first; when the answer text arrives with a new `item_id`, it is mapped to that same index. This can send two `Start` events with the same index, route text deltas into the still-open reasoning context, or overwrite the reasoning context in `auto_send`'s `ctx_map`, leaving the reasoning message unfinalized and attaching the final answer to the wrong message. Reserve a fresh index for every new text `item_id`, not only after tool output, or close and advance the reasoning item before starting text.
How can I resolve this? If you propose a fix, please make it concise.| # Don't send done events for reasoning content/summary | ||
| # They just end with their last delta | ||
| if message_type not in ("reasoning_content", "reasoning_summary"): | ||
| yield StreamTaskMessageDone( | ||
| type="done", | ||
| index=item_id_to_index[item_id], | ||
| ) |
There was a problem hiding this comment.
Reasoning messages are opened with StreamTaskMessageStart, but this branch skips the matching Done. UnifiedEmitter.auto_send only closes contexts on StreamTaskMessageDone; otherwise it closes them during final teardown, and SpanDeriver.flush() can mark the reasoning span incomplete. When an OpenAI reasoning or summary item is emitted through OpenAITurn(result=...), sync/yield consumers never receive a normal done event for the reasoning message. Emit StreamTaskMessageDone when a reasoning content or summary output item completes, since the accumulator already rebuilds ReasoningContent from reasoning deltas.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/adk/_modules/_openai_sync.py
Line: 178-184
Comment:
**Reasoning streams hang**
Reasoning messages are opened with `StreamTaskMessageStart`, but this branch skips the matching `Done`. `UnifiedEmitter.auto_send` only closes contexts on `StreamTaskMessageDone`; otherwise it closes them during final teardown, and `SpanDeriver.flush()` can mark the reasoning span incomplete. When an OpenAI reasoning or summary item is emitted through `OpenAITurn(result=...)`, sync/yield consumers never receive a normal done event for the reasoning message. Emit `StreamTaskMessageDone` when a reasoning content or summary output item completes, since the accumulator already rebuilds `ReasoningContent` from reasoning deltas.
How can I resolve this? If you propose a fix, please make it concise.| if tool_call_item.arguments: | ||
| if isinstance(tool_call_item.arguments, str): | ||
| import json | ||
|
|
||
| tool_arguments = json.loads(tool_call_item.arguments) if tool_call_item.arguments else {} |
There was a problem hiding this comment.
This json.loads() runs on the OpenAI streaming conversion path without a guard. If the Agents SDK surfaces malformed, truncated, or provider-specific raw function arguments, convert_openai_to_agentex_events / OpenAITurn.events raises and stops the whole turn before later tool output or final text can be delivered. The Temporal streaming path already catches JSONDecodeError and falls back to {}; this converter should use the same defensive parsing here and in the generic arguments branch, for example by using {} or preserving the raw string under _raw.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/adk/_modules/_openai_sync.py
Line: 73-77
Comment:
**Bad args abort**
This `json.loads()` runs on the OpenAI streaming conversion path without a guard. If the Agents SDK surfaces malformed, truncated, or provider-specific raw function arguments, `convert_openai_to_agentex_events` / `OpenAITurn.events` raises and stops the whole turn before later tool output or final text can be delivered. The Temporal streaming path already catches `JSONDecodeError` and falls back to `{}`; this converter should use the same defensive parsing here and in the generic arguments branch, for example by using `{}` or preserving the raw string under `_raw`.
How can I resolve this? If you propose a fix, please make it concise.

✨ Stainless prepared a new release
agentex-client: 0.16.0
0.16.0 (2026-06-24)
Full Changelog: agentex-client-v0.15.0...agentex-client-v0.16.0
⚠ BREAKING CHANGES
Features
Bug Fixes
Refactors
agentex-sdk: 0.15.0
0.15.0 (2026-06-24)
Full Changelog: agentex-sdk-v0.14.0...agentex-sdk-v0.15.0
⚠ BREAKING CHANGES
Refactors
This pull request is managed by Stainless's GitHub App.
The semver version number is based on included commit messages. Alternatively, you can manually set the version number in the title of this pull request.
For a better experience, it is recommended to use either rebase-merge or squash-merge when merging this pull request.
🔗 Stainless website
📚 Read the docs
🙋 Reach out for help or questions
Greptile Summary
Confidence Score: 3/5
Merge safety is reduced by OpenAI streaming conversion edge cases and a CLI cancellation path that can create files after cancellation.
The changes are broad but the main risks are concentrated in the OpenAI sync converter and init command prompt flow.
src/agentex/lib/adk/_modules/_openai_sync.py; src/agentex/lib/cli/commands/init.py
What T-Rex did
**Verification: Text reuses index**
**Result**: Blocked
Executed a focused direct-converter repro harness with fake OpenAI reasoning and text stream events, but runtime import could not load the reviewed converter file from the repository checkout.
The captured run output shows the repro stopped before exercising the converter because src/agentex/lib/adk/_modules/_openai_sync.py was missing at execution time.
**Verification: Reasoning streams hang**
**Result**: Blocked
I attempted to run a focused converter harness, but the repository checkout no longer contains src/agentex/lib/adk/_modules/_openai_sync.py, so the changed code could not be executed.
Installing the ADK package was also blocked because the available interpreter is Python 3.11.6 while agentex-sdk requires Python >=3.12.
**Verification: Bad args abort**
**Result**: Blocked
I created a focused local Python harness with faked OpenAI response classes to exercise both the ResponseFunctionToolCall branch and the generic arguments branch with malformed JSON followed by later tool output and final text.
Running the harness with PYTHONPATH=src was blocked before converter execution because the reviewed file src/agentex/lib/adk/_modules/_openai_sync.py is missing from the working tree, so the runtime path could not be loaded.
**Verification: Cancel creates project**
**Result**: Reproduced
Executed a focused Python harness against the actual init command with mocked questionary prompts where earlier answers were valid and the package-manager select returned None.
The run showed the temp directory was empty before init and contained a generated cancel_agent project afterward.
The captured CLI output showed the package-manager prompt returned None, followed by project structure creation and the success message.
The generated files included requirements.txt and Dockerfile, proving the cancellation flowed through as the non-uv path.
`trex-artifacts/release-metadata-01-before.txt` contains the executed base run with command, working directory, full parsed metadata, and exit code 0.
The required after artifact is missing because the runtime command facility failed before it could be generated.
Per validation instructions, I am marking this inconclusive rather than substituting static inspection or prose for executed head evidence.
Successful setup command output showed both requested worktrees were created.
Initial package-import smoke command failed with `ModuleNotFoundError: No module named 'httpx'`, before exercising changed template code.
Subsequent attempts to run the adjusted harness and even a trivial `pwd; ls` command returned `Not connected`, preventing executable proof capture in `trex-artifacts`.
No valid proof artifacts were produced for this request.
Blocker: shell execution backend disconnected before the focused contract script and pytest commands could complete, preventing executed before/after comparison evidence.
`trex-artifacts/temporal-hosted-tools-01-before.txt` contains the actual captured base command output.
Missing required comparable after artifact: command execution became unavailable before the head run could be performed.
Blocker: `multibash` returned `Not connected` for simple commands including `bash -lc 'echo hi'`, preventing further runtime validation.
Comments Outside Diff (1)
src/agentex/lib/cli/commands/init.py, line 266-274 (link)Earlier prompts return immediately when the user cancels, but this prompt does not. If the user cancels at the package-manager prompt,
use_uvbecomesNone, then flows through as falsy and creates the non-uv template with a success message. Add the same cancel guard before buildinganswers.Artifacts
Repro: focused init cancellation harness
Repro: harness output showing project creation after package-manager cancellation
Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (8): Last reviewed commit: "chore: release main" | Re-trigger Greptile