Skip to content

Commit d9fdb28

Browse files
committed
refactor: remove minimal catalog from renderers, keep in spec, and add simple basic samples
Remove all 'minimal' catalog usage and logic from the renderer packages (Angular and React) to eliminate maintenance burden and catalog ID override hacks. The minimal catalog and its examples remain in the specification for historical reference. To ensure developers still have simple entry-point examples in the standard Basic Catalog, we have: - Copied the simple minimal examples into the basic catalog examples directory (prefixed with `00_` so they sort first). - Renamed the simple login form example to `00_simple-login-form.json` to avoid name collisions with the original basic login form (`09_login-form.json`). - Added the `capitalize` function definition to the v0.9 and v0.10 basic catalogs, as it is used by the migrated `00_capitalized-text.json` example. - Re-added the simple tests in Angular as basic `00_` tests, loading from the basic catalog, verifying that renderers can load these simple examples from the basic catalog. Fixes a2ui-project#1432 TAG=agy CONV=9137c307-af0d-4380-8e89-52054dd1fcb0
1 parent 76dff6a commit d9fdb28

31 files changed

Lines changed: 2776 additions & 4918 deletions

renderers/angular/a2ui_explorer/src/app/tests/v0_8/5_complex_layout.spec.ts renamed to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_complex-layout.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
import {Version, getCanvas, loadExample} from '../utils/test_utils';
1818

