feat: Gemini Enterprise Demo Generator v11.91-public - #3056
Open
ryotat7 wants to merge 5 commits into
Open
Conversation
Ports the sample forward from v11.62-public. The largest change is where an
A2UI button is allowed to sit, which turned out to decide where Gemini
Enterprise leaves the reader after a press.
A2UI press landing
- A press scrolls to the nearest surface ABOVE the pressed one whose root
renders as a card, crossing the turn boundary only when the pressed
button's own turn has no earlier card-rooted surface. A button in the
first card of a turn therefore scrolls the reader back into the previous
answer. Buttons now go in a trailing, card-rooted surface of their own,
and the server-built gate cards keep their prose in the card while their
input fields and buttons move out together - a {"path": ...} binding only
resolves inside the surface the button lives in, so the fields cannot stay
behind. Compose, confirmation and what-if cards keep their buttons inside,
and so does the welcome card. AGENTS.md section 2.6 records the rule.
- Eight few-shot examples move their follow-up row out to the trailing
surface, and the prompt no longer asks every card for a footer action row.
- Drop component properties the v0.9 composite catalog does not declare
(MaterialRow.ariaLabel and friends): the renderer is strict where draft-07
validation is not, and one foreign property drops the whole surface.
Prompt cost
- The setup script prunes the seven Workspace few-shot examples when
Workspace MCP is off. a2ui globs the examples directory, so they were
prefilled on every turn - about 5.5k tokens teaching an agent to compose a
Gmail draft it has no tool to send. A2UI_KEEP_ALL_EXAMPLES=1 keeps them.
- Trim the BigQuery toolset and the routing block so a figure question is one
execute_sql call instead of a metadata expedition in front of it.
Hardening in the generated demo
- Log an auth-token fingerprint instead of a token prefix, in both the agent
and the A2A runtime.
- sha256 for the idempotency key; a generic message for task failures and for
the viewer app's error responses, with the detail going to the log - these
run on public Cloud Run URLs and the exception text carries Firestore paths
and project identifiers.
- Restrict record and task ids to identifier characters before they reach an
inline handler, escape the goal preview's markdown input, and pin subresource
integrity hashes on the two version-pinned CDN scripts.
Sample data and defaults
- Genericize the few-shot business data: no real company names, and English
throughout, so the examples do not steer the agent's output language.
- Default agent model moves to Gemini 3.7 Flash.
….90-public)
A live test that changed nothing in the agent finally pinned the press-scroll
defect: press a button in the newest turn, then scroll up and press one in a
much older turn, and the view jumps DOWN - onto the surface pressed a moment
earlier. Direction is the tell. No rule phrased as "the nearest surface above
the pressed one" can scroll downward, so the reading this sample has carried
since v11.83, including v11.89's, is withdrawn. The rule is:
on a press, Gemini Enterprise scrolls to the element of the PREVIOUS press.
That target is client state and no arrangement of surfaces can move it. The one
lever left is that a deleted surface cannot be scrolled to, so a press-initiated
turn now retires the surface its button lived in - exactly the anchor the next
press would aim at. Live-verified: the backwards jump stops. The choice stays
visible, because a press arrives with query.text, which the client renders as
the user's message. A surface this turn is also rendering is never deleted, and
A2UI_KEEP_PRESSED_SURFACE=1 restores the old behaviour.
The v11.87 chip wrapper and the v11.89 trailing action surface both stay. Their
scroll rationale is dead, but next actions below the answer card is the layout
that was asked for and it reads better. The comments, AGENTS.md section 2.6 and
the two prompt sentences that asserted the refuted rule are corrected, which
also trims the prompt.
test_press_retire.py covers the helper off-line: chip, gate and welcome presses,
the re-render guard, typed messages, malformed payloads and the kill switch.
The welcome-card exception in the agent instruction still explained itself with "there is nothing above it to jump to", which is the reading v11.90 withdrew. The exception itself stands - the welcome card's buttons are its own content - so only the justification goes.
…91-public) The generated setup script warned when the authorization write failed and then handed $AUTH_ID to register_agent.py anyway. Discovery Engine resolves authorizationConfig.agentAuthorization at create time and rejects the WHOLE registration with 404 NOT_FOUND when it names nothing, so a broken authorization did not cost the demo its Workspace tools - it cost the demo its agent and its direct chat link. Two guards: - read the authorization back with a GET after the write. A 200 on the POST or PATCH is not proof the resource is readable, and only the read answers the question the registration actually asks. Not readable -> clear $AUTH_ID and say what was lost. - retry the registration once without the authorization. Reading back fine is still no guarantee the registration accepts it. A registered agent with degraded Workspace tools beats no agent at all. Both registration call sites - single app and pick-an-app - now go through one register_ge_agent_with_fallback, so the two branches cannot drift again.
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.
Description
Ports the Gemini Enterprise Demo Generator sample forward from
v11.62-publicto
v11.91-public. One new file (test_press_retire.py), no layout change —the same sample, updated.
The largest change is a client scroll behaviour that made every A2UI button
press throw the reader backwards, and what the agent can do about it.
A2UI press landing
On a press, Gemini Enterprise scrolls to the element of the user's PREVIOUS
press. The test that settled it changed nothing in the agent: press a button
in the newest turn, then scroll up and press one in a much older turn, and the
view jumps down, onto the surface pressed a moment earlier. Direction is the
tell — no rule about "the nearest surface above the pressed one" can scroll
downward, so the earlier readings are withdrawn.
move it. What it can do is delete what the target points at:
_pressed_surface_delete_parts()readsuserAction.surfaceIdoff the presspayload and appends a
deleteSurfaceas the last part of the artifact, so theanchor the next press would aim at no longer exists. Live-verified on a
deployed demo: the backwards jump stops.
query.text, which the clientrenders as the user's own message. A surface the same turn is rendering is
never deleted, and
A2UI_KEEP_PRESSED_SURFACE=1restores the old behaviour.test_press_retire.pyexercises the helper off-line (chip, gate and welcomepresses, the re-render guard, typed messages, malformed payloads, the kill
switch), because the helper deletes a surface the user can see.
scroll fix any more, but because next actions below the answer card is the
layout the demos want. The server-built gate cards keep their prose in the
card and move their input fields out together with the buttons: a
{"path": ...}binding only resolves inside the surface the button lives in,so the fields cannot stay behind. Compose, confirmation and what-if cards keep
their buttons inside, and so does the welcome card.
and the prompt no longer asks every card for a footer action row.
(
MaterialRow.ariaLabeland friends) are removed: the renderer is strict wheredraft-07 validation is not, and one foreign property drops the whole surface.
AGENTS.mdsection 2.6 records the rule, the test that pinned it, and thedead ends (an anchor surface before the card, an invisible trailing landing).
Registration survives a broken authorization
The setup script warned when the authorization write failed and then handed
$AUTH_IDtoregister_agent.pyanyway. That is worse than it sounds:Discovery Engine resolves
authorizationConfig.agentAuthorizationat createtime and rejects the whole registration with
404 NOT_FOUNDwhen it namesnothing — so a broken authorization did not cost the demo its Workspace tools,
it cost the demo its agent and its direct chat link.
200on the POST or PATCH is not proof theresource is readable, and only the read answers the question the registration
actually asks. Not readable → clear
$AUTH_ID, register without it, and sayplainly what was lost.
guarantee the registration accepts it (bound to another agent, wrong project
number). A registered agent with degraded Workspace tools beats no agent at
all.
through one
register_ge_agent_with_fallback, so the two copies cannot driftapart again.
Prompt cost
MCP is off. a2ui globs the examples directory, so they were prefilled on every
turn — about 5.5k tokens teaching an agent to compose a Gmail draft it has no
tool to send.
A2UI_KEEP_ALL_EXAMPLES=1keeps them.uses, and the routing block is rewritten so a figure question is one
execute_sqlcall instead of a metadata expedition in front of it.Hardening in the generated demo
agent and the A2A runtime.
responses return a generic message and log the detail — these run on public
Cloud Run URLs and the exception text carries Firestore paths and project
identifiers.
an inline handler, the goal preview escapes its markdown input, and the two
version-pinned CDN scripts carry subresource integrity hashes.
Sample data and defaults
throughout, so the examples do not steer the agent's output language.
Validation
catalog (
validate_examples.py), and the 9 template Python files compile.python3 test_press_retire.py— 9 cases, all passing.node --checkonCode.gs;bash -non all six renders of the setup script(managed-agent × Workspace-MCP × Workspace-auth), with the authorization
read-back present in exactly the four Workspace combos and the registration
fallback used at both call sites in all six.
.github/actions/spelling/allow.txt.Checklist
CONTRIBUTINGGuide.AGENTS.md).CODEOWNERSfor these files.