generative-a11y
Integrations

Custom applications

Connect a custom app by reporting its response, tool, and interaction events directly to generative-a11y.

Install core and browser delivery

Terminal
npm install @generative-a11y/core @generative-a11y/dom

Use this path when your app owns the callbacks that confirm response, tool, or interaction events.

Keep translation thin

Connect browser delivery

Create one runtime for the mounted chat surface and keep it alive across responses.

accessibility.ts
import { createRuntime } from "@generative-a11y/core";
import { bindRuntime } from "@generative-a11y/dom";

export function createAccessibility() {
  const runtime = createRuntime({});
  const delivery = bindRuntime(runtime);

  return {
    runtime,
    dispose() {
      delivery.dispose();
      runtime.dispose();
    },
  };
}

Report events at the source

Call the factory when your surface mounts, then dispatch from the transport or application callbacks that confirm each event. This sequence shows a successful response; replace the sample ID and text with your app's values, and send only newly added text in each delta.

Response lifecycle callbacks
import { createAccessibility } from "./accessibility";

const accessibility = createAccessibility();
const { runtime } = accessibility;

runtime.dispatch({ type: "response.started", responseId: "response-1" });
runtime.dispatch({
  type: "response.text.delta",
  responseId: "response-1",
  delta: "A complete sentence.",
});
runtime.dispatch({ type: "response.completed", responseId: "response-1" });

Dispose by ownership

Stop your transport subscriptions, then call this when the chat surface unmounts. Do not dispose after each response: delivery may still have paced output queued.

App unmount callback
accessibility.dispose();

Report interruption and failure

Send exactly the terminal event confirmed by your app. For a cancelled response, use this instead of response.completed:

Cancellation callback
runtime.dispatch({ type: "response.interrupted", responseId: "response-1" });

For a failed response:

Error callback
runtime.dispatch({ type: "response.failed", responseId: "response-1" });

Preserve stable IDs

Use response and tool IDs from your app, with a namespace when multiple surfaces share a runtime. Labels, array positions, and render counts are not stable IDs. Provide translated user-facing labels when reporting tools or interactions. See the event reference for their required fields.

Compatibility and delivery

The packages require Node.js 22+ and have no framework peers. Core works without a browser; DOM delivery stays inactive when document is unavailable. In React, use A11yProvider to own runtime and browser delivery instead of calling the factory above.

Your app keeps its visible UI, semantic structure, keyboard controls, and focus management. Ordinary streaming does not move focus. Browser delivery tests do not establish what a screen reader speaks.

Leave out events the framework cannot report

Do not treat streamed arguments as a completed tool, a repeated render as a retry, a ready state as an interruption, or a tool name as an approval. If the framework does not report an event, the adapter leaves it out.