19-
describe('Example: Complex Layout (minimal) (v0.8)', () => {
19+
describe('Example: Complex Layout (v0.8)', () => {
2020
let textContent: string;
2121

2222
beforeEach(async () => {
23-
await loadExample('Complex Layout (minimal)', Version.V0_8);
23+
await loadExample('Complex Layout', Version.V0_8);
2424
textContent = getCanvas().textContent;
2525
});
2626

renderers/angular/a2ui_explorer/src/app/tests/v0_8/3_interactive_button.spec.ts renamed to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_interactive-button.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing';
1818
import {DemoComponent} from '../../demo.component';
1919
import {Version, getCanvas, loadExample, wait} from '../utils/test_utils';
2020

21-
describe('Example: Interactive Button (minimal) (v0.8)', () => {
21+
describe('Example: Interactive Button (v0.8)', () => {
2222
let textContent: string;
2323
let fixture: ComponentFixture<DemoComponent>;
2424

2525
beforeEach(async () => {
26-
fixture = await loadExample('Interactive Button (minimal)', Version.V0_8);
26+
fixture = await loadExample('Interactive Button', Version.V0_8);
2727
textContent = getCanvas().textContent;
2828
});
2929

renderers/angular/a2ui_explorer/src/app/tests/v0_8/2_row_layout.spec.ts renamed to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_row-layout.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
import {Version, getCanvas, loadExample} from '../utils/test_utils';
1818

19-
describe('Example: Row Layout (minimal) (v0.8)', () => {
19+
describe('Example: Row Layout (v0.8)', () => {
2020
let textContent: string;
2121

2222
beforeEach(async () => {
23-
await loadExample('Row Layout (minimal)', Version.V0_8);
23+
await loadExample('Row Layout', Version.V0_8);
2424
textContent = getCanvas().textContent;
2525
});
2626

renderers/angular/a2ui_explorer/src/app/tests/v0_8/4_login_form.spec.ts renamed to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-login-form.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing';
1818
import {DemoComponent} from '../../demo.component';
1919
import {Version, getCanvas, loadExample, wait} from '../utils/test_utils';
2020

21-
describe('Example: Login Form (minimal) (v0.8)', () => {
21+
describe('Example: Simple Login Form (v0.8)', () => {
2222
let textContent: string;
2323
let fixture: ComponentFixture<DemoComponent>;
2424

2525
beforeEach(async () => {
26-
fixture = await loadExample('Login Form (minimal)', Version.V0_8);
26+
fixture = await loadExample('Simple Login Form', Version.V0_8);
2727
textContent = getCanvas().textContent;
2828
});
2929

renderers/angular/a2ui_explorer/src/app/tests/v0_8/1_simple_text.spec.ts renamed to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-text.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
import {Version, getCanvas, loadExample} from '../utils/test_utils';
1818

19-
describe('Example: Simple Text (minimal) (v0.8)', () => {
19+
describe('Example: Simple Text (v0.8)', () => {
2020
let textContent: string;
2121

2222
beforeEach(async () => {
23-
await loadExample('Simple Text (minimal)', Version.V0_8);
23+
await loadExample('Simple Text', Version.V0_8);
2424
textContent = getCanvas().textContent;
2525
});
2626

renderers/angular/scripts/generate-examples.mjs

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const DEFAULT_OUT_FILE = 'a2ui_explorer/src/app/generated/examples-bundle.ts';
2626
/**
2727
* The default catalogs to generate examples for if none are specified.
2828
*/
29-
const DEFAULT_CATALOGS = ['minimal', 'basic'];
29+
const DEFAULT_CATALOGS = ['basic'];
3030

3131
/**
3232
* The options that this script accepts.
@@ -35,7 +35,6 @@ const options = {
3535
help: {type: 'boolean', short: 'h'},
3636
'out-file': {type: 'string', short: 'o', default: DEFAULT_OUT_FILE},
3737
catalog: {type: 'string', short: 'c', multiple: true, default: DEFAULT_CATALOGS},
38-
'override-minimal-catalog-id': {type: 'boolean', default: true},
3938
};
4039

4140
/**
@@ -46,35 +45,13 @@ const HELP_MESSAGE = `Usage: node generate-examples.mjs [options]
4645
Options:
4746
-o, --out-file <path> Output file path (default: ${DEFAULT_OUT_FILE})
4847
-c, --catalog <name> Catalog names to include (can be specified multiple times) (default: ${DEFAULT_CATALOGS.join(', ')})
49-
--no-override-minimal-catalog-id Do not override catalog ID for minimal catalog
5048
-h, --help Show this help message
5149
`;
5250

53-
/**
54-
* Overrides the catalog ID for minimal catalog to use basic catalog instead,
55-
* preserving the version in the path.
56-
*/
57-
function overrideMessagesCatalogId(messages) {
58-
const overrideCatalogId = catalogId => {
59-
return catalogId.replace('catalogs/minimal/catalog.json', 'catalogs/basic/catalog.json');
60-
};
61-
for (const msg of messages) {
62-
if (msg.createSurface && msg.createSurface.catalogId) {
63-
// For v0.9 (and up?)
64-
msg.createSurface.catalogId = overrideCatalogId(msg.createSurface.catalogId);
65-
}
66-
// The minimal catalog examples in 0.8 contain a catalogId (but not the basic
67-
// catalog ones). That's probably copy-pasta from when catalogIds were
68-
// introduced later, as the v0.8 renderers didn't use catalogIds. We don't
69-
// need to handle the overrides of the catalogId for the beginRendering
70-
// messages from the v0.8 spec.
71-
}
72-
}
73-
7451
/**
7552
* Reads examples for a given version and catalogs.
7653
*/
77-
function readExamples(specPath, catalogs, overrideCatalogId, version) {
54+
function readExamples(specPath, catalogs, version) {
7855
const examples = [];
7956

8057
for (const catalog of catalogs) {
@@ -117,10 +94,6 @@ function readExamples(specPath, catalogs, overrideCatalogId, version) {
11794
};
11895
}
11996

120-
if (catalog === 'minimal' && overrideCatalogId) {
121-
overrideMessagesCatalogId(example.messages);
122-
}
123-
12497
examples.push(example);
12598
} catch (e) {
12699
throw new Error(`Error parsing ${filePath}`, {cause: e});
@@ -145,26 +118,15 @@ async function main() {
145118

146119
const outPath = values['out-file'];
147120
const outDir = path.dirname(outPath);
148-
const overrideCatalogId = values['override-minimal-catalog-id'];
149121

150122
if (!fs.existsSync(outDir)) {
151123
fs.mkdirSync(outDir, {recursive: true});
152124
}
153125

154126
const catalogs = values.catalog;
155127

156-
const examplesV08 = readExamples(
157-
'../../specification/v0_8/json/catalogs',
158-
catalogs,
159-
overrideCatalogId,
160-
'0.8',
161-
);
162-
const examplesV09 = readExamples(
163-
'../../specification/v0_9/catalogs',
164-
catalogs,
165-
overrideCatalogId,
166-
'0.9',
167-
);
128+
const examplesV08 = readExamples('../../specification/v0_8/json/catalogs', catalogs, '0.8');
129+
const examplesV09 = readExamples('../../specification/v0_9/catalogs', catalogs, '0.9');
168130

169131
// Generate the file now!
170132
const tsContent = `/**

renderers/lit/a2ui_explorer/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# A2UI Local Gallery (Minimal v0.8)
1+
# A2UI Local Gallery (Basic v0.9)
22

3-
This is a standalone, agentless web application designed to render the A2UI v0.8 minimal examples directly from static JSON files. It serves as a focused environment for testing renderer subset compatibility and protocol compliance.
3+
This is a standalone, agentless web application designed to render the A2UI v0.9 basic examples directly from static JSON files. It serves as a focused environment for testing renderer compatibility and protocol compliance.
44

55
## Prerequisites
66

@@ -46,13 +46,12 @@ For more details on building the renderers, see:
4646
npm run dev
4747
```
4848
This command will:
49-
- Sync all JSON examples from `specification/v0_8/json/catalogs/minimal/examples/`.
50-
- Generate a manifest file (`index.json`) for dynamic discovery.
49+
- Load all JSON examples from `specification/v0_9/catalogs/basic/examples/`.
5150
- Start the Vite server at `http://localhost:5173`.
5251

5352
## Architecture
5453

5554
- **Agentless**: Unlike other samples, this does not require a running Python agent. It simulates agent responses locally for interactive components (like the Login Form).
56-
- **Dynamic Loading**: The app automatically discovers and loads _all_ `.json` files present in the v0.8 minimal specification folder at build time. To add a new test case, simply drop a JSON file into that specification folder and restart the dev server.
55+
- **Dynamic Loading**: The app automatically discovers and loads _all_ `.json` files present in the v0.9 basic specification folder at build time. To add a new test case, simply drop a JSON file into that specification folder and restart the dev server.
5756
- **Surface Isolation**: Each example is rendered into its own independent `a2ui-surface` with a unique ID derived from the filename.
5857
- **Mock Agent Console**: All user interactions (button clicks, form submissions) are intercepted and logged to a sidebar, demonstrating how the renderer resolves actions and contexts.

0 commit comments

Comments
 (0)