-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: add a2a agent card generation with the CLI #3606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add a2a agent card generation with the CLI #3606
Conversation
Summary of ChangesHello @guillaumeblaquiere, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the ADK (Agent Development Kit) by adding a new command-line interface tool, Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Response from ADK Triaging Agent Hello @guillaumeblaquiere, thank you for creating this PR! To help us review this PR more effectively, could you please provide the following:
This information will help reviewers to review your PR more efficiently. You can find more details in our contribution guidelines. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new CLI command, generate_agent_card, for A2A agent card generation. The implementation is well-structured, with good error handling for optional dependencies and for processing multiple agents. The new command is correctly integrated into the existing CLI tool. I've added a few comments, mostly related to code style and minor improvements in the new cli_generate_agent_card.py file. The new test case in test_fast_api.py is also a great addition to ensure the A2A runner factory works as expected.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
Hi @guillaumeblaquiere , Thank you for your contribution through this pull request! |
…add-generate-card-command
|
Hi @guillaumeblaquiere , This PR has merge conflicts that require changes from your end. Could you please rebase your branch with the latest main branch to address these? Once this is complete, please let us know so we can proceed with the review. |
|
@ryanaiagent Let me know if it's ok now |
|
Hi @guillaumeblaquiere, Thank you for your patience here. I apologize for the delay in getting to this review; I know this has been sitting for a while. This PR has merge conflicts that require changes from your end. Could you please rebase your branch with the latest main branch to address these? Once this is complete, please let us know so we can proceed with the review. |
|
@ryanaiagent No worries, everyone has his own constraint ;-) Conflict resolved. |
|
Hi @guillaumeblaquiere , thank you for rebasing. can you also fix the failing unit tests and formatting errors |
|
@ryanaiagent unit test fixed, formatting also |
|
/gemini review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new CLI command, generate_agent_card, which is a valuable addition for A2A communication setup. The implementation is solid, with good use of Click and handling for optional dependencies. My review focuses on improving the CLI's exit behavior for better scripting, enhancing test practices for isolation and clarity, and seeking clarification on some unrelated but significant changes in the test suite. Overall, this is a great feature addition.
|
|
||
| # Mock A2A client | ||
| mock_a2a_client = create_autospec(spec=A2AClient, instance=True) | ||
| mock_a2a_client = MagicMock(spec=A2AClient) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mock for A2AClient has been changed from create_autospec to MagicMock. While MagicMock(spec=...) provides some of the benefits of a spec, create_autospec is generally stricter and safer. It ensures that the mock's interface (methods, arguments, and return values) matches the real object, which helps prevent tests from passing with an invalid mock API.
Was there a specific reason for this change? If not, it would be better to stick with create_autospec to maintain stricter mocking and prevent potential issues if the A2AClient interface changes in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests failed if I use create_autospec
| def test_generate_agent_card_missing_a2a(runner): | ||
| with patch.dict( | ||
| "sys.modules", {"google.adk.a2a.utils.agent_card_builder": None} | ||
| ): | ||
| # Simulate ImportError by ensuring the module cannot be imported | ||
| with patch( | ||
| "builtins.__import__", | ||
| side_effect=ImportError("No module named 'google.adk.a2a'"), | ||
| ): | ||
| # We need to target the specific import in the function | ||
| # Since it's a local import inside the function, we can mock sys.modules or use side_effect on import | ||
| # However, patching builtins.__import__ is risky and affects everything. | ||
| # A better way is to mock the module in sys.modules to raise ImportError on access or just rely on the fact that if it's not there it fails. | ||
| # But here we want to force failure even if it is installed. | ||
|
|
||
| # Let's try to patch the specific module import path in the function if possible, | ||
| # but since it is inside the function, we can use patch.dict on sys.modules with a mock that raises ImportError when accessed? | ||
| # No, that's for import time. | ||
|
|
||
| # Actually, the easiest way to test the ImportError branch is to mock the import itself. | ||
| # But `from ..a2a.utils.agent_card_builder import AgentCardBuilder` is hard to mock if it exists. | ||
| pass | ||
|
|
||
| # Alternative: Mock the function `_generate_agent_card_async` to raise ImportError? | ||
| # No, the import is INSIDE `_generate_agent_card_async`. | ||
|
|
||
| # Let's use a patch on the module where `_generate_agent_card_async` is defined, | ||
| # but we can't easily patch the import statement itself. | ||
| # We can use `patch.dict(sys.modules, {'google.adk.a2a.utils.agent_card_builder': None})` | ||
| # and ensure the previous import is cleared? | ||
| pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case, along with test_generate_agent_card_import_error, is currently empty and will pass without performing any checks. Empty tests can give a false sense of security about test coverage.
If testing the ImportError case is too complex for now, it's better to explicitly skip these tests using pytest.skip() or the @pytest.mark.skip decorator with a reason. This makes it clear that the test is intentionally not being run and can be addressed later.
For example:
import pytest
def test_generate_agent_card_missing_a2a(runner):
pytest.skip("Skipping test for ImportError as it is complex to mock local imports.")| cwd = tmp_path / "project" | ||
| cwd.mkdir() | ||
| os.chdir(cwd) | ||
|
|
||
| agent_dir = cwd / "agent1" | ||
| agent_dir.mkdir() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using os.chdir() directly in tests is risky because it affects the global state of the process and can interfere with other tests. A safer, more idiomatic approach for testing Click commands is to use runner.isolated_filesystem().
This context manager provides a temporary, isolated directory and automatically handles changing to and from it, ensuring your test doesn't have side effects. The test can be simplified by creating the agent directory directly within the isolated filesystem.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This PR introduces a new CLI command, generate_agent_card, to the ADK. This command simplifies the setup for A2A (Agent-to-Agent) communication by automating the generation of Agent Cards. It scans the project directory for available agents and produces the necessary JSON configuration for each one.
Key Features
protocol,host, andportused in the agent's endpoint URL.--create-fileflag to automatically save the generated configuration asagent.jsonwithin each agent's directory.Usage Examples
Print Agent Cards to console:
Generate agent.json files for all agents with a custom host and port: