Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
e8458de
Bump ruff to 0.15 and reformat
brianstrauch May 8, 2026
cc43197
contrib/strands: add Strands Agents plugin
brianstrauch May 12, 2026
91ac3fe
contrib/strands: split activity helper into _TemporalActivityTool
brianstrauch May 12, 2026
1c7ad3a
contrib/strands: import strands_tools at module level in wrapper
brianstrauch May 12, 2026
e8e7810
contrib/strands: run models as activities via TemporalModel
brianstrauch May 12, 2026
b828b31
contrib/strands: patch Agent.__init__ to route models through activities
brianstrauch May 13, 2026
acd767d
contrib/strands: explicit TemporalModel/TemporalMCPClient, drop monke…
brianstrauch May 13, 2026
160bed0
contrib/strands: rewrite README, default TemporalModel to BedrockModel
brianstrauch May 13, 2026
d759fa6
contrib/strands: show worker activity registration in Tools snippet
brianstrauch May 13, 2026
f29728e
contrib/strands: add activity_as_hook helper, document Hooks
brianstrauch May 14, 2026
58cba6d
contrib/strands: rename activity_as_hook extract to activity_input
brianstrauch May 14, 2026
12cc311
contrib/strands: document HITL interrupts, add integration test
brianstrauch May 14, 2026
9d6e68a
contrib/strands: document continue-as-new for long chats
brianstrauch May 14, 2026
5702606
contrib/strands: document OpenTelemetryPlugin compatibility
brianstrauch May 14, 2026
bba6b67
contrib/strands: fix lint warnings and add missing docstrings
brianstrauch May 14, 2026
81870af
disable tiktoken and other sandbox warnings
brianstrauch May 15, 2026
5be969f
contrib/strands: disable Strands retries, route via Temporal RetryPolicy
brianstrauch May 15, 2026
09ebad7
contrib/strands: move activity_as_tool/hook under workflow.* submodule
brianstrauch May 15, 2026
d9ffbd1
contrib/strands: disable Agent.take_snapshot/load_snapshot
brianstrauch May 18, 2026
28a6e8f
contrib/strands: add CODEOWNERS entries
brianstrauch May 18, 2026
9997120
Merge remote-tracking branch 'origin/main' into strands
brianstrauch May 18, 2026
d6fdf3e
contrib/strands: type _InvokeModelInput fields as Any
brianstrauch May 18, 2026
45c6c5a
contrib/common: extract _heartbeat_decorator for cross-plugin use
brianstrauch May 18, 2026
8ab32a7
contrib/strands: auto-heartbeat model activities, loosen input types
brianstrauch May 18, 2026
36ec764
contrib/strands: clarify tiktoken comment
brianstrauch May 18, 2026
d8c52c1
contrib/common: drop leading underscore from auto_heartbeater
brianstrauch May 18, 2026
4c8681d
contrib/strands: drop redundant passthrough entries
brianstrauch May 18, 2026
06b6012
contrib/strands: support multiple models and MCP servers per worker
brianstrauch May 19, 2026
f078cd1
contrib/strands: introduce TemporalAgent, drop Agent monkey-patches
brianstrauch May 19, 2026
34b4017
contrib/strands: register OpenTelemetryPlugin on the client in the RE…
brianstrauch May 19, 2026
95159e2
contrib/strands: set max_cached_workflows=0 in tests
brianstrauch May 19, 2026
71c4f68
contrib/strands: appease poe lint
brianstrauch May 19, 2026
300fdc5
contrib/strands: propagate InterruptException across activity boundary
brianstrauch May 19, 2026
e6f7b02
contrib/strands: forward invocation_state; default StrandsPlugin to B…
brianstrauch May 19, 2026
efc6fe7
contrib/strands: gate implicit model resolution behind the plugin def…
brianstrauch May 19, 2026
c650265
contrib/strands: mark terminal Strands exceptions non-retryable
brianstrauch May 19, 2026
15a9ab3
contrib/strands: accept MCPClient factories in mcp_clients
brianstrauch May 20, 2026
ff60a79
contrib/strands: drop _get_encoding monkey patch
brianstrauch May 20, 2026
67ecb64
contrib/strands: swap current_time for shell in demos and tests
brianstrauch May 20, 2026
17cc14f
contrib/strands: ruff format populate_cache signature
brianstrauch May 20, 2026
bb8d7c3
contrib/strands: switch test_structured_output to TemporalAgent
brianstrauch May 20, 2026
a144273
Merge remote-tracking branch 'origin/main' into strands
brianstrauch May 20, 2026
2b54db9
contrib/strands: rename optional dependency to strands-agents
brianstrauch May 21, 2026
e083d8e
contrib/strands: fix pydoctor docstring errors
brianstrauch May 21, 2026
cc724b2
tests: fix Windows test collection failures
brianstrauch May 21, 2026
ca173ee
tests/contrib/strands: swap shell tool for file_read
brianstrauch May 21, 2026
c84320c
Fix Strands MCP client on Python 3.10
brianstrauch May 22, 2026
c9027be
Merge remote-tracking branch 'origin/main' into strands
brianstrauch May 22, 2026
a4636e4
contrib: inline _heartbeat_decorator into strands and openai_agents
brianstrauch May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@


