Skip to content

release: 0.11.2#357

Merged
declan-scale merged 2 commits into
mainfrom
release-please--branches--main--changes--next
May 13, 2026
Merged

release: 0.11.2#357
declan-scale merged 2 commits into
mainfrom
release-please--branches--main--changes--next

Conversation

@stainless-app
Copy link
Copy Markdown
Contributor

@stainless-app stainless-app Bot commented May 13, 2026

Automated Release PR

0.11.2 (2026-05-13)

Full Changelog: v0.11.1...v0.11.2

Bug Fixes

  • messages: stamp agent messages with workflow.now() for monotonic ordering (#356) (afe5265)

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: TaskMessage
Loading

Fix All in Cursor Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
examples/tutorials/10_async/00_base/010_multiturn/tests/test_agent.py:148
**Brittle sleep-based synchronization**

`asyncio.sleep(1)` is a hardcoded delay that can still race in slow CI environments and wastes a full second in fast ones. A retry loop polling `client.states.list` until `len(states) >= 1` (with a short timeout) would be more deterministic and faster.

Reviews (1): Last reviewed commit: "release: 0.11.2" | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@declan-scale declan-scale merged commit 795424c into main May 13, 2026
41 checks passed
@declan-scale declan-scale deleted the release-please--branches--main--changes--next branch May 13, 2026 20:47
@stainless-app
Copy link
Copy Markdown
Contributor Author

stainless-app Bot commented May 13, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant