You've already forked adk-python
mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f13a11e1dc | |||
| 131d39c3db | |||
| 12db84f5cd | |||
| dc3f60cc93 | |||
| 14e3802643 | |||
| ffbab4cf4e | |||
| b2b7f2d6aa | |||
| 3ad30a58f9 | |||
| 0ac35b23dc | |||
| 857de04deb | |||
| e15e19da05 | |||
| 0cc3d6d6d5 | |||
| b5f5df9fa8 | |||
| a12ae812d3 | |||
| 8eb1bdbc58 | |||
| 236f562cd2 | |||
| 4dd28a3970 | |||
| b2c45f8d91 | |||
| 5ac5129fb0 | |||
| c642f13f21 | |||
| a48a1a9e88 | |||
| a5ac1d5e14 | |||
| 0ec01956e8 |
@@ -39,6 +39,7 @@ LABEL_TO_OWNER = {
|
||||
"core": "Jacksunwei",
|
||||
"web": "wyf7107",
|
||||
"a2a": "seanzhou1023",
|
||||
"bq": "shobsi",
|
||||
}
|
||||
|
||||
LABEL_GUIDELINES = """
|
||||
@@ -63,6 +64,7 @@ LABEL_GUIDELINES = """
|
||||
sandbox, `agent_engine_id`). If the issue does not explicitly mention
|
||||
Agent Engine concepts, do not use this label—choose "core" instead.
|
||||
- "a2a": Agent-to-agent workflows, coordination logic, or A2A protocol.
|
||||
- "bq": BigQuery integration or general issues related to BigQuery.
|
||||
|
||||
When unsure between labels, prefer the most specific match. If a label
|
||||
cannot be assigned confidently, do not call the labeling tool.
|
||||
@@ -214,6 +216,7 @@ root_agent = Agent(
|
||||
- Use "agent engine" only when the issue clearly references Vertex AI Agent Engine deployment artifacts (for example `.agent_engine_config.json`, `ae_ignore`, `agent_engine_id`, or Agent Engine sandbox errors).
|
||||
- If it's about Model Context Protocol (e.g. MCP tool, MCP toolset, MCP session management etc.), label it with both "mcp" and "tools".
|
||||
- If it's about A2A integrations or workflows, label it with "a2a".
|
||||
- If it's about BigQuery integrations, label it with "bq".
|
||||
- If you can't find an appropriate labels for the issue, follow the previous instruction that starts with "IMPORTANT:".
|
||||
|
||||
Call the `add_label_and_owner_to_issue` tool to label the issue, which will also assign the issue to the owner of the label.
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Simple test script for Rewind Session agent."""
|
||||
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import agent
|
||||
from google.adk.agents.run_config import RunConfig
|
||||
from google.adk.cli.utils import logs
|
||||
from google.adk.events.event import Event
|
||||
from google.adk.runners import InMemoryRunner
|
||||
from google.genai import types
|
||||
|
||||
APP_NAME = "rewind_test_app"
|
||||
USER_ID = "test_user"
|
||||
|
||||
logs.setup_adk_logger(level=logging.ERROR)
|
||||
logging.getLogger("google_genai.types").setLevel(logging.ERROR)
|
||||
|
||||
|
||||
# ANSI color codes for terminal output
|
||||
COLOR_RED = "\x1b[31m"
|
||||
COLOR_BLUE = "\x1b[34m"
|
||||
COLOR_YELLOW = "\x1b[33m"
|
||||
COLOR_BOLD = "\x1b[1m"
|
||||
RESET = "\x1b[0m"
|
||||
|
||||
|
||||
def highlight(text: str) -> str:
|
||||
"""Adds color highlights to tool responses and agent text."""
|
||||
text = str(text)
|
||||
return (
|
||||
text.replace("'red'", f"'{COLOR_RED}red{RESET}'")
|
||||
.replace('"red"', f'"{COLOR_RED}red{RESET}"')
|
||||
.replace("'blue'", f"'{COLOR_BLUE}blue{RESET}'")
|
||||
.replace('"blue"', f'"{COLOR_BLUE}blue{RESET}"')
|
||||
.replace("'version1'", f"'{COLOR_BOLD}{COLOR_YELLOW}version1{RESET}'")
|
||||
.replace("'version2'", f"'{COLOR_BOLD}{COLOR_YELLOW}version2{RESET}'")
|
||||
)
|
||||
|
||||
|
||||
async def call_agent_async(
|
||||
runner: InMemoryRunner, user_id: str, session_id: str, prompt: str
|
||||
) -> list[Event]:
|
||||
"""Helper function to call the agent and return events."""
|
||||
print(f"\n👤 User: {prompt}")
|
||||
content = types.Content(
|
||||
role="user", parts=[types.Part.from_text(text=prompt)]
|
||||
)
|
||||
events = []
|
||||
try:
|
||||
async for event in runner.run_async(
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
new_message=content,
|
||||
run_config=RunConfig(),
|
||||
):
|
||||
events.append(event)
|
||||
if event.content and event.author and event.author != "user":
|
||||
for part in event.content.parts:
|
||||
if part.text:
|
||||
print(f" 🤖 Agent: {highlight(part.text)}")
|
||||
elif part.function_call:
|
||||
print(f" 🛠️ Tool Call: {part.function_call.name}")
|
||||
elif part.function_response:
|
||||
print(
|
||||
" 📦 Tool Response:"
|
||||
f" {highlight(part.function_response.response)}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"❌ Error during agent call: {e}")
|
||||
raise
|
||||
return events
|
||||
|
||||
|
||||
async def main():
|
||||
"""Demonstrates session rewind."""
|
||||
print("🚀 Testing Rewind Session Feature")
|
||||
print("=" * 50)
|
||||
|
||||
runner = InMemoryRunner(
|
||||
agent=agent.root_agent,
|
||||
app_name=APP_NAME,
|
||||
)
|
||||
|
||||
# Create a session
|
||||
session = await runner.session_service.create_session(
|
||||
app_name=APP_NAME, user_id=USER_ID
|
||||
)
|
||||
print(f"Created session: {session.id}")
|
||||
|
||||
# 1. Initial agent calls to set state and artifact
|
||||
print("\n\n===== INITIALIZING STATE AND ARTIFACT =====")
|
||||
await call_agent_async(
|
||||
runner, USER_ID, session.id, "set state `color` to red"
|
||||
)
|
||||
await call_agent_async(
|
||||
runner, USER_ID, session.id, "save artifact file1 with content version1"
|
||||
)
|
||||
|
||||
# 2. Check current state and artifact
|
||||
print("\n\n===== STATE BEFORE UPDATE =====")
|
||||
await call_agent_async(
|
||||
runner, USER_ID, session.id, "what is the value of state `color`?"
|
||||
)
|
||||
await call_agent_async(runner, USER_ID, session.id, "load artifact file1")
|
||||
|
||||
# 3. Update state and artifact - THIS IS THE POINT WE WILL REWIND BEFORE
|
||||
print("\n\n===== UPDATING STATE AND ARTIFACT =====")
|
||||
events_update_state = await call_agent_async(
|
||||
runner, USER_ID, session.id, "update state key color to blue"
|
||||
)
|
||||
rewind_invocation_id = events_update_state[0].invocation_id
|
||||
print(f"Will rewind before invocation: {rewind_invocation_id}")
|
||||
|
||||
await call_agent_async(
|
||||
runner, USER_ID, session.id, "save artifact file1 with content version2"
|
||||
)
|
||||
|
||||
# 4. Check state and artifact after update
|
||||
print("\n\n===== STATE AFTER UPDATE =====")
|
||||
await call_agent_async(
|
||||
runner, USER_ID, session.id, "what is the value of state key color?"
|
||||
)
|
||||
await call_agent_async(runner, USER_ID, session.id, "load artifact file1")
|
||||
|
||||
# 5. Perform rewind
|
||||
print(f"\n\n===== REWINDING SESSION to before {rewind_invocation_id} =====")
|
||||
await runner.rewind_async(
|
||||
user_id=USER_ID,
|
||||
session_id=session.id,
|
||||
rewind_before_invocation_id=rewind_invocation_id,
|
||||
)
|
||||
print("✅ Rewind complete.")
|
||||
|
||||
# 6. Check state and artifact after rewind
|
||||
print("\n\n===== STATE AFTER REWIND =====")
|
||||
await call_agent_async(
|
||||
runner, USER_ID, session.id, "what is the value of state `color`?"
|
||||
)
|
||||
await call_agent_async(runner, USER_ID, session.id, "load artifact file1")
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("✨ Rewind testing complete!")
|
||||
print(
|
||||
"🔧 If rewind was successful, color should be 'red' and file1 content"
|
||||
" should contain 'version1' in the final check."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -188,20 +188,18 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
# Storage layout matches the cloud and in-memory services:
|
||||
# root/
|
||||
# ├── apps/
|
||||
# │ └── {app_name}/
|
||||
# │ └── users/
|
||||
# │ └── {user_id}/
|
||||
# │ ├── sessions/
|
||||
# │ │ └── {session_id}/
|
||||
# │ │ └── artifacts/
|
||||
# │ │ └── {artifact_path}/ # derived from filename
|
||||
# │ │ └── versions/
|
||||
# │ │ └── {version}/
|
||||
# │ │ ├── {original_filename}
|
||||
# │ │ └── metadata.json
|
||||
# │ └── artifacts/
|
||||
# │ └── {artifact_path}/...
|
||||
# └── users/
|
||||
# └── {user_id}/
|
||||
# ├── sessions/
|
||||
# │ └── {session_id}/
|
||||
# │ └── artifacts/
|
||||
# │ └── {artifact_path}/ # derived from filename
|
||||
# │ └── versions/
|
||||
# │ └── {version}/
|
||||
# │ ├── {original_filename}
|
||||
# │ └── metadata.json
|
||||
# └── artifacts/
|
||||
# └── {artifact_path}/...
|
||||
#
|
||||
# Artifact paths are derived from the provided filenames: separators create
|
||||
# nested directories, and path traversal is rejected to keep the layout
|
||||
@@ -217,19 +215,18 @@ class FileArtifactService(BaseArtifactService):
|
||||
self.root_dir = Path(root_dir).expanduser().resolve()
|
||||
self.root_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def _base_root(self, app_name: str, user_id: str) -> Path:
|
||||
"""Returns the artifacts root directory for an app/user combination."""
|
||||
return self.root_dir / "apps" / app_name / "users" / user_id
|
||||
def _base_root(self, user_id: str, /) -> Path:
|
||||
"""Returns the artifacts root directory for a user."""
|
||||
return self.root_dir / "users" / user_id
|
||||
|
||||
def _scope_root(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
session_id: Optional[str],
|
||||
filename: str,
|
||||
) -> Path:
|
||||
"""Returns the directory that represents the artifact scope."""
|
||||
base = self._base_root(app_name, user_id)
|
||||
base = self._base_root(user_id)
|
||||
if _is_user_scoped(session_id, filename):
|
||||
return _user_artifacts_dir(base)
|
||||
if not session_id:
|
||||
@@ -240,14 +237,12 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _artifact_dir(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
session_id: Optional[str],
|
||||
filename: str,
|
||||
) -> Path:
|
||||
"""Builds the directory path for an artifact."""
|
||||
scope_root = self._scope_root(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -258,7 +253,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
def _build_artifact_version(
|
||||
self,
|
||||
*,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
session_id: Optional[str],
|
||||
filename: str,
|
||||
@@ -270,7 +264,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
metadata.canonical_uri
|
||||
if metadata and metadata.canonical_uri
|
||||
else self._canonical_uri(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -289,7 +282,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
def _canonical_uri(
|
||||
self,
|
||||
*,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
session_id: Optional[str],
|
||||
filename: str,
|
||||
@@ -297,7 +289,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
) -> str:
|
||||
"""Builds the canonical file:// URI for an artifact payload."""
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -336,7 +327,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
"""
|
||||
return await asyncio.to_thread(
|
||||
self._save_artifact_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
filename,
|
||||
artifact,
|
||||
@@ -346,7 +336,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _save_artifact_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
filename: str,
|
||||
artifact: types.Part,
|
||||
@@ -355,7 +344,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
) -> int:
|
||||
"""Saves an artifact to disk and returns its version."""
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -386,7 +374,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
raise ValueError("Artifact must have either inline_data or text content.")
|
||||
|
||||
canonical_uri = self._canonical_uri(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -421,7 +408,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
) -> Optional[types.Part]:
|
||||
return await asyncio.to_thread(
|
||||
self._load_artifact_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
filename,
|
||||
session_id,
|
||||
@@ -430,7 +416,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _load_artifact_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
filename: str,
|
||||
session_id: Optional[str],
|
||||
@@ -438,7 +423,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
) -> Optional[types.Part]:
|
||||
"""Loads an artifact from disk."""
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -493,21 +477,19 @@ class FileArtifactService(BaseArtifactService):
|
||||
) -> list[str]:
|
||||
return await asyncio.to_thread(
|
||||
self._list_artifact_keys_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
session_id,
|
||||
)
|
||||
|
||||
def _list_artifact_keys_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
session_id: Optional[str],
|
||||
) -> list[str]:
|
||||
"""Lists artifact filenames for the given session/user."""
|
||||
filenames: set[str] = set()
|
||||
|
||||
base_root = self._base_root(app_name, user_id)
|
||||
base_root = self._base_root(user_id)
|
||||
|
||||
if session_id:
|
||||
session_root = _session_artifacts_dir(base_root, session_id)
|
||||
@@ -550,7 +532,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
"""
|
||||
await asyncio.to_thread(
|
||||
self._delete_artifact_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
filename,
|
||||
session_id,
|
||||
@@ -558,13 +539,11 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _delete_artifact_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
filename: str,
|
||||
session_id: Optional[str],
|
||||
) -> None:
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -585,7 +564,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
"""Lists all versions stored for an artifact."""
|
||||
return await asyncio.to_thread(
|
||||
self._list_versions_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
filename,
|
||||
session_id,
|
||||
@@ -593,13 +571,11 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _list_versions_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
filename: str,
|
||||
session_id: Optional[str],
|
||||
) -> list[int]:
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -618,7 +594,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
"""Lists metadata for each artifact version on disk."""
|
||||
return await asyncio.to_thread(
|
||||
self._list_artifact_versions_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
filename,
|
||||
session_id,
|
||||
@@ -626,13 +601,11 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _list_artifact_versions_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
filename: str,
|
||||
session_id: Optional[str],
|
||||
) -> list[ArtifactVersion]:
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -644,7 +617,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
metadata = _read_metadata(metadata_path)
|
||||
artifact_versions.append(
|
||||
self._build_artifact_version(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -667,7 +639,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
"""Gets metadata for a specific artifact version."""
|
||||
return await asyncio.to_thread(
|
||||
self._get_artifact_version_sync,
|
||||
app_name,
|
||||
user_id,
|
||||
filename,
|
||||
session_id,
|
||||
@@ -676,14 +647,12 @@ class FileArtifactService(BaseArtifactService):
|
||||
|
||||
def _get_artifact_version_sync(
|
||||
self,
|
||||
app_name: str,
|
||||
user_id: str,
|
||||
filename: str,
|
||||
session_id: Optional[str],
|
||||
version: Optional[int],
|
||||
) -> Optional[ArtifactVersion]:
|
||||
artifact_dir = self._artifact_dir(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
@@ -701,7 +670,6 @@ class FileArtifactService(BaseArtifactService):
|
||||
metadata_path = _metadata_path(artifact_dir, version_to_read)
|
||||
metadata = _read_metadata(metadata_path)
|
||||
return self._build_artifact_version(
|
||||
app_name=app_name,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
filename=filename,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
-1
@@ -18,9 +18,10 @@ This package provides an intelligent assistant for building multi-agent systems
|
||||
using YAML configurations. It can be used directly as an agent or integrated
|
||||
with ADK tools and web interfaces.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from . import agent # Import to make agent.root_agent available
|
||||
from .agent_builder_assistant import AgentBuilderAssistant
|
||||
from .adk_agent_builder_assistant import AgentBuilderAssistant
|
||||
|
||||
__all__ = [
|
||||
'AgentBuilderAssistant',
|
||||
+6
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Agent factory for creating Agent Builder Assistant with embedded schema."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import textwrap
|
||||
@@ -415,3 +416,8 @@ class AgentBuilderAssistant:
|
||||
|
||||
with open(template_path, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
# Expose a module-level root_agent so the AgentLoader can find this built-in
|
||||
# assistant when requested as "__adk_agent_builder_assistant".
|
||||
root_agent = AgentBuilderAssistant.create_agent()
|
||||
+2
-1
@@ -13,8 +13,9 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Agent Builder Assistant instance for ADK web testing."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .agent_builder_assistant import AgentBuilderAssistant
|
||||
from .adk_agent_builder_assistant import AgentBuilderAssistant
|
||||
|
||||
# Create the agent instance using the factory
|
||||
# The root_agent variable is what ADK looks for when loading agents
|
||||
+3
@@ -75,6 +75,9 @@ Always reference this schema when creating configurations to ensure compliance.
|
||||
- **CRITICAL TIMING**: Ask for model selection IMMEDIATELY after determining LlmAgent is needed, BEFORE presenting any design
|
||||
- **MANDATORY CONFIRMATION**: Say "Please confirm what model you want to use" - do NOT assume or suggest defaults
|
||||
- **EXAMPLES**: "gemini-2.5-flash", "gemini-2.5-pro", etc.
|
||||
- **ALLOWED MODELS ONLY**: Only mention or propose "gemini-2.5-flash" or
|
||||
"gemini-2.5-pro". Treat any request for gemini-1.5-* or older models as
|
||||
unsupported and redirect to one of the 2.5 options.
|
||||
- **RATIONALE**: Only LlmAgent requires model specification; workflow agents do not
|
||||
- **DEFAULT MODEL**: If user says "use default" or "proceed with default model", use: {default_model}
|
||||
* This is the actual model name, NOT the literal string "default"
|
||||
+1
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Sub-agents for Agent Builder Assistant."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .google_search_agent import create_google_search_agent
|
||||
from .url_context_agent import create_url_context_agent
|
||||
+1
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Sub-agent for Google Search functionality."""
|
||||
from __future__ import annotations
|
||||
|
||||
from google.adk.agents import LlmAgent
|
||||
from google.adk.tools import google_search
|
||||
+1
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Sub-agent for URL context fetching functionality."""
|
||||
from __future__ import annotations
|
||||
|
||||
from google.adk.agents import LlmAgent
|
||||
from google.adk.tools import url_context
|
||||
+1
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Tools for Agent Builder Assistant."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .cleanup_unused_files import cleanup_unused_files
|
||||
from .delete_files import delete_files
|
||||
+1
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""File deletion tool for Agent Builder Assistant."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user