When one agent hands off to another, `_present_other_agent_message` replays the
first agent's turn to the second as a `role="user"` message -- the same channel
the real user speaks on -- interpolating the text straight into
`[agent] said: ...`. Nothing marks where the quoted transcript ends, so a
payload the first agent was talked into emitting reads to the second agent as a
fresh directive. Anyone who can chat to a low-privilege front-end agent can
therefore aim instructions at whatever tools the agent it transfers to holds.
Every relayed payload -- text, thoughts, tool arguments, tool results -- is now
quoted between explicit markers, and the leading part of the message states
that what sits between them is data to read and not instructions to follow.
Markers occurring inside a payload are elided first, so quoted content cannot
close its own block and carry on speaking as the framework.
The markers, the preamble and the quoting helpers live in
`flows/llm_flows/_fencing.py`. The unit tests and the conformance harness both
have to spell the expected framing, so it sits in a module of its own rather
than inside `contents.py`, where they would have to reach for private names.
This raises the bar rather than closing the class: a model can still be talked
round by text it was told to distrust. What it removes is the structural
ambiguity that made a relayed payload indistinguishable from a user turn.
Relayed turns now cost the preamble plus two marker lines per part, and
anything matching on the old `For context: [x] said: y` shape needs updating.
The conformance replay harness is one such matcher, and now reduces a relayed
turn to the payload it carries before comparing, so recordings cut before the
fencing still replay.
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 966694665
The basic and output-schema request processors now read
`model.capabilities.output_schema_and_tools` instead of inferring support from
the model name. A `BaseLlm` subclass that declares the capability is honored,
which previously it was not: support was derived from the model id and backend
variant regardless of what the model reported.
Built-in models are unaffected. `Gemini` and `LiteLlm` already self-report, and
any model that does not falls through to the deprecated name-based fallback on
`BaseLlm`, which reproduces the previous answer and warns.
`utils/output_schema_utils.can_use_output_schema_with_tools()` is marked
deprecated. Its body is unchanged and it keeps working; it cannot honor
capabilities declared by a subclass, so callers should read the model instead.
Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 960515327
- Wrap run_live generator in aclosing/Aclosing in InMemoryRunner and test runners to ensure they are closed when tests exit early.
- Refactor test_streaming.py to use a single, robust TestRunner helper, eliminating 10 duplicated CustomTestRunner definitions.
- Implement close() and async context manager support directly in PerAgentDatabaseSessionService in local_storage.py to clean up SQLAlchemy engines and connection threads without changing BaseSessionService.
- Wrap PerAgentDatabaseSessionService in async with blocks (or try-finally) in test_local_storage.py to ensure they are closed.
Co-authored-by: Shangjie Chen <deanchen@google.com>
PiperOrigin-RevId: 936950444
gen_ai.client.operation.duration and gen_ai.client.token.usage already
exist in OTel semconv
(https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/),
and are currently emitted by
https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-google-genai,
if configured. However, they have no agentic attributes.
This change builds on top of the recently introduced metric
instrumentation and emits those two metrics a new attribute:
gen_ai.agent.name. In the future, gen_ai.agent.version will also be set.
Semconv updates will be handled separately.
When the google-genai instrumentation lib is active for a Gemini agent,
we don't re-emit the gen_ai.client.* metrics to avoid double-counting.
Change-Id: Ie610d25ca44671d3a31d4307ebf068a1c9deeaab
This includes:
- Test verifying multiple spans are written during E2E runner execution.
- Regression tests for the "ContextVar was created in a different Context" exceptions caused by the interplay of context based instrumentation and async generators getting indeterminately suspended.
PiperOrigin-RevId: 804333483
This commit adds support for the session resumption configuration in the run_config.
The SessionResumptionConfig is added to RunConfig to allow the user to set up a configuration for session resumption(only transparent mode for now).
There are two modes of session resumption: manual and transparent. In manual mode, you have to manually bookkeeping the session information and restarts the session which is tricky to do right now. In transparent mode, the server does the bookkeeping for you and no hassle on ADK side. For now, the transparent mode should be enough.
Also, added the relevant unit tests to check that every possible configuration is set properly and the run_config is correctly populated.
This is needed for supporting the new session resumption feature.
PiperOrigin-RevId: 786549455
This CL add new callbacks in plugin system:
- `on_tool_error_callback`
- `on_model_error_callback`
This allow the user to create plugins that can handle errors.
PiperOrigin-RevId: 786469646
This change integrates the plugin system with ADK. PluginManager is attached to the invocation context similar to session/artifact/memory.
It includes integrations with following ADK internal callbacks:
* App callbacks: Integrated in the BaseRunner class, in run_async and run_live
* On Message callbacks: Integrated in the BaseRunner class, triggers on run_async.
* Agent callbacks: Integrated in the BaseAgent class. Leveraging the existing *callback functions
* Model callbacks: Integrating in the base_llm_flow.
* Tool callbacks: Integrated in functions.py, wrapped around the code for agent tool_callbacks
Sample code to use plugins:
```python
# Add plugins to Runner
runner = Runner(
app_name="my-app",
agent=root_agent,
artifact_service=artifact_service,
session_service=session_service,
memory_service=memory_service,
plugins=[
MySamplePlugin(),
LoggingPlugin(),
],
)
```
PiperOrigin-RevId: 781746586
Merge https://github.com/google/adk-python/pull/981
issue: https://github.com/google/adk-python/issues/982
This pull request introduces a new configuration option, `realtime_input_config`, to the `RunConfig` class.
**Reason for this change:**
Currently, there is no direct way to configure real-time audio input behaviors, such as Voice Activity Detection (VAD), for live agents through the `RunConfig`. The Gemini API documentation (specifically [Configure automatic VAD](https://ai.google.dev/gemini-api/docs/live#configure-automatic-vad)) outlines parameters for VAD that users may want to customize.
This change enables users to pass these real-time input configurations, providing more granular control over the audio input for live agents.
**Changes made:**
- Added a new optional field `realtime_input_config: Optional[types.RealtimeInputConfig]` to the `RunConfig` class.
- The docstring for `realtime_input_config` has been added to explain its purpose.
**Example Usage (Conceptual):**
While the specific structure of `types.RealtimeInputConfig` would define the exact parameters, a user might configure it like this:
```python
# (Assuming types.RealtimeInputConfig and types.VadConfig are defined elsewhere)
# import your_project.types as types
run_config = RunConfig(
# ... other configurations ...
realtime_input_config=types.RealtimeInputConfig(
automatic_activity_detection =types.AutomaticActivityDetection(
# VAD specific parameters like sensitivity, endpoint_duration_millis etc.
# based on https://ai.google.dev/gemini-api/docs/live#configure-automatic-vad
)
# Potentially other real-time input settings could be added here in the future
)
)
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/981 from ammmr:patch-add-realtime-input-config b2e17fbf5742d264029ad49bf632422b5c5b1e0a
PiperOrigin-RevId: 770797640
--
73826d258b136f92a8da8171f7dc14d5f07de8dd by Calvin Giles <calvin.giles@trademe.co.nz>:
fix: Enable InMemoryRunner to be used in async tests
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/868 from calvingiles:enable-test-runner-in-async fb9033ed6f350a3114859715cae51798f864ecf6
PiperOrigin-RevId: 763233472