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
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f46b73b0cb | |||
| b2f319f440 | |||
| 0c4054200f | |||
| c9e265551a | |||
| 416dc6feed | |||
| 9df3f725bd | |||
| 6c999caa41 | |||
| 77f44a4e45 | |||
| 484b33ef10 | |||
| aaf1f9b930 | |||
| 8e438f2752 | |||
| fa110c22f2 | |||
| 088200072f | |||
| bf47a8bf7d | |||
| cf5d7016a0 | |||
| f38c08b305 | |||
| 3ae6ce10bc | |||
| 13f98c396a | |||
| be7120831a | |||
| 4942f19f3f | |||
| 8488ff052f | |||
| a09781142a | |||
| 309a656f49 | |||
| 9abb8414da | |||
| 3b1f2ae9bf | |||
| 6ed635190c | |||
| d1b058707e | |||
| 54367dcc56 | |||
| fe1de7b103 | |||
| 078ac842d7 | |||
| 4b1c218cbe | |||
| 7dbd8c6a5b | |||
| b7ebb6947f | |||
| 4269cac953 | |||
| 19dbe244e0 | |||
| c224626ae1 | |||
| 1d8d1e0a4e | |||
| 0d232588e6 | |||
| cf689fd528 | |||
| 78bfce4d89 | |||
| 068df04bce | |||
| 86e15cab89 | |||
| 92e7a4a488 | |||
| c6e1e82efb | |||
| 54ed031d1a | |||
| 984c1d6b8b | |||
| 552e42fa06 | |||
| d052e8f13a |
@@ -0,0 +1,113 @@
|
||||
# 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.
|
||||
|
||||
name: "Check file contents"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.py'
|
||||
|
||||
jobs:
|
||||
check-file-contents:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Check for logger pattern in all changed Python files
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }}
|
||||
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' || true)
|
||||
if [ -n "$CHANGED_FILES" ]; then
|
||||
echo "Changed Python files to check:"
|
||||
echo "$CHANGED_FILES"
|
||||
echo ""
|
||||
|
||||
# Check for 'logger = logging.getLogger(__name__)' in changed .py files.
|
||||
# The grep command will exit with a non-zero status code if the pattern is not found.
|
||||
# We invert the exit code with ! so the step succeeds if the pattern is NOT found.
|
||||
set +e
|
||||
FILES_WITH_FORBIDDEN_LOGGER=$(grep -lE 'logger = logging\.getLogger\(__name__\)' $CHANGED_FILES)
|
||||
GREP_EXIT_CODE=$?
|
||||
set -e
|
||||
|
||||
# grep exits with 0 if matches are found, 1 if no matches are found.
|
||||
# A non-zero exit code other than 1 indicates an error.
|
||||
if [ $GREP_EXIT_CODE -eq 0 ]; then
|
||||
echo "❌ Found forbidden use of 'logger = logging.getLogger(__name__)'. Please use 'logger = logging.getLogger('google_adk.' + __name__)' instead."
|
||||
echo "The following files contain the forbidden pattern:"
|
||||
echo "$FILES_WITH_FORBIDDEN_LOGGER"
|
||||
exit 1
|
||||
elif [ $GREP_EXIT_CODE -eq 1 ]; then
|
||||
echo "✅ No instances of 'logger = logging.getLogger(__name__)' found in changed Python files."
|
||||
fi
|
||||
else
|
||||
echo "✅ No relevant Python files found."
|
||||
fi
|
||||
|
||||
- name: Check for import pattern in certain changed Python files
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }}
|
||||
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' | grep -v -E '__init__.py$|version.py$|tests/.*|contributing/samples/' || true)
|
||||
if [ -n "$CHANGED_FILES" ]; then
|
||||
echo "Changed Python files to check:"
|
||||
echo "$CHANGED_FILES"
|
||||
echo ""
|
||||
|
||||
# Use grep -L to find files that DO NOT contain the pattern.
|
||||
# This command will output a list of non-compliant files.
|
||||
FILES_MISSING_IMPORT=$(grep -L 'from __future__ import annotations' $CHANGED_FILES)
|
||||
|
||||
# Check if the list of non-compliant files is empty
|
||||
if [ -z "$FILES_MISSING_IMPORT" ]; then
|
||||
echo "✅ All modified Python files include 'from __future__ import annotations'."
|
||||
exit 0
|
||||
else
|
||||
echo "❌ The following files are missing 'from __future__ import annotations':"
|
||||
echo "$FILES_MISSING_IMPORT"
|
||||
echo "This import is required to allow forward references in type annotations without quotes."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✅ No relevant Python files found."
|
||||
fi
|
||||
|
||||
- name: Check for import from cli package in certain changed Python files
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }}
|
||||
CHANGED_FILES=$(git diff --diff-filter=ACMR --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.py$' | grep -v -E 'cli/.*|tests/.*|contributing/samples/' || true)
|
||||
if [ -n "$CHANGED_FILES" ]; then
|
||||
echo "Changed Python files to check:"
|
||||
echo "$CHANGED_FILES"
|
||||
echo ""
|
||||
|
||||
set +e
|
||||
FILES_WITH_FORBIDDEN_IMPORT=$(grep -lE '^from.*cli.*import.*$' $CHANGED_FILES)
|
||||
GREP_EXIT_CODE=$?
|
||||
set -e
|
||||
|
||||
if [[ $GREP_EXIT_CODE -eq 0 ]]; then
|
||||
echo "❌ Do not import from the cli package outside of the cli package. If you need to reuse the code elsewhere, please move the code outside of the cli package."
|
||||
echo "The following files contain the forbidden pattern:"
|
||||
echo "$FILES_WITH_FORBIDDEN_IMPORT"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ No instances of importing from the cli package found in relevant changed Python files."
|
||||
fi
|
||||
else
|
||||
echo "✅ No relevant Python files found."
|
||||
fi
|
||||
+132
@@ -1,5 +1,137 @@
|
||||
# Changelog
|
||||
|
||||
## [1.3.0](https://github.com/google/adk-python/compare/v1.2.1...v1.3.0) (2025-06-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add memory_service option to CLI ([416dc6f](https://github.com/google/adk-python/commit/416dc6feed26e55586d28f8c5132b31413834c88))
|
||||
* Add support for display_name and description when deploying to agent engine ([aaf1f9b](https://github.com/google/adk-python/commit/aaf1f9b930d12657bfc9b9d0abd8e2248c1fc469))
|
||||
* Dev UI: Trace View
|
||||
* New trace tab which contains all traces grouped by user messages
|
||||
* Click each row will open corresponding event details
|
||||
* Hover each row will highlight the corresponding message in dialog
|
||||
* Dev UI: Evaluation
|
||||
* Evaluation Configuration: users can now configure custom threshold for the metrics used for each eval run ([d1b0587](https://github.com/google/adk-python/commit/d1b058707eed72fd4987d8ec8f3b47941a9f7d64))
|
||||
* Each eval case added can now be viewed and edited. Right now we only support edit of text.
|
||||
* Show the used metric in evaluation history ([6ed6351](https://github.com/google/adk-python/commit/6ed635190c86d5b2ba0409064cf7bcd797fd08da))
|
||||
* Tool enhancements:
|
||||
* Add url_context_tool ([fe1de7b](https://github.com/google/adk-python/commit/fe1de7b10326a38e0d5943d7002ac7889c161826))
|
||||
* Support to customize timeout for mcpstdio connections ([54367dc](https://github.com/google/adk-python/commit/54367dcc567a2b00e80368ea753a4fc0550e5b57))
|
||||
* Introduce write protected mode to BigQuery tools ([6c999ca](https://github.com/google/adk-python/commit/6c999caa41dca3a6ec146ea42b0a794b14238ec2))
|
||||
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Agent Engine deployment:
|
||||
* Correct help text formatting for `adk deploy agent_engine` ([13f98c3](https://github.com/google/adk-python/commit/13f98c396a2fa21747e455bb5eed503a553b5b22))
|
||||
* Handle project and location in the .env properly when deploying to Agent Engine ([0c40542](https://github.com/google/adk-python/commit/0c4054200fd50041f0dce4b1c8e56292b99a8ea8))
|
||||
* Fix broken agent graphs ([3b1f2ae](https://github.com/google/adk-python/commit/3b1f2ae9bfdb632b52e6460fc5b7c9e04748bd50))
|
||||
* Forward `__annotations__` to the fake func for FunctionTool inspection ([9abb841](https://github.com/google/adk-python/commit/9abb8414da1055ab2f130194b986803779cd5cc5))
|
||||
* Handle the case when agent loading error doesn't have msg attribute in agent loader ([c224626](https://github.com/google/adk-python/commit/c224626ae189d02e5c410959b3631f6bd4d4d5c1))
|
||||
* Prevent agent_graph.py throwing when workflow agent is root agent ([4b1c218](https://github.com/google/adk-python/commit/4b1c218cbe69f7fb309b5a223aa2487b7c196038))
|
||||
* Remove display_name for non-Vertex file uploads ([cf5d701](https://github.com/google/adk-python/commit/cf5d7016a0a6ccf2b522df6f2d608774803b6be4))
|
||||
|
||||
|
||||
### Documentation
|
||||
|
||||
* Add DeepWiki badge to README ([f38c08b](https://github.com/google/adk-python/commit/f38c08b3057b081859178d44fa2832bed46561a9))
|
||||
* Update code example in tool declaration to reflect BigQuery artifact description ([3ae6ce1](https://github.com/google/adk-python/commit/3ae6ce10bc5a120c48d84045328c5d78f6eb85d4))
|
||||
|
||||
|
||||
## [1.2.1](https://github.com/google/adk-python/compare/v1.2.0...v1.2.1) (2025-06-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Import deprecated from typing_extensions ([068df04](https://github.com/google/adk-python/commit/068df04bcef694725dd36e09f4476b5e67f1b456))
|
||||
|
||||
|
||||
## [1.2.0](https://github.com/google/adk-python/compare/v1.1.1...v1.2.0) (2025-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add agent engine as a deployment option to the ADK CLI ([2409c3e](https://github.com/google/adk-python/commit/2409c3ef192262c80f5328121f6dc4f34265f5cf))
|
||||
* Add an option to use gcs artifact service in adk web. ([8d36dbd](https://github.com/google/adk-python/commit/8d36dbda520b1c0dec148e1e1d84e36ddcb9cb95))
|
||||
* Add index tracking to handle parallel tool call using litellm ([05f4834](https://github.com/google/adk-python/commit/05f4834759c9b1f0c0af9d89adb7b81ea67d82c8))
|
||||
* Add sortByColumn functionality to List Operation ([af95dd2](https://github.com/google/adk-python/commit/af95dd29325865ec30a1945b98e65e457760e003))
|
||||
* Add implementation for `get_eval_case`, `update_eval_case` and `delete_eval_case` for the local eval sets manager. ([a7575e0](https://github.com/google/adk-python/commit/a7575e078a564af6db3f42f650e94ebc4f338918))
|
||||
* Expose more config of VertexAiSearchTool from latest Google GenAI SDK ([2b5c89b](https://github.com/google/adk-python/commit/2b5c89b3a94e82ea4a40363ea8de33d9473d7cf0))
|
||||
* New Agent Visualization ([da4bc0e](https://github.com/google/adk-python/commit/da4bc0efc0dd96096724559008205854e97c3fd1))
|
||||
* Set the max width and height of view image dialog to be 90% ([98a635a](https://github.com/google/adk-python/commit/98a635afee399f64e0a813d681cd8521fbb49500))
|
||||
* Support Langchain StructuredTool for Langchain tool ([7e637d3](https://github.com/google/adk-python/commit/7e637d3fa05ca3e43a937e7158008d2b146b1b81))
|
||||
* Support Langchain tools that has run_manager in _run args and don't have args_schema populated ([3616bb5](https://github.com/google/adk-python/commit/3616bb5fc4da90e79eb89039fb5e302d6a0a14ec))
|
||||
* Update for anthropic models ([16f7d98](https://github.com/google/adk-python/commit/16f7d98acf039f21ec8a99f19eabf0ef4cb5268c))
|
||||
* Use bigquery scope by default in bigquery credentials. ([ba5b80d](https://github.com/google/adk-python/commit/ba5b80d5d774ff5fdb61bd43b7849057da2b4edf))
|
||||
* Add jira_agent adk samples code which connect Jira cloud ([8759a25](https://github.com/google/adk-python/commit/8759a2525170edb2f4be44236fa646a93ba863e6))
|
||||
* Render HTML artifact in chat window ([5c2ad32](https://github.com/google/adk-python/commit/5c2ad327bf4262257c3bc91010c3f8c303d3a5f5))
|
||||
* Add export to json button in the chat window ([fc3e374](https://github.com/google/adk-python/commit/fc3e374c86c4de87b4935ee9c56b6259f00e8ea2))
|
||||
* Add tooltip to the export session button ([2735942](https://github.com/google/adk-python/commit/273594215efe9dbed44d4ef85e6234bd7ba7b7ae))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add adk icon for UI ([2623c71](https://github.com/google/adk-python/commit/2623c710868d832b6d5119f38e22d82adb3de66b))
|
||||
* Add cache_ok option to remove sa warning. ([841e10a](https://github.com/google/adk-python/commit/841e10ae353e0b1b3d020a26d6cac6f37981550e))
|
||||
* Add support for running python main function in UnsafeLocalCodeExecutor when the code has an if __name__ == "__main__" statement. ([95e33ba](https://github.com/google/adk-python/commit/95e33baf57e9c267a758e08108cde76adf8af69b))
|
||||
* Adk web not working on some env for windows, fixes https://github.com/google/adk-web/issues/34 ([daac8ce](https://github.com/google/adk-python/commit/daac8cedfe6d894f77ea52784f0a6d19003b2c00))
|
||||
* Assign empty inputSchema to MCP tool when converting an ADK tool that wraps a function which takes no parameters. ([2a65c41](https://github.com/google/adk-python/commit/2a65c4118bb2aa97f2a13064db884bd63c14a5f7))
|
||||
* Call all tools in parallel calls during partial authentication ([0e72efb](https://github.com/google/adk-python/commit/0e72efb4398ce6a5d782bcdcb770b2473eb5af2e))
|
||||
* Continue fetching events if there are multiple pages. ([6506302](https://github.com/google/adk-python/commit/65063023a5a7cb6cd5db43db14a411213dc8acf5))
|
||||
* Do not convert "false" value to dict ([60ceea7](https://github.com/google/adk-python/commit/60ceea72bde2143eb102c60cf33b365e1ab07d8f))
|
||||
* Enhance agent loader exception handler and expose precise error information ([7b51ae9](https://github.com/google/adk-python/commit/7b51ae97245f6990c089183734aad41fe59b3330))
|
||||
* Ensure function description is copied when ignoring parameters ([7fdc6b4](https://github.com/google/adk-python/commit/7fdc6b4417e5cf0fbc72d3117531914353d3984a))
|
||||
* Filter memory by app_name and user_id. ([db4bc98](https://github.com/google/adk-python/commit/db4bc9809c7bb6b0d261973ca7cfd87b392694be))
|
||||
* Fix filtering by user_id for vertex ai session service listing ([9d4ca4e](https://github.com/google/adk-python/commit/9d4ca4ed44cf10bc87f577873faa49af469acc25))
|
||||
* fix parameter schema generation for gemini ([5a67a94](https://github.com/google/adk-python/commit/5a67a946d2168b80dd6eba008218468c2db2e74e))
|
||||
* Handle non-indexed function call chunks with incremental fallback index ([b181cbc](https://github.com/google/adk-python/commit/b181cbc8bc629d1c9bfd50054e47a0a1b04f7410))
|
||||
* Handles function tool parsing corner case where type hints are stored as strings. ([a8a2074](https://github.com/google/adk-python/commit/a8a20743f92cd63c3d287a3d503c1913dd5ad5ae))
|
||||
* Introduce PreciseTimestamp to fix mysql datetime precision issue. ([841e10a](https://github.com/google/adk-python/commit/841e10ae353e0b1b3d020a26d6cac6f37981550e))
|
||||
* match arg case in errors ([b226a06](https://github.com/google/adk-python/commit/b226a06c0bf798f85a53c591ad12ee582703af6d))
|
||||
* ParallelAgent should only append to its immediate sub-agent, not transitive descendants ([ec8bc73](https://github.com/google/adk-python/commit/ec8bc7387c84c3f261c44cedfe76eb1f702e7b17))
|
||||
* Relax openapi spec to gemini schema conversion to tolerate more cases ([b1a74d0](https://github.com/google/adk-python/commit/b1a74d099fae44d41750b79e58455282d919dd78))
|
||||
* Remove labels from config when using API key from Google AI Studio to call model ([5d29716](https://github.com/google/adk-python/commit/5d297169d08a2d0ea1a07641da2ac39fa46b68a4))
|
||||
* **sample:** Correct text artifact saving in artifact_save_text sample ([5c6001d](https://github.com/google/adk-python/commit/5c6001d90fe6e1d15a2db6b30ecf9e7b6c26eee4))
|
||||
* Separate thinking from text parts in streaming mode ([795605a](https://github.com/google/adk-python/commit/795605a37e1141e37d86c9b3fa484a3a03e7e9a6))
|
||||
* Simplify content for ollama provider ([eaee49b](https://github.com/google/adk-python/commit/eaee49bc897c20231ecacde6855cccfa5e80d849))
|
||||
* Timeout issues for mcpstdio server when mcp tools are incorrect. ([45ef668](https://github.com/google/adk-python/commit/45ef6684352e3c8082958bece8610df60048f4a3))
|
||||
* **transfer_to_agent:** update docstring for clarity and accuracy ([854a544](https://github.com/google/adk-python/commit/854a5440614590c2a3466cf652688ba57d637205))
|
||||
* Update unit test code for test_connection ([b0403b2](https://github.com/google/adk-python/commit/b0403b2d98b2776d15475f6b525409670e2841fc))
|
||||
* Use inspect.cleandoc on function docstrings in generate_function_declaration. ([f7cb666](https://github.com/google/adk-python/commit/f7cb66620be843b8d9f3d197d6e8988e9ee0dfca))
|
||||
* Restore errors path ([32c5ffa](https://github.com/google/adk-python/commit/32c5ffa8ca5e037f41ff345f9eecf5b26f926ea1))
|
||||
* Unused import for deprecated ([ccd05e0](https://github.com/google/adk-python/commit/ccd05e0b00d0327186e3b1156f1b0216293efe21))
|
||||
* Prevent JSON parsing errors and preserve non-ascii characters in telemetry ([d587270](https://github.com/google/adk-python/commit/d587270327a8de9f33b3268de5811ac756959850))
|
||||
* Raise HTTPException when running evals in fast_api if google-adk[eval] is not installed ([1de5c34](https://github.com/google/adk-python/commit/1de5c340d8da1cedee223f6f5a8c90070a9f0298))
|
||||
* Fix typos in README for sample bigquery_agent and oauth_calendar_agent ([9bdd813](https://github.com/google/adk-python/commit/9bdd813be15935af5c5d2a6982a2391a640cab23))
|
||||
* Make tool_call one span for telemetry and renamed to execute_tool ([999a7fe](https://github.com/google/adk-python/commit/999a7fe69d511b1401b295d23ab3c2f40bccdc6f))
|
||||
* Use media type in chat window. Remove isArtifactImage and isArtifactAudio reference ([1452dac](https://github.com/google/adk-python/commit/1452dacfeb6b9970284e1ddeee6c4f3cb56781f8))
|
||||
* Set output_schema correctly for LiteLllm ([6157db7](https://github.com/google/adk-python/commit/6157db77f2fba4a44d075b51c83bff844027a147))
|
||||
* Update pending event dialog style ([1db601c](https://github.com/google/adk-python/commit/1db601c4bd90467b97a2f26fe9d90d665eb3c740))
|
||||
* Remove the gap between event holder and image ([63822c3](https://github.com/google/adk-python/commit/63822c3fa8b0bdce2527bd0d909c038e2b66dd98))
|
||||
|
||||
|
||||
### Documentation
|
||||
|
||||
* Adds a sample agent to illustrate state usage via `callbacks`. ([18fbe3c](https://github.com/google/adk-python/commit/18fbe3cbfc9f2af97e4b744ec0a7552331b1d8e3))
|
||||
* Fix typos in documentation ([7aaf811](https://github.com/google/adk-python/commit/7aaf8116169c210ceda35c649b5b49fb65bbb740))
|
||||
* Change eval_dataset to eval_dataset_file_path_or_dir ([62d7bf5](https://github.com/google/adk-python/commit/62d7bf58bb1c874caaf3c56a614500ae3b52f215))
|
||||
* Fix broken link to A2A example ([0d66a78](https://github.com/google/adk-python/commit/0d66a7888b68380241b92f7de394a06df5a0cc06))
|
||||
* Fix typo in envs.py ([bd588bc](https://github.com/google/adk-python/commit/bd588bce50ccd0e70b96c7291db035a327ad4d24))
|
||||
* Updates CONTRIBUTING.md to refine setup process using uv. ([04e07b4](https://github.com/google/adk-python/commit/04e07b4a1451123272641a256c6af1528ea6523e))
|
||||
* Create and update project documentation including README.md and CONTRIBUTING.md ([f180331](https://github.com/google/adk-python/commit/f1803312c6a046f94c23cfeaed3e8656afccf7c3))
|
||||
* Rename the root agent in the example to match the example name ([94c0aca](https://github.com/google/adk-python/commit/94c0aca685f1dfa4edb44caaedc2de25cc0caa41))
|
||||
* ADK: add section comment ([349a414](https://github.com/google/adk-python/commit/349a414120fbff0937966af95864bd683f063d08))
|
||||
|
||||
|
||||
### Chore
|
||||
|
||||
* Miscellaneous changes ([0724a83](https://github.com/google/adk-python/commit/0724a83aa9cda00c1b228ed47a5baa7527bb4a0a), [a9dcc58](https://github.com/google/adk-python/commit/a9dcc588ad63013d063dbe37095c0d2e870142c3), [ac52eab](https://github.com/google/adk-python/commit/ac52eab88eccafa451be7584e24aea93ff15f3f3), [a0714b8](https://github.com/google/adk-python/commit/a0714b8afc55461f315ede8451b17aad18d698dd))
|
||||
* Enable release-please workflow ([57d99aa](https://github.com/google/adk-python/commit/57d99aa7897fb229f41c2a08034606df1e1e6064))
|
||||
* Added unit test coverage for local_eval_sets_manager.py ([174afb3](https://github.com/google/adk-python/commit/174afb3975bdc7e5f10c26f3eebb17d2efa0dd59))
|
||||
* Extract common options for `adk web` and `adk api_server` ([01965bd](https://github.com/google/adk-python/commit/01965bdd74a9dbdb0ce91a924db8dee5961478b8))
|
||||
|
||||
## 1.1.1
|
||||
|
||||
### Features
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[](LICENSE)
|
||||
[](https://github.com/google/adk-python/actions/workflows/python-unit-tests.yml)
|
||||
[](https://www.reddit.com/r/agentdevelopmentkit/)
|
||||
[](https://deepwiki.com/google/adk-python)
|
||||
|
||||
<html>
|
||||
<h2 align="center">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This folder host resources for ADK contributors, for example, testing samples etc.
|
||||
|
||||
# Samples
|
||||
## Samples
|
||||
|
||||
Samples folder host samples to test different features. The samples are usually minimal and simplistic to test one or a few scenarios.
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
# 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 os
|
||||
import random
|
||||
import time
|
||||
|
||||
from google.adk import Agent
|
||||
from google.adk.tools.tool_context import ToolContext
|
||||
from google.genai import types
|
||||
import requests
|
||||
|
||||
# Read the PAT from the environment variable
|
||||
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # Ensure you've set this in your shell
|
||||
if not GITHUB_TOKEN:
|
||||
raise ValueError("GITHUB_TOKEN environment variable not set")
|
||||
|
||||
# Repository information
|
||||
OWNER = "google"
|
||||
REPO = "adk-python"
|
||||
|
||||
# Base URL for the GitHub API
|
||||
BASE_URL = "https://api.github.com"
|
||||
|
||||
# Headers including the Authorization header
|
||||
headers = {
|
||||
"Authorization": f"token {GITHUB_TOKEN}",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
|
||||
|
||||
def list_issues(per_page: int):
|
||||
"""
|
||||
Generator to list all issues for the repository by handling pagination.
|
||||
|
||||
Args:
|
||||
per_page: number of pages to return per page.
|
||||
|
||||
"""
|
||||
state = "open"
|
||||
# only process the 1st page for testing for now
|
||||
page = 1
|
||||
results = []
|
||||
url = ( # :contentReference[oaicite:16]{index=16}
|
||||
f"{BASE_URL}/repos/{OWNER}/{REPO}/issues"
|
||||
)
|
||||
# Warning: let's only handle max 10 issues at a time to avoid bad results
|
||||
params = {"state": state, "per_page": per_page, "page": page}
|
||||
response = requests.get(url, headers=headers, params=params)
|
||||
response.raise_for_status() # :contentReference[oaicite:17]{index=17}
|
||||
issues = response.json()
|
||||
if not issues:
|
||||
return []
|
||||
for issue in issues:
|
||||
# Skip pull requests (issues API returns PRs as well)
|
||||
if "pull_request" in issue:
|
||||
continue
|
||||
results.append(issue)
|
||||
return results
|
||||
|
||||
|
||||
def add_label_to_issue(issue_number: str, label: str):
|
||||
"""
|
||||
Add the specified label to the given issue number.
|
||||
|
||||
Args:
|
||||
issue_number: issue number of the Github issue, in string foramt.
|
||||
label: label to assign
|
||||
"""
|
||||
url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/labels"
|
||||
payload = [label]
|
||||
response = requests.post(url, headers=headers, json=payload)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
|
||||
root_agent = Agent(
|
||||
model="gemini-2.5-pro-preview-05-06",
|
||||
name="adk_triaging_assistant",
|
||||
description="Triage ADK issues.",
|
||||
instruction="""
|
||||
You are a Github adk-python repo triaging bot. You will help get issues, and label them.
|
||||
Here are the rules for labeling:
|
||||
- If the user is asking about documentation-related questions, label it with "documentation".
|
||||
- If it's about session, memory services, label it with "services"
|
||||
- If it's about UI/web, label it with "question"
|
||||
- If it's related to tools, label it with "tools"
|
||||
- If it's about agent evalaution, then label it with "eval".
|
||||
- If it's about streaming/live, label it with "live".
|
||||
- If it's about model support(non-Gemini, like Litellm, Ollama, OpenAI models), label it with "models".
|
||||
- If it's about tracing, label it with "tracing".
|
||||
- If it's agent orchestration, agent definition, label it with "core".
|
||||
- If you can't find a appropriate labels for the issue, return the issues to user to decide.
|
||||
""",
|
||||
tools=[
|
||||
list_issues,
|
||||
add_label_to_issue,
|
||||
],
|
||||
generate_content_config=types.GenerateContentConfig(
|
||||
safety_settings=[
|
||||
types.SafetySetting( # avoid false alarm about rolling dice.
|
||||
category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
|
||||
threshold=types.HarmBlockThreshold.OFF,
|
||||
),
|
||||
]
|
||||
),
|
||||
)
|
||||
@@ -17,11 +17,15 @@ import os
|
||||
from google.adk.agents import llm_agent
|
||||
from google.adk.tools.bigquery import BigQueryCredentialsConfig
|
||||
from google.adk.tools.bigquery import BigQueryToolset
|
||||
from google.adk.tools.bigquery.config import BigQueryToolConfig
|
||||
from google.adk.tools.bigquery.config import WriteMode
|
||||
import google.auth
|
||||
|
||||
RUN_WITH_ADC = False
|
||||
|
||||
|
||||
tool_config = BigQueryToolConfig(write_mode=WriteMode.ALLOWED)
|
||||
|
||||
if RUN_WITH_ADC:
|
||||
# Initialize the tools to use the application default credentials.
|
||||
application_default_credentials, _ = google.auth.default()
|
||||
@@ -37,7 +41,9 @@ else:
|
||||
client_secret=os.getenv("OAUTH_CLIENT_SECRET"),
|
||||
)
|
||||
|
||||
bigquery_toolset = BigQueryToolset(credentials_config=credentials_config)
|
||||
bigquery_toolset = BigQueryToolset(
|
||||
credentials_config=credentials_config, bigquery_tool_config=tool_config
|
||||
)
|
||||
|
||||
# The variable name `root_agent` determines what your root agent is for the
|
||||
# debug CLI
|
||||
|
||||
@@ -70,12 +70,22 @@ async def main():
|
||||
if event.content.parts and event.content.parts[0].text:
|
||||
print(f'** {event.author}: {event.content.parts[0].text}')
|
||||
|
||||
async def check_rolls_in_state(rolls_size: int):
|
||||
session = await runner.session_service.get_session(
|
||||
app_name=app_name, user_id=user_id_1, session_id=session_11.id
|
||||
)
|
||||
assert len(session.state['rolls']) == rolls_size
|
||||
for roll in session.state['rolls']:
|
||||
assert roll > 0 and roll <= 100
|
||||
|
||||
start_time = time.time()
|
||||
print('Start time:', start_time)
|
||||
print('------------------------------------')
|
||||
await run_prompt(session_11, 'Hi')
|
||||
await run_prompt(session_11, 'Roll a die with 100 sides')
|
||||
await check_rolls_in_state(1)
|
||||
await run_prompt(session_11, 'Roll a die again with 100 sides.')
|
||||
await check_rolls_in_state(2)
|
||||
await run_prompt(session_11, 'What numbers did I got?')
|
||||
await run_prompt_bytes(session_11, 'Hi bytes')
|
||||
print(
|
||||
|
||||
@@ -61,7 +61,7 @@ async def check_prime(nums: list[int]) -> str:
|
||||
|
||||
root_agent = Agent(
|
||||
model=Claude(model="claude-3-5-sonnet-v2@20241022"),
|
||||
name="data_processing_agent",
|
||||
name="hello_world_agent",
|
||||
description=(
|
||||
"hello world agent that can roll a dice of 8 sides and check prime"
|
||||
" numbers."
|
||||
|
||||
@@ -1 +1,15 @@
|
||||
# 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.
|
||||
|
||||
from . import agent
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
import os
|
||||
|
||||
from google.adk.agents.llm_agent import LlmAgent
|
||||
from google.adk.tools.mcp_tool import StdioConnectionParams
|
||||
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
|
||||
from google.adk.tools.mcp_tool.mcp_toolset import StdioServerParameters
|
||||
from mcp import StdioServerParameters
|
||||
|
||||
_allowed_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
@@ -31,13 +32,16 @@ Allowed directory: {_allowed_path}
|
||||
""",
|
||||
tools=[
|
||||
MCPToolset(
|
||||
connection_params=StdioServerParameters(
|
||||
command='npx',
|
||||
args=[
|
||||
'-y', # Arguments for the command
|
||||
'@modelcontextprotocol/server-filesystem',
|
||||
_allowed_path,
|
||||
],
|
||||
connection_params=StdioConnectionParams(
|
||||
server_params=StdioServerParameters(
|
||||
command='npx',
|
||||
args=[
|
||||
'-y', # Arguments for the command
|
||||
'@modelcontextprotocol/server-filesystem',
|
||||
_allowed_path,
|
||||
],
|
||||
),
|
||||
timeout=5,
|
||||
),
|
||||
# don't want agent to do write operation
|
||||
# you can also do below
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# 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 os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from google.adk.agents import Agent
|
||||
from google.adk.tools.retrieval.vertex_ai_rag_retrieval import VertexAiRagRetrieval
|
||||
from vertexai.preview import rag
|
||||
|
||||
load_dotenv()
|
||||
|
||||
ask_vertex_retrieval = VertexAiRagRetrieval(
|
||||
name="retrieve_rag_documentation",
|
||||
description=(
|
||||
"Use this tool to retrieve documentation and reference materials for"
|
||||
" the question from the RAG corpus,"
|
||||
),
|
||||
rag_resources=[
|
||||
rag.RagResource(
|
||||
# please fill in your own rag corpus
|
||||
# e.g. projects/123/locations/us-central1/ragCorpora/456
|
||||
rag_corpus=os.environ.get("RAG_CORPUS"),
|
||||
)
|
||||
],
|
||||
similarity_top_k=1,
|
||||
vector_distance_threshold=0.6,
|
||||
)
|
||||
|
||||
root_agent = Agent(
|
||||
model="gemini-2.0-flash-001",
|
||||
name="root_agent",
|
||||
instruction=(
|
||||
"You are an AI assistant with access to specialized corpus of"
|
||||
" documents. Your role is to provide accurate and concise answers to"
|
||||
" questions based on documents that are retrievable using"
|
||||
" ask_vertex_retrieval."
|
||||
),
|
||||
tools=[ask_vertex_retrieval],
|
||||
)
|
||||
@@ -1 +1,15 @@
|
||||
# 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.
|
||||
|
||||
from . import agent
|
||||
|
||||
@@ -44,6 +44,7 @@ dependencies = [
|
||||
"PyYAML>=6.0.2", # For APIHubToolset.
|
||||
"sqlalchemy>=2.0", # SQL database ORM
|
||||
"tzlocal>=5.3", # Time zone utilities
|
||||
"typing-extensions>=4.5, <5",
|
||||
"uvicorn>=0.34.0", # ASGI server for FastAPI
|
||||
# go/keep-sorted end
|
||||
]
|
||||
|
||||
@@ -129,7 +129,7 @@ class LlmAgent(BaseAgent):
|
||||
global_instruction: Union[str, InstructionProvider] = ''
|
||||
"""Instructions for all the agents in the entire agent tree.
|
||||
|
||||
global_instruction ONLY takes effect in root agent.
|
||||
ONLY the global_instruction in root agent will take effect.
|
||||
|
||||
For example: use global_instruction to make all agents have a stable identity
|
||||
or personality.
|
||||
@@ -204,11 +204,6 @@ class LlmAgent(BaseAgent):
|
||||
"""
|
||||
# Advance features - End
|
||||
|
||||
# TODO: remove below fields after migration. - Start
|
||||
# These fields are added back for easier migration.
|
||||
examples: Optional[ExamplesUnion] = None
|
||||
# TODO: remove above fields after migration. - End
|
||||
|
||||
# Callbacks - Start
|
||||
before_model_callback: Optional[BeforeModelCallback] = None
|
||||
"""Callback or list of callbacks to be called before calling the LLM.
|
||||
|
||||
@@ -112,7 +112,7 @@ class AuthHandler:
|
||||
|
||||
def parse_and_store_auth_response(self, state: State) -> None:
|
||||
|
||||
credential_key = self.get_credential_key()
|
||||
credential_key = "temp:" + self.auth_config.get_credential_key()
|
||||
|
||||
state[credential_key] = self.auth_config.exchanged_auth_credential
|
||||
if not isinstance(
|
||||
@@ -130,7 +130,7 @@ class AuthHandler:
|
||||
raise ValueError("auth_scheme is empty.")
|
||||
|
||||
def get_auth_response(self, state: State) -> AuthCredential:
|
||||
credential_key = self.get_credential_key()
|
||||
credential_key = "temp:" + self.auth_config.get_credential_key()
|
||||
return state.get(credential_key, None)
|
||||
|
||||
def generate_auth_request(self) -> AuthConfig:
|
||||
@@ -192,29 +192,6 @@ class AuthHandler:
|
||||
exchanged_auth_credential=exchanged_credential,
|
||||
)
|
||||
|
||||
def get_credential_key(self) -> str:
|
||||
"""Generates a unique key for the given auth scheme and credential."""
|
||||
auth_scheme = self.auth_config.auth_scheme
|
||||
auth_credential = self.auth_config.raw_auth_credential
|
||||
if auth_scheme.model_extra:
|
||||
auth_scheme = auth_scheme.model_copy(deep=True)
|
||||
auth_scheme.model_extra.clear()
|
||||
scheme_name = (
|
||||
f"{auth_scheme.type_.name}_{hash(auth_scheme.model_dump_json())}"
|
||||
if auth_scheme
|
||||
else ""
|
||||
)
|
||||
if auth_credential.model_extra:
|
||||
auth_credential = auth_credential.model_copy(deep=True)
|
||||
auth_credential.model_extra.clear()
|
||||
credential_name = (
|
||||
f"{auth_credential.auth_type.value}_{hash(auth_credential.model_dump_json())}"
|
||||
if auth_credential
|
||||
else ""
|
||||
)
|
||||
|
||||
return f"temp:adk_{scheme_name}_{credential_name}"
|
||||
|
||||
def generate_auth_uri(
|
||||
self,
|
||||
) -> AuthCredential:
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .auth_credential import AuthCredential
|
||||
from .auth_credential import BaseModelWithConfig
|
||||
from .auth_schemes import AuthScheme
|
||||
@@ -43,6 +45,34 @@ class AuthConfig(BaseModelWithConfig):
|
||||
this field to guide the user through the OAuth2 flow and fill auth response in
|
||||
this field"""
|
||||
|
||||
def get_credential_key(self):
|
||||
"""Generates a hash key based on auth_scheme and raw_auth_credential. This
|
||||
hash key can be used to store / retrieve exchanged_auth_credential in a
|
||||
credentials store.
|
||||
"""
|
||||
auth_scheme = self.auth_scheme
|
||||
|
||||
if auth_scheme.model_extra:
|
||||
auth_scheme = auth_scheme.model_copy(deep=True)
|
||||
auth_scheme.model_extra.clear()
|
||||
scheme_name = (
|
||||
f"{auth_scheme.type_.name}_{hash(auth_scheme.model_dump_json())}"
|
||||
if auth_scheme
|
||||
else ""
|
||||
)
|
||||
|
||||
auth_credential = self.raw_auth_credential
|
||||
if auth_credential.model_extra:
|
||||
auth_credential = auth_credential.model_copy(deep=True)
|
||||
auth_credential.model_extra.clear()
|
||||
credential_name = (
|
||||
f"{auth_credential.auth_type.value}_{hash(auth_credential.model_dump_json())}"
|
||||
if auth_credential
|
||||
else ""
|
||||
)
|
||||
|
||||
return f"adk_{scheme_name}_{credential_name}"
|
||||
|
||||
|
||||
class AuthToolArguments(BaseModelWithConfig):
|
||||
"""the arguments for the special long running function tool that is used to
|
||||
|
||||
@@ -64,11 +64,11 @@ async def build_graph(
|
||||
if isinstance(tool_or_agent, BaseAgent):
|
||||
# Added Workflow Agent checks for different agent types
|
||||
if isinstance(tool_or_agent, SequentialAgent):
|
||||
return tool_or_agent.name + f' (Sequential Agent)'
|
||||
return tool_or_agent.name + ' (Sequential Agent)'
|
||||
elif isinstance(tool_or_agent, LoopAgent):
|
||||
return tool_or_agent.name + f' (Loop Agent)'
|
||||
return tool_or_agent.name + ' (Loop Agent)'
|
||||
elif isinstance(tool_or_agent, ParallelAgent):
|
||||
return tool_or_agent.name + f' (Parallel Agent)'
|
||||
return tool_or_agent.name + ' (Parallel Agent)'
|
||||
else:
|
||||
return tool_or_agent.name
|
||||
elif isinstance(tool_or_agent, BaseTool):
|
||||
@@ -144,49 +144,53 @@ async def build_graph(
|
||||
)
|
||||
return False
|
||||
|
||||
def build_cluster(child: graphviz.Digraph, agent: BaseAgent, name: str):
|
||||
async def build_cluster(child: graphviz.Digraph, agent: BaseAgent, name: str):
|
||||
if isinstance(agent, LoopAgent):
|
||||
# Draw the edge from the parent agent to the first sub-agent
|
||||
draw_edge(parent_agent.name, agent.sub_agents[0].name)
|
||||
if parent_agent:
|
||||
draw_edge(parent_agent.name, agent.sub_agents[0].name)
|
||||
length = len(agent.sub_agents)
|
||||
currLength = 0
|
||||
curr_length = 0
|
||||
# Draw the edges between the sub-agents
|
||||
for sub_agent_int_sequential in agent.sub_agents:
|
||||
build_graph(child, sub_agent_int_sequential, highlight_pairs)
|
||||
await build_graph(child, sub_agent_int_sequential, highlight_pairs)
|
||||
# Draw the edge between the current sub-agent and the next one
|
||||
# If it's the last sub-agent, draw an edge to the first one to indicating a loop
|
||||
draw_edge(
|
||||
agent.sub_agents[currLength].name,
|
||||
agent.sub_agents[curr_length].name,
|
||||
agent.sub_agents[
|
||||
0 if currLength == length - 1 else currLength + 1
|
||||
0 if curr_length == length - 1 else curr_length + 1
|
||||
].name,
|
||||
)
|
||||
currLength += 1
|
||||
curr_length += 1
|
||||
elif isinstance(agent, SequentialAgent):
|
||||
# Draw the edge from the parent agent to the first sub-agent
|
||||
draw_edge(parent_agent.name, agent.sub_agents[0].name)
|
||||
if parent_agent:
|
||||
draw_edge(parent_agent.name, agent.sub_agents[0].name)
|
||||
length = len(agent.sub_agents)
|
||||
currLength = 0
|
||||
curr_length = 0
|
||||
|
||||
# Draw the edges between the sub-agents
|
||||
for sub_agent_int_sequential in agent.sub_agents:
|
||||
build_graph(child, sub_agent_int_sequential, highlight_pairs)
|
||||
await build_graph(child, sub_agent_int_sequential, highlight_pairs)
|
||||
# Draw the edge between the current sub-agent and the next one
|
||||
# If it's the last sub-agent, don't draw an edge to avoid a loop
|
||||
draw_edge(
|
||||
agent.sub_agents[currLength].name,
|
||||
agent.sub_agents[currLength + 1].name,
|
||||
) if currLength != length - 1 else None
|
||||
currLength += 1
|
||||
if curr_length != length - 1:
|
||||
draw_edge(
|
||||
agent.sub_agents[curr_length].name,
|
||||
agent.sub_agents[curr_length + 1].name,
|
||||
)
|
||||
curr_length += 1
|
||||
|
||||
elif isinstance(agent, ParallelAgent):
|
||||
# Draw the edge from the parent agent to every sub-agent
|
||||
for sub_agent in agent.sub_agents:
|
||||
build_graph(child, sub_agent, highlight_pairs)
|
||||
draw_edge(parent_agent.name, sub_agent.name)
|
||||
await build_graph(child, sub_agent, highlight_pairs)
|
||||
if parent_agent:
|
||||
draw_edge(parent_agent.name, sub_agent.name)
|
||||
else:
|
||||
for sub_agent in agent.sub_agents:
|
||||
build_graph(child, sub_agent, highlight_pairs)
|
||||
await build_graph(child, sub_agent, highlight_pairs)
|
||||
draw_edge(agent.name, sub_agent.name)
|
||||
|
||||
child.attr(
|
||||
@@ -196,21 +200,20 @@ async def build_graph(
|
||||
fontcolor=light_gray,
|
||||
)
|
||||
|
||||
def draw_node(tool_or_agent: Union[BaseAgent, BaseTool]):
|
||||
async def draw_node(tool_or_agent: Union[BaseAgent, BaseTool]):
|
||||
name = get_node_name(tool_or_agent)
|
||||
shape = get_node_shape(tool_or_agent)
|
||||
caption = get_node_caption(tool_or_agent)
|
||||
asCluster = should_build_agent_cluster(tool_or_agent)
|
||||
child = None
|
||||
as_cluster = should_build_agent_cluster(tool_or_agent)
|
||||
if highlight_pairs:
|
||||
for highlight_tuple in highlight_pairs:
|
||||
if name in highlight_tuple:
|
||||
# if in highlight, draw highlight node
|
||||
if asCluster:
|
||||
if as_cluster:
|
||||
cluster = graphviz.Digraph(
|
||||
name='cluster_' + name
|
||||
) # adding "cluster_" to the name makes the graph render as a cluster subgraph
|
||||
build_cluster(cluster, agent, name)
|
||||
await build_cluster(cluster, agent, name)
|
||||
graph.subgraph(cluster)
|
||||
else:
|
||||
graph.node(
|
||||
@@ -224,12 +227,12 @@ async def build_graph(
|
||||
)
|
||||
return
|
||||
# if not in highlight, draw non-highlight node
|
||||
if asCluster:
|
||||
if as_cluster:
|
||||
|
||||
cluster = graphviz.Digraph(
|
||||
name='cluster_' + name
|
||||
) # adding "cluster_" to the name makes the graph render as a cluster subgraph
|
||||
build_cluster(cluster, agent, name)
|
||||
await build_cluster(cluster, agent, name)
|
||||
graph.subgraph(cluster)
|
||||
|
||||
else:
|
||||
@@ -264,10 +267,9 @@ async def build_graph(
|
||||
else:
|
||||
graph.edge(from_name, to_name, arrowhead='none', color=light_gray)
|
||||
|
||||
draw_node(agent)
|
||||
await draw_node(agent)
|
||||
for sub_agent in agent.sub_agents:
|
||||
|
||||
build_graph(graph, sub_agent, highlight_pairs, agent)
|
||||
await build_graph(graph, sub_agent, highlight_pairs, agent)
|
||||
if not should_build_agent_cluster(
|
||||
sub_agent
|
||||
) and not should_build_agent_cluster(
|
||||
@@ -276,7 +278,7 @@ async def build_graph(
|
||||
draw_edge(agent.name, sub_agent.name)
|
||||
if isinstance(agent, LlmAgent):
|
||||
for tool in await agent.canonical_tools():
|
||||
draw_node(tool)
|
||||
await draw_node(tool)
|
||||
draw_edge(agent.name, get_node_name(tool))
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user