fix: unblock SDK security dependency patches#336
Merged
declan-scale merged 1 commit intonextfrom Apr 30, 2026
Merged
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
209dc1f to
42b9d17
Compare
Contributor
|
Can you pull the latest next and rebase this branch off of next? The diff looks a little messed up |
42b9d17 to
91d33eb
Compare
declan-scale
approved these changes
Apr 30, 2026
Merged
declan-scale
added a commit
that referenced
this pull request
Apr 30, 2026
* feat(api): api update * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * chore(internal): more robust bootstrap script * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * fix: use correct field name format for multipart file arrays * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * feat: support setting headers via env * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * codegen metadata * fix: allow litellm security patch (#336) * fix(adk): Always inject headers on execute activity (#337) * perf(streaming): coalesce per-token publishes to Redis (50ms / 128-char window) (#333) * perf(streaming): coalesce per-token publishes to Redis (50ms / 128-char window) Per-token Redis publishes from TemporalStreamingModel were adding ~45s (56-62%) overhead to agent response latency, mostly from head-of-line blocking on the model's event loop: each `await streaming_context.stream_update(...)` inside the OpenAI stream `async for` paused token consumption until the publish round-trip completed. This change introduces a `CoalescingBuffer` driven by an `asyncio.Event`, so the producer never awaits on Redis. Deltas are merged consecutive-only (preserving character order in every (type, index) channel) and flushed on a 50ms timer, on a 128-char size threshold, or immediately for the first delta to keep perceived responsiveness high. The buffer's `close()` drains remaining deltas before the DONE event, so consumers see the full sequence in order. A new `StreamingMode = Literal["off", "per_token", "coalesced"]` lives in `streaming.py` as the single source of truth and is plumbed through the adk streaming module, `StreamingService.streaming_task_message_context`, and `StreamingTaskMessageContext`. Default is `"coalesced"` everywhere, so all 13+ existing context callers (claude_agents, langgraph, litellm provider, openai sync provider, etc.) benefit automatically. * chore(streaming): fix import ordering (ruff I001) * fix(streaming): address greptile review findings - _run: when CancelledError is raised mid-flush in the for-loop, re-enqueue the in-flight item plus any remaining items in the local `drained` list back into self._buf so close()'s final drain can recover them. Previously the local `drained` list was unreachable after CancelledError exited the for-loop, causing the last coalesced batch to be silently dropped on close-during-flush races. Trade-off: the in-flight item may be duplicated on the consumer side (Redis pub may have completed before cancel was delivered), which is preferable to silent loss for streaming UX. - _merge_pair: replace `return b` fallback with AssertionError. All six current TaskMessageDelta variants have explicit isinstance branches, so the fallback is unreachable today. But _can_merge returns True for any same-type pair, so adding a 7th delta variant without updating _merge_pair would silently drop `a`'s accumulated content. Asserting turns a future silent data-loss into an immediate, diagnosable crash. * test(streaming): add coalescing-layer tests; loosen one model assertion After merging the test-suite repair from main (#334) into this branch, one model test (test_responses_api_streaming) regressed because its assert_called_with strict-matched all kwargs of streaming_task_message_context and didn't tolerate the new `streaming_mode='coalesced'` kwarg this PR adds. Switched to assert_called() + targeted kwarg checks so the test verifies what it cares about (task_id threading) without locking in implementation details. Replaced the ad-hoc smoke scripts that lived in conversation with a real pytest module at tests/lib/core/services/adk/test_streaming.py covering: - _delta_char_len, _can_merge, _merge_pair: per-channel correctness + None-handling - _merge_consecutive: pure-text collapse, cross-channel order preservation, per-channel reconstruction matches per-token semantics - CoalescingBuffer: first-delta-immediate flush within ~20ms, size-threshold flush before timer fires, multi-delta coalescing within one window, idle close, add-after-close no-op - CoalescingBuffer cancel-during-flush regression test for the P1 fix: five queued chunks must all surface across publishes when close() cancels mid-flush (asserts substring presence rather than exact ordering, since the documented trade-off allows duplicates of the in-flight item) - StreamingTaskMessageContext mode dispatch: "off" suppresses publishes but persists full content, "per_token" publishes each delta synchronously, "coalesced" batches and persists full content * chore(streaming): route TemporalStreamingModel logger through make_logger The model file used raw ``logging.getLogger("agentex.temporal.streaming")``, which returns a logger with no handler attached and no level configured — so the existing ``[TemporalStreamingModel] Initialized ... streaming_mode=...`` INFO log was silently dropped, making it impossible to verify at runtime that a coalesced (or any) streaming mode was actually wired. Switch to the SDK's ``make_logger`` helper (level=INFO, RichHandler in local mode, StreamHandler otherwise) used everywhere else in the SDK. The explicit logger name ``agentex.temporal.streaming`` is preserved so any external logging configuration targeting that name keeps working. * codegen metadata * feat(api): api update * release: 0.10.3 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> Co-authored-by: Brandon Allen <brandon.allen@scale.com> Co-authored-by: Declan Brady <declan.brady@scale.com> Co-authored-by: Stas Moreinis <stas.moreinis@scale.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR updates
agentex-sdkon thenextbranch so downstream repos can consume a0.10.3release that resolves the dependency blockers currently preventing security remediation.The original blocker was
agentex-sdk==0.10.2requiringhttpx>=0.27.2,<0.28, while patchedlitellm>=1.83.7requireshttpx==0.28.1. This PR relaxes the SDK bound and raises thelitellmfloor so downstream consumers can upgrade without dependency conflicts.While reviewing older security work, I also found PR #289 was never merged. I ported the still-relevant pieces from that PR into this current
next-based branch instead of cherry-picking it wholesale, because #289 was based on older code and would revert/remove a lot of currentnextwork.What Changed
Dependency and security remediation
httpxfrom>=0.27.2,<0.28to>=0.28.1,<0.29.litellmfrom>=1.83.0,<2to>=1.83.7,<2.fastapi<0.116cap so the resolver can select patched Starlette-compatible FastAPI releases.starlette>=0.49.1floor for CVE-2025-62727 remediation.tornado>=6.5.5floor for CVE-2026-31958 remediation.uv.lockfrom the currentnextbranch.Resolved package versions in the lockfile:
httpx0.27.20.28.1litellmlitellm1.83.01.83.7fastapi0.115.140.136.1starlette0.46.21.0.0tornado6.5.26.5.5Runtime compatibility fixes carried forward from #289
RequestIDMiddleware'sBaseHTTPMiddlewareimplementation with pure ASGI middleware.BaseHTTPMiddlewarestreaming-response buffering/loss behavior, which matters now that Starlette can resolve to newer versions.send_messageto consume message responses via streaming response handling.SendMessageStreamResponse.resultoptional.result: null; validating those as required caused client-side failures.workflow.execute_activity_methodtoworkflow.execute_activity.execute_activityis the public API path used by the current Temporal SDK.SDK tracing surface fix
task_idto the generated span model, create/update params, span resource methods, and Agentex tracing processor calls.task_id, but the generated span types/resources did not expose it. CI surfaced this as pyright errors after dependency resolution started matching the declaredpyproject.tomldependencies.What Was Not Ported From #289
I did not merge #289 wholesale. That branch was based on older
main/pre-nextstate and includes broad generated-code churn, tutorial changes, and reversions that do not apply cleanly to currentnext. This PR only carries forward the still-relevant security and runtime compatibility fixes.Validation
Local validation:
uv lock --checkuv run --with ruff ruff check .uv run --with pyright==1.1.399 --with nox --with respx --with dirty-equals --with httpx-aiohttp --with claude-agent-sdk==0.1.52 pyrightuv builduv run --with pytest-xdist --with respx --with dirty-equals pytest724 passed, 961 skippedGitHub CI after the latest push:
lint: passedbuild: passedtest: passedNote:
ryeis not installed locally, so local validation useduvequivalents with the same pinned pyright version and CI-resolved dev packages.Greptile Summary
This PR unblocks security dependency patches by relaxing
httpxandfastapibounds, raising thelitellmfloor, and adding explicitstarletteandtornadofloors to address two CVEs. It also ports runtime compatibility fixes from the never-merged PR #289 — replacingBaseHTTPMiddlewarewith pure ASGI middleware, switchingsend_messageto streaming-response parsing, makingSendMessageStreamResponse.resultoptional, migrating Temporal hooks toworkflow.execute_activity, and surfacingtask_idacross the span types/resources/processor.Confidence Score: 5/5
Safe to merge — all findings are P2 style/robustness suggestions with no blocking correctness issues.
The dependency updates are well-justified and the lockfile has been regenerated. The ASGI middleware rewrite, Temporal API migration, and span field additions are all correct. The only non-trivial behaviour change is the streaming-based send_message implementation, which is logically sound; the one flagged concern (silent empty-stream fallback) is a robustness improvement suggestion, not a blocking bug. CI (lint, build, test, tutorials) passes.
src/agentex/resources/agents.py — review the empty-stream fallback behaviour in the new send_message streaming implementation.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[send_message called] --> B{agent_id or agent_name?} B -->|agent_id| C[with_streaming_response.rpc] B -->|agent_name| D[with_streaming_response.rpc_by_name] B -->|neither| E[raise ValueError] C --> F[Open streaming context] D --> F F --> G[iter_lines] G --> H{line empty?} H -->|yes| G H -->|no| I[Strip data: prefix if SSE] I --> J[json.loads line] J --> K{Validate as SendMessageResponse?} K -->|success| L[return immediately] K -->|ValidationError| M[Validate as SendMessageStreamResponse] M --> N{result.type == full?} N -->|yes| O[append parent_task_message] N -->|no| G O --> G M -->|ValidationError| G J -->|JSONDecodeError| G G -->|stream exhausted| P[return SendMessageResponse id jsonrpc result=task_messages]Prompt To Fix All With AI
Reviews (4): Last reviewed commit: "fix: allow litellm security patch" | Re-trigger Greptile