Skip to content

Commit 73ecf8d

Browse files
chengxin-wangcopybara-github
authored andcommitted
feat: Pass invocation_id to _setup_invocation_context
PiperOrigin-RevId: 934183388
1 parent a7377b4 commit 73ecf8d

2 files changed

Lines changed: 51 additions & 4 deletions

File tree

src/google/adk/runners.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ def __init__(
192192
Args:
193193
app: An `App` instance. Mutually exclusive with `agent` and `node`.
194194
app_name: The application name. Required when `agent` is provided.
195-
Optional override for `app.name` when `app` is provided. Defaults
196-
to `node.name` when only `node` is provided.
195+
Optional override for `app.name` when `app` is provided. Defaults to
196+
`node.name` when only `node` is provided.
197197
agent: The root agent to run. Mutually exclusive with `app` and `node`.
198198
node: The root node to run. Mutually exclusive with `app` and `agent`.
199199
plugins: Deprecated. A list of plugins for the runner. Please use the
@@ -203,8 +203,8 @@ def __init__(
203203
memory_service: The memory service for the runner.
204204
credential_service: The credential service for the runner.
205205
plugin_close_timeout: The timeout in seconds for plugin close methods.
206-
auto_create_session: Whether to automatically create a session when
207-
not found. Defaults to False. If False, a missing session raises
206+
auto_create_session: Whether to automatically create a session when not
207+
found. Defaults to False. If False, a missing session raises
208208
ValueError with a helpful message.
209209
210210
Raises:
@@ -1071,6 +1071,7 @@ async def _run_with_trace(
10711071
new_message=new_message,
10721072
run_config=run_config,
10731073
state_delta=state_delta,
1074+
invocation_id=invocation_id,
10741075
)
10751076
else:
10761077
invocation_id = self._resolve_invocation_id(
@@ -1833,6 +1834,7 @@ async def _setup_context_for_new_invocation(
18331834
new_message: types.Content,
18341835
run_config: RunConfig,
18351836
state_delta: Optional[dict[str, Any]],
1837+
invocation_id: Optional[str] = None,
18361838
) -> InvocationContext:
18371839
"""Sets up the context for a new invocation.
18381840
@@ -1841,6 +1843,7 @@ async def _setup_context_for_new_invocation(
18411843
new_message: The new message to process and append to the session.
18421844
run_config: The run config of the agent.
18431845
state_delta: Optional state changes to apply to the session.
1846+
invocation_id: Optional invocation identifier.
18441847
18451848
Returns:
18461849
The invocation context for the new invocation.
@@ -1850,6 +1853,7 @@ async def _setup_context_for_new_invocation(
18501853
session,
18511854
new_message=new_message,
18521855
run_config=run_config,
1856+
invocation_id=invocation_id,
18531857
)
18541858
# Step 2: Handle new message, by running callbacks and appending to
18551859
# session.

tests/unittests/test_runners.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from contextlib import aclosing
1516
import importlib
1617
from pathlib import Path
1718
import sys
@@ -763,6 +764,48 @@ def test_run_passes_state_delta():
763764
assert user_event.actions.state_delta == state_delta
764765

765766

767+
@pytest.mark.asyncio
768+
async def test_run_async_propagates_invocation_id():
769+
"""run_async should propagate invocation_id to the invocation context and events."""
770+
771+
session_service = InMemorySessionService()
772+
runner = Runner(
773+
app_name=TEST_APP_ID,
774+
agent=MockAgent("test_agent"),
775+
session_service=session_service,
776+
artifact_service=InMemoryArtifactService(),
777+
auto_create_session=True,
778+
)
779+
780+
custom_invocation_id = "my_custom_invocation_id"
781+
782+
agen = runner.run_async(
783+
user_id=TEST_USER_ID,
784+
session_id=TEST_SESSION_ID,
785+
new_message=types.Content(role="user", parts=[types.Part(text="hello")]),
786+
invocation_id=custom_invocation_id,
787+
)
788+
789+
events = []
790+
async with aclosing(agen) as a:
791+
async for event in a:
792+
events.append(event)
793+
794+
assert len(events) >= 1
795+
# Verify yielded events have the custom invocation ID
796+
for event in events:
797+
assert event.invocation_id == custom_invocation_id
798+
799+
# Verify the session has the custom invocation ID in its events
800+
session = await session_service.get_session(
801+
app_name=TEST_APP_ID, user_id=TEST_USER_ID, session_id=TEST_SESSION_ID
802+
)
803+
assert session is not None
804+
assert len(session.events) == 2
805+
for event in session.events:
806+
assert event.invocation_id == custom_invocation_id
807+
808+
766809
@pytest.mark.asyncio
767810
async def test_run_live_persists_event_callback_modifications():
768811
"""run_live should persist the same event it streams after callback changes."""

0 commit comments

Comments
 (0)