-
Notifications
You must be signed in to change notification settings - Fork 698
Move example A2UI tools to SDK #444
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?
Conversation
8acb82e to
c44b5e8
Compare
|
Closes #375 |
| @@ -0,0 +1,273 @@ | |||
| # Copyright 2025 Google LLC | |||
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.
can we call this file
send_a2ui_to_client_toolset.py
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.
Done
|
|
||
|
|
||
| @experimental | ||
| class A2uiToolset(base_toolset.BaseToolset): |
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.
SendA2uiToClientToolset
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.
Done
| from google.genai import types as genai_types | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
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 needs a lot of documentation at the top to explain how to use it, with examples
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.
Done
| raise ValueError("A2UI schema is empty") | ||
| return {"type": "array", "items": a2ui_schema} | ||
|
|
||
| async def canonical_a2ui_enabled(self, ctx: ReadonlyContext) -> bool: |
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.
follow a2aagentexecutorpattern
_resolve_a2ui_enabled
_resolve_a2ui_schema
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.
Done
| A2UI_JSON_ARG_NAME = "a2ui_json" | ||
|
|
||
| def __init__(self, toolset: A2uiToolset): | ||
| self._toolset = toolset |
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.
oof maybe just pass the
a2ui_schema: Union[dict[str, Any], A2uiSchemaProvider]
in
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.
Done
| return {"error": err} | ||
|
|
||
| @experimental | ||
| class A2uiPartConverter: |
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.
SendA2uiToClientPartConverter
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.
Done
| def __init__(self): | ||
| self._a2ui_schema = None | ||
|
|
||
| def set_a2ui_schema(self, a2ui_schema: dict[str, Any]): |
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.
can we base this off the schema provider pattern above?
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.
It's not possible, because this function is passed to A2aAgentExecutor in the config.
The somewhat hacky solution (which already existed) is to call set_a2ui_schema on every request in _prepare_session. This is also where the schema is recreated based on the incoming request, so it works.
Yesterday you mentioned we could do part conversion elsewhere: but still, we want A2aAgentExecutor to have a working part converter whenever it decides to use it, which is not controlled by this code directly.
Let me know what you think: is this good enough for now?
| @classmethod | ||
| def load_example(cls, path: str, a2ui_schema: dict[str, Any]) -> dict[str, Any]: | ||
| example_str = Path(path).read_text() | ||
| def __init__(self, a2ui_enabled_provider: A2uiToolset.A2uiEnabledProvider, a2ui_schema_provider: A2uiToolset.A2uiSchemaProvider): |
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.
I think don't nest the provider in the toolset
A2uiEnabledProvider
A2uiSchemaProvider
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.
Done
| The wrapped A2UI schema. | ||
| """ | ||
| a2ui_schema = self._a2ui_schema_provider(ctx) | ||
| return A2uiToolset.wrap_schema(a2ui_schema) |
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.
feels outside of the A2uiToolset, also clarify name
maybe wrap_as_json_array(a2ui_schema)
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.
I moved it to a2ui_extension.py and renamed it. WDYT?
7050d5b to
3bab73e
Compare
No description provided.