0.11.2 (2026-05-13)
Full Changelog: v0.11.1...v0.11.2
Bug Fixes
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
This release (v0.11.2) fixes a message-ordering bug by stamping agent messages with workflow.now() when created inside a Temporal workflow, ensuring monotonically increasing created_at values even when two messages.create calls are awaited in quick succession from the same workflow turn. The created_at is captured at the workflow layer before activity dispatch and threaded through the entire stack — activity params, services, streaming contexts, and the SDK client — using an omit sentinel when no explicit timestamp is needed.
Confidence Score: 4/5
Safe to merge — only P2 findings, no logic errors or security concerns.
The core bug fix is well-structured and correctly captures workflow.now() at the workflow layer before activity dispatch. The _make_created_at_dispenser pattern in openai.py correctly limits the workflow timestamp to the first message per turn. Tests adequately cover the new behaviour. The only concern is the asyncio.sleep(1) in the integration test, which is a P2 style issue.
examples/tutorials/10_async/00_base/010_multiturn/tests/test_agent.py — brittle sleep-based synchronization worth revisiting.
Important Files Changed
| Filename | Overview |
|---|---|
| src/agentex/lib/utils/temporal.py | Adds workflow_now_if_in_workflow() — returns deterministic workflow.now() inside a Temporal workflow, None otherwise. Clean implementation. |
| src/agentex/lib/adk/_modules/messages.py | Auto-injects workflow_now_if_in_workflow() as created_at default in create() and create_batch(), threading the timestamp through both the activity-dispatch and direct-service paths. |
| src/agentex/lib/core/services/adk/providers/openai.py | Introduces _make_created_at_dispenser to stamp only the first streaming context opened per turn with the workflow timestamp; subsequent messages fall back to server wall-clock. Implementation is correct and well-commented. |
| src/agentex/lib/core/services/adk/streaming.py | Propagates created_at through StreamingTaskMessageContext and uses omit sentinel when None to let the server apply its own clock. Mostly formatting-only changes otherwise. |
| src/agentex/lib/core/temporal/activities/adk/messages_activities.py | Adds `created_at: datetime |
| examples/tutorials/10_async/00_base/010_multiturn/tests/test_agent.py | Adds asyncio.sleep(1) to work around a race between task creation and state initialization; brittle in slow CI environments. |
| tests/lib/adk/test_messages_module.py | New tests covering workflow/non-workflow created_at injection for MessagesModule.create and create_batch. Patch targets are correct. |
| tests/lib/adk/test_messages_service.py | Tests forwarding of created_at to SDK client and omit sentinel when None. Covers both single-message and batch paths. |
Sequence Diagram
sequenceDiagram
participant WF as Temporal Workflow
participant Mod as MessagesModule / LiteLLMModule / OpenAIModule
participant Act as Temporal Activity
participant Svc as MessagesService / OpenAIService
participant SDK as AgentEx SDK Client
WF->>Mod: messages.create(task_id, content)
Note over Mod: created_at = workflow_now_if_in_workflow()<br/>(captures deterministic workflow clock)
Mod->>Act: "execute_activity(CreateMessageParams{created_at})"
Note over Act: Runs outside workflow context
Act->>Svc: create_message(task_id, content, created_at)
Svc->>SDK: "messages.create(task_id, content, created_at=ts OR omit)"
SDK-->>Svc: TaskMessage
Svc-->>Act: TaskMessage
Act-->>Mod: TaskMessage
Mod-->>WF: TaskMessagePrompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.