feat(skills): Support non-blocking skill loading in async runtimes#6060
Open
godwin3737 wants to merge 2 commits into
Open
feat(skills): Support non-blocking skill loading in async runtimes#6060godwin3737 wants to merge 2 commits into
godwin3737 wants to merge 2 commits into
Conversation
Add asynchronous counterparts for loading and listing local and GCS skills: - load_skill_from_dir_async - load_skill_from_gcs_dir_async - list_skills_in_dir_async - list_skills_in_gcs_dir_async These use asyncio.to_thread to run blocking I/O in a background thread pool, keeping the main event loop free. Closes google#6057
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. Link to an existing issue (if applicable):
Problem:
Currently, all local and GCS skill loading and listing functions (load_skill_from_dir, load_skill_from_gcs_dir, list_skills_in_dir, list_skills_in_gcs_dir) are strictly synchronous and perform blocking disk or network I/O.
While the SkillRegistry abstract interface uses async methods, implementing a registry that loads local/GCS skills or using these loading utilities inside an asynchronous web server (like FastAPI) or async runners causes the main event loop to block, degrading performance and responsiveness
Solution:
Add asynchronous counterparts for all 4 core skill loading/listing functions in the google.adk.skills package, preserving the existing synchronous functions for backward compatibility:
load_skill_from_dir_async(skill_dir)
load_skill_from_gcs_dir_async(bucket_name, skill_id, ...)
list_skills_in_dir_async(skills_base_path)
list_skills_in_gcs_dir_async(bucket_name, ...)
These functions should utilize Python's built-in asyncio.to_thread to offload blocking I/O operations to a background thread pool, keeping the async event loop completely non-blocking.
Testing Plan
This change was verified using local unit tests. Four new asynchronous test cases were added to tests/unittests/skills/test__utils.py to validate the behavior of the new async APIs under different scenarios (local directories and Google Cloud Storage).
The following new unit tests were added:
test_load_skill_from_dir_async: Verifies that a skill (including instructions, frontmatter, and assets/references) is correctly loaded asynchronously from a local directory.
test_list_skills_in_dir_async: Verifies that skills in a parent directory are discovered asynchronously and their lightweight metadata is returned correctly.
test_load_skill_from_gcs_dir_async: Verifies that a skill is loaded asynchronously from Google Cloud Storage (GCS), with mock storage client interactions.
test_list_skills_in_gcs_dir_async: Verifies that skills stored in GCS are listed and discovered asynchronously using mock GCS directory prefixes.
Unit Tests:
Summary of passed
pytestresults.============================= test session starts ==============================
platform linux -- Python 3.11.9, pytest-9.0.3, pluggy-1.6.0
rootdir: /usr/local/google/home/godwinpaul/Documents/source/adk-python
configfile: pyproject.toml
plugins: langsmith-0.8.11, asyncio-1.4.0, anyio-4.13.0, xdist-3.8.0, mock-3.15.1
asyncio: mode=Mode.AUTO, debug=False, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function
collecting ...
collecting 21 items
collected 21 items
tests/unittests/skills/test__utils.py ..................... [100%]
======================== 21 passed, 4 warnings in 2.74s ========================
Manual End-to-End (E2E) Tests:
Checklist