Repository navigation
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the prompt generation system by making PromptGenerator.generate() a final method that delegates to a new shared assemble_instructions function. Subclasses of PromptGenerator are now required to implement an abstract catalogs property and three hook methods (generate_base_rules, generate_catalog_instructions, and generate_examples) instead of overriding generate(). Specific format prompt generators are no longer exported directly from a2ui.inference_formats. Additionally, SkillGenerator has been updated to use assemble_instructions to prevent logic duplication, caching has been introduced for generator instructions, and comprehensive unit tests have been added. As there are no review comments, I have no feedback to provide.
0891ca7 to
5f6f7b8
Compare
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Should this also update the blueprints? |
|
@ditman Good call, done in 3a387f3:
|
da38fc0 to
2b913eb
Compare
2b913eb to
ffc9627
Compare
Prompt snippets now follow one layout in every SDK and format: the base rules, then the catalog instructions, then the examples under '### Examples:' and a blank line. - Drop the '## Workflow Description:' heading (and Atom's '## Instructions:') before the base rules. Callers can add their own. - Direct JSON puts the protocol schemas in one schema block after the rules and each catalog schema in a block of its own, in Python, TS and Dart. The TS DirectJsonPromptGenerator moves the protocol schemas into generateBaseRules() and no longer overrides generate() (#3562). - Regenerate the shared Direct JSON prompt fixtures under conformance/test_data/prompts/direct_json/. Refs #3416, #3464 Signed-off-by: Nan Yu <nanyu@google.com>
Signed-off-by: Nan Yu <nanyu@google.com>
The snippet layout is an implementation detail rather than a public API contract, so the entries no longer carry a breaking-change marker. Signed-off-by: Nan Yu <nanyu@google.com>
Signed-off-by: Nan Yu <nanyu@google.com>
Add assemble_instructions(generator, catalogs=None) to a2ui.prompt. It joins a generator's base rules, catalog instructions and examples, and caches the result per generator and catalogs. - PromptGenerator.generate() is now @Final and returns assemble_instructions(self). Subclasses implement the abstract catalogs property and the three hooks. The Express, Direct JSON, Elemental and Atom generators drop their generate() overrides; snippets are unchanged. - SkillGenerator.generate_skill() builds its body with the same function, so a monolithic skill for the format's catalogs holds the prompt snippet. - Stop exporting the per-format PromptGenerator subclasses; reach them through InferenceFormat.prompt_generator. Refs #3416 Signed-off-by: Nan Yu <nanyu@google.com>
Caching text for arbitrary catalogs kept those catalogs alive with the generator. Cache just the generator's own snippet, keyed weakly on the generator; other catalogs are assembled on each call. Signed-off-by: Nan Yu <nanyu@google.com>
…rate() Update the a2ui_agent module blueprint and the skill_generator feature blueprint to match the Python SDK: PromptGenerator declares catalogs and three hooks, generate() is final and returns assemble_instructions(self), SkillGenerator.generate_skill() builds its body with the same function, and the per-format generator classes are internal. Base rules hold what every catalog shares, including protocol schemas such as Direct JSON's. Signed-off-by: Nan Yu <nanyu@google.com>
…rompt assembler entries Signed-off-by: Nan Yu <nanyu@google.com>
ffc9627 to
61dffd0
Compare
ditman
left a comment
There was a problem hiding this comment.
Thanks for updating the blueprints as well! Centralizing prompt and monolithic skill assembly in assemble_instructions(), marking PromptGenerator.generate() @final, and hiding the format-specific PromptGenerator subclasses behind InferenceFormat.prompt_generator is a great simplification.
Left a few minor comments on a docstring contradiction in PromptGenerator.generate_catalog_instructions, a small caching docstring clarification, and an optional cleanup in SkillGenerator.generate_skill.
Signed-off-by: Nan Yu <nanyu@google.com> # Conflicts: # conformance/test_data/prompts/direct_json/cross_ref_catalogs_pruned.txt # dart/a2ui_agent/CHANGELOG.md # python/a2ui_agent/CHANGELOG.md # typescript/agents/a2ui_agent/CHANGELOG.md
…hema_prompt generate_catalog_instructions() now makes a single catalog_schema_prompt() call, so the catalogs' shared protocol version is checked once. Mark the TS changelog entry as a breaking change and link the Dart entry to the PR. Signed-off-by: Nan Yu <nanyu@google.com>
Keep main's ExpressResponseStream exports while leaving ExpressPromptGenerator private, and reach the generator through ExpressFormat.prompt_generator in the test that came in from main. Signed-off-by: Nan Yu <nanyu@google.com>
Type the hooks' catalog argument as CatalogApi, describe the shared multi-catalog content that generate_catalog_instructions() returns with no catalog, say that only the generator's own catalogs are cached, and pass catalogs straight to assemble_instructions in SkillGenerator. Signed-off-by: Nan Yu <nanyu@google.com>
Signed-off-by: Nan Yu <nanyu@google.com> # Conflicts: # python/a2ui_agent/src/a2ui/inference_formats/direct_json/prompt_generator.py # python/a2ui_agent/src/a2ui/inference_formats/experimental/atom/prompt_generator.py # python/a2ui_agent/src/a2ui/inference_formats/experimental/elemental/prompt_generator.py # python/a2ui_agent/src/a2ui/inference_formats/express/prompt_generator.py # python/a2ui_agent/src/a2ui/prompt/generator.py # python/a2ui_agent/src/a2ui/skill/generator.py
Important
Stacked PR, 2 of 3. Stack: #3567 → this PR → #3569.
The base branch is #3567's branch (
stack/prompt-layout), so the diff shows only this PR's changes. When #3567 merges, GitHub retargets this PR tomain.Summary
This PR gives Python one shared function that builds both prompt snippets and monolithic skills.
PromptGenerator.generate()becomes a method that subclasses can't override. It's the "shared assembler + fixedgenerate()" item in #3416, Python only.Changes
a2ui.prompt.assemble_instructions(generator, catalogs=None)joins the base rules, the catalog instructions and the examples (underEXAMPLES_HEADING), and caches the snippet for each generator's own catalogs (weakly keyed on the generator, so the cache keeps nothing alive beyond it).generate_catalog_instructions()andgenerate_examples()once each, so a format can still render shared content once. Express's multi-catalog# Catalogheadings and Elemental's shared type definitions rely on this.SkillGeneratordid.PromptGenerator:generate()is marked@typing.finaland returnsassemble_instructions(self).catalogsis a new abstract property.generate()overrides from the Express, Direct JSON, Elemental and Atom generators. Their snippets don't change: the prompt conformance fixtures and every existing test pass unchanged.SkillGenerator.generate_skill()builds its body withassemble_instructions, so a monolithic skill for the format's own catalogs holds the prompt snippet.ExpressPromptGenerator,DirectJsonPromptGenerator,ElementalPromptGeneratorandAtomPromptGeneratorare removed froma2ui.inference_formatsand their format packages. UseInferenceFormat.prompt_generatorto reach a format's generator.tests/test_prompt_assembler.pyand updated the two test subclasses ofPromptGeneratorto the new contract.a2ui_agentmodule blueprint and theskill_generatorfeature blueprint describe the newPromptGeneratorcontract andassemble_instructions.Impact & Risks
PromptGeneratorsubclasses: they must implementcatalogsand stop overridinggenerate(). mypy reports an override as an error; at runtime the override still runs.Testing
uv run pytest python/a2ui_agent/tests python/a2ui_adk/tests python/a2ui_a2a/tests: all passed, plus 9 new tests intest_prompt_assembler.py.uv run mypy python/a2ui_agentanduv run pyinkare clean.Refs #3416.