# Below are owners for modules in the temporalio/contrib/
# and tests/contrib/ directories that are owned by teams
# other than the SDK team. For each one, we add the owning team,
# and tests/contrib/ directories that are owned by teams
# other than the SDK team. For each one, we add the owning team,
# as well as @temporalio/sdk, so the SDK team can continue to
# manage repo-wide concerns.
/temporalio/contrib/common/ @temporalio/ai-sdk @temporalio/sdk
/temporalio/contrib/google_adk_agents/ @temporalio/ai-sdk @temporalio/sdk
/temporalio/contrib/langsmith/ @temporalio/ai-sdk @temporalio/sdk
/temporalio/contrib/openai_agents/ @temporalio/ai-sdk @temporalio/sdk
/temporalio/contrib/strands/ @temporalio/ai-sdk @temporalio/sdk
/tests/contrib/google_adk_agents/ @temporalio/ai-sdk @temporalio/sdk
/tests/contrib/langsmith/ @temporalio/ai-sdk @temporalio/sdk
/tests/contrib/openai_agents/ @temporalio/ai-sdk @temporalio/sdk
/tests/contrib/strands/ @temporalio/ai-sdk @temporalio/sdk
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ lambda-worker-otel = [
"opentelemetry-sdk-extension-aws>=2.0.0,<3",
]
aioboto3 = ["aioboto3>=10.4.0", "types-aioboto3[s3]>=10.4.0"]
strands-agents = ["strands-agents>=1.39.0"]

[project.urls]
Homepage = "https://github.com/temporalio/sdk-python"
Expand Down Expand Up @@ -85,6 +86,8 @@ dev = [
"opentelemetry-sdk-extension-aws>=2.0.0,<3",
"pytest-flakefinder>=1.1.0",
"async-timeout>=4.0,<6; python_version < '3.11'",
"strands-agents>=1.39.0",
"strands-agents-tools>=0.5.2",
]

[tool.poe.tasks]
Expand Down
14 changes: 6 additions & 8 deletions temporalio/contrib/openai_agents/_heartbeat_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,22 @@
F = TypeVar("F", bound=Callable[..., Awaitable[Any]])


def _auto_heartbeater(fn: F) -> F: # type:ignore[reportUnusedClass]
# Propagate type hints from the original callable.
def auto_heartbeater(fn: F) -> F:
"""Decorator that heartbeats at half the activity's heartbeat timeout."""

@wraps(fn)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
heartbeat_timeout = activity.info().heartbeat_timeout
heartbeat_task = None
if heartbeat_timeout:
# Heartbeat twice as often as the timeout
heartbeat_task = asyncio.create_task(
heartbeat_every(heartbeat_timeout.total_seconds() / 2)
_heartbeat_every(heartbeat_timeout.total_seconds() / 2)
)
try:
return await fn(*args, **kwargs)
finally:
if heartbeat_task:
heartbeat_task.cancel()
# Wait for heartbeat cancellation to complete
try:
await heartbeat_task
except asyncio.CancelledError:
Expand All @@ -33,8 +32,7 @@ async def wrapper(*args: Any, **kwargs: Any) -> Any:
return cast(F, wrapper)


async def heartbeat_every(delay: float, *details: Any) -> None:
"""Heartbeat every so often while not cancelled"""
async def _heartbeat_every(delay: float) -> None:
while True:
await asyncio.sleep(delay)
activity.heartbeat(*details)
activity.heartbeat()
8 changes: 4 additions & 4 deletions temporalio/contrib/openai_agents/_invoke_model_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from typing_extensions import Required, TypedDict

from temporalio import activity
from temporalio.contrib.openai_agents._heartbeat_decorator import _auto_heartbeater
from temporalio.contrib.openai_agents._heartbeat_decorator import auto_heartbeater
from temporalio.contrib.workflow_streams import WorkflowStreamClient
from temporalio.exceptions import ApplicationError

Expand Down Expand Up @@ -314,7 +314,7 @@ def __init__(self, model_provider: ModelProvider | None = None):
)

@activity.defn
@_auto_heartbeater
@auto_heartbeater
async def invoke_model_activity(self, input: ActivityModelInput) -> ModelResponse:
"""Activity that invokes a model with the given input."""
model = self._model_provider.get_model(input.get("model_name"))
Expand All @@ -337,7 +337,7 @@ async def invoke_model_activity(self, input: ActivityModelInput) -> ModelRespons
_raise_for_openai_status(e)

@activity.defn
@_auto_heartbeater
@auto_heartbeater
async def invoke_model_activity_streaming(
self, input: StreamingActivityModelInput
) -> list[TResponseStreamEvent]:
Expand All @@ -357,7 +357,7 @@ async def invoke_model_activity_streaming(
``streaming_topic`` so external consumers (UIs, tracing,
etc.) can observe events as they arrive.

Heartbeats run on a background task via ``_auto_heartbeater`` so
Heartbeats run on a background task via ``auto_heartbeater`` so
long initial-token latency or long pauses between chunks do not
trip ``heartbeat_timeout``.
"""
Expand Down
Loading
Loading