Fixes#423
Related to #1670
- This avoids the `GeneratorExit` error thrown, which would crash OTel metric collection and cause `Failed to detach context` error.
- This also allows all function calls are processed when exit_loop is called together with other tools in the same LLmResponse.
A sample agent for testing:
```
from google.adk import Agent
from google.adk.agents.loop_agent import LoopAgent
from google.adk.tools.exit_loop_tool import exit_loop
worker_1 = Agent(
name='worker_1',
description='Worker 1',
instruction="""\
Just say job #1 is done.
If job #1 is said to be done. Call exit_loop tool.""",
tools=[exit_loop],
)
worker_2 = Agent(
name='worker_2',
description='Worker 2',
instruction="""\
Just say job #2 is done.
If job #2 is said to be done. Call exit_loop tool.""",
tools=[exit_loop],
)
work_agent = LoopAgent(
name='work_agent',
description='Do all work.',
sub_agents=[worker_1, worker_2],
max_iterations=5,
)
root_agent = Agent(
model='gemini-2.0-flash',
name='hello_world_agent',
description='hello world agent that can roll a check prime',
instruction="""Hand off works to sub agents.""",
sub_agents=[work_agent],
)
```
PiperOrigin-RevId: 785538101
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
This would allow users to easily make a copy of the agents they built without having to add too much boilerplates. This promotes code reuse, modularity and testability of agents.
PiperOrigin-RevId: 781214379
Bug: When a model emits a stream of tokens, it sometimes emits a final chunk of whitespace or no content. The agent was trying to parse that content into JSON, causing a validation error.
Fix: If a model is expected to return JSON and the last streamed token is empty/whitespace, the agent will no longer try to parse it, and exit gracefully.
New unit tests confirm the scenario and the fix.
PiperOrigin-RevId: 777609415
When the user provides instruction provider, we assume that they will inject the session state parameters if needed. This assumption allows users to return code snippets in the instruction provider without any template replacement.
PiperOrigin-RevId: 759705471
Copybara import of the project:
--
ade1d98e030a966183f56cb5c9c1b04cf51f5337 by Thiago Neves <thiagohneves@gmail.com>:
fix(tests): use mock GCS client in artifact service tests to avoid real credentials
--
becd2925feebf60196129b029a0ab8d490f7b19e by Thiago Neves <thiagohneves@gmail.com>:
test(agents): add unit tests for live_request_queue, readonly_context, and run_config
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/641 from thiagoneves:feature/increase-test-coverage 0f7a9fc55d97902e190a394f099324fbeb1541af
PiperOrigin-RevId: 756798390
(before/after) agent callbacks are invoked throughout the provided chain until one callback does not return None. Callbacks can be async and sync.
PiperOrigin-RevId: 756359693
(before/after) model callbacks are invoked throughout the provided chain until one callback does not return None. Callbacks can be async and sync.
PiperOrigin-RevId: 755565583