Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 3 deletions temporalio/contrib/google_adk_agents/workflow.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Workflow utilities for Google ADK agents integration with Temporal."""

import functools
import inspect
from typing import Any, Callable

Expand All @@ -18,6 +19,7 @@ def activity_tool(activity_def: Callable, **kwargs: Any) -> Callable:
while marking it as a tool that executes via 'workflow.execute_activity'.
"""

@functools.wraps(activity_def)
async def wrapper(*args: Any, **kw: Any):
# Inspect signature to bind arguments
sig = inspect.signature(activity_def)
Expand Down Expand Up @@ -48,9 +50,8 @@ async def wrapper(*args: Any, **kw: Any):
activity_def, args=activity_args, **options
)

# Copy metadata
wrapper.__name__ = activity_def.__name__
wrapper.__doc__ = activity_def.__doc__
# functools.wraps copies name/doc/module/annotations/qualname/dict.
# Signature must be set explicitly since the wrapper uses *args/**kw.
setattr(wrapper, "__signature__", inspect.signature(activity_def))

return wrapper
39 changes: 39 additions & 0 deletions tests/contrib/google_adk_agents/test_google_adk_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""Integration tests for ADK Temporal support."""

import inspect
import json
import logging
import os
Expand Down Expand Up @@ -1119,3 +1120,41 @@ def test_explicitly_set_none_preserved() -> None:

assert "cache_config" in serialized, "Explicitly-set None should be preserved"
assert serialized["cache_config"] is None


def test_activity_tool_preserves_metadata() -> None:
"""activity_tool wrapper preserves the original function's metadata.

This ensures ADK's tool schema generation can inspect __annotations__
and __module__ on the wrapper, which are needed by
``_handle_params_as_deferred_annotations`` to resolve type hints.
"""

@activity.defn
async def my_activity(city: str, count: int = 1) -> str:
"""Get info for a city."""
return f"{city}: {count}"

tool = temporalio.contrib.google_adk_agents.workflow.activity_tool(
my_activity, start_to_close_timeout=timedelta(seconds=30)
)

# __name__ and __doc__
assert tool.__name__ == "my_activity"
assert tool.__doc__ == "Get info for a city."

# __annotations__ — critical for ADK type introspection
assert "city" in tool.__annotations__
assert tool.__annotations__["city"] is str
assert tool.__annotations__["count"] is int
assert tool.__annotations__["return"] is str

# __module__ — needed by _handle_params_as_deferred_annotations
assert tool.__module__ == my_activity.__module__

# __signature__ — must match the original, not *args/**kw
sig = inspect.signature(tool)
params = list(sig.parameters.keys())
assert params == ["city", "count"]
assert sig.parameters["city"].annotation is str
assert sig.parameters["count"].default == 1
Loading