Skip to content

[DO NOT MERGE] docs(thermidor): use standard a2ui renderer in ng sample - #7942

Draft
fbeaudoincoveo wants to merge 16 commits into
mainfrom
standard-parsers
Draft

[DO NOT MERGE] docs(thermidor): use standard a2ui renderer in ng sample#7942
fbeaudoincoveo wants to merge 16 commits into
mainfrom
standard-parsers

Conversation

@fbeaudoincoveo

@fbeaudoincoveo fbeaudoincoveo commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

As of today, the /converse endpoint is returning a A2UI that does not fully respect the v0.8 specification of the standard.

There are plans to make it return legit v0.9 A2UI, as this would allow implementations to rely on standard renderers (e.g., @a2ui/angular), as opposed to using custom logic to parse and render the A2UI surface.

This PR shows what it would look like to use the standard A2UI v0.9 Angular renderer in the Angular conversational sample. In order to make it testable, we're adding new prompts / responses to the mock converse service:

  • surfboards v09 (will render a product carousel component + next actions)
  • compare wetsuits v09 (will render a comparison table + summary + next actions)
  • surfing bundle v09 (will render a bundle component + next actions)

In order to test the sample, run the mock service and start the sample with pnpm run dev:mock (see the README for more details).

Most notably, this PR allows us to delete:

  • a2ui-parser.ts (~400 lines)
  • surface-outlet.component.ts (~ 100 lines)
  • A bunch of types in models.ts (~200 lines)

Removing a2ui-parser.ts is particularly good. There is lots of complex / error-prone logic in there.

@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 00613f0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@svcsnykcoveo

svcsnykcoveo commented Jul 8, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@fbeaudoincoveo fbeaudoincoveo Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As explained in the PR description, three additional prompts were added to the mock-converse-api so that we can test the sample with (mocked) v0.9 a2ui surfaces.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registers the sample's custom Angular components with the A2UI renderer so it knows which component to instantiate when it encounters a ProductCarousel, ComparisonTable, etc. in the surface messages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced individual input() fields with the renderer's props signal and derive display values from it using prop(). The template is otherwise unchanged.

Similar changes were made in other a2ui components to adapt them to the standard a2ui Angular renderer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporary change, just to make it obvious what prompts to use when testing locally.

@fbeaudoincoveo fbeaudoincoveo Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a custom switch/dispatcher that used NgComponentOutlet to map each componentType string to the right Angular component. The standard A2UI renderer's SurfaceComponent does exactly the same thing via the catalog, so it's redundant and we can get rid of it! 🥳

@fbeaudoincoveo fbeaudoincoveo Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the surfaces input and quickAction output (no longer needed). Surfaces are now rendered via the standard <a2ui-v09-surface> component, driven by surface IDs exposed as a signal from the adapter service.

@fbeaudoincoveo fbeaudoincoveo Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lets the A2UI renderer receive operations as deltas without having to diff against an accumulated state.

I'll probably cherry-pick this commit and merge it into main separately. This is a net improvement. Without this, we would have to do quite a bit of adaptative work in the implementation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small util to keep components a bit DRYer

@fbeaudoincoveo fbeaudoincoveo Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This service is a thin Angular wrapper around A2uiRendererService. It forwards incoming operations to the renderer and exposes the active surface IDs as a signal for the template. It also handles clearing surfaces between turns via deleteSurface messages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surface operations now flow directly from the controller via onSurfaceOperation callback to the adapter. On submit, the conversation service clears previous surfaces so only the current turn's content is displayed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the custom code that manually parsed raw A2UI operations into typed surface objects and managed state (deduplication, loading flags, data model extraction).

The standard A2UI renderer does all of this internally, so we can delete it entirely! 🥳

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes ensure that the app provides the A2UI renderer service and registers the custom component catalog so the renderer knows how to instantiate our components.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the standard renderer handles parsing and data binding internally, these types are now unused and we can get rid of them! 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants