Soverius AI is now maintaining CopilotKit for Angular

AngularCopilotKitGenerative UIA2UINgRxGemma

Soverius AI is now maintaining @copilotkit/angular, the Angular bindings for CopilotKit. We work directly with the CopilotKit team, and the code lives upstream in CopilotKit/CopilotKit — not in a fork.

This gives Angular developers most of the agentic building blocks the React community already has: a drop-in chat surface, generative UI, sandboxed "open generative UI," frontend tools, and shared agent state. All of it MIT-licensed. To show how it works, we built MacroQuest, an Angular + NgRx Signal Store food tracker that turns a meal description into an interactive, agent-generated UI.

Why we're doing this

Generative and agentic UI has mostly happened in React so far, and the unspoken assumption became "if you want an AI surface, bring a React app." We don't think that trade is necessary. Angular already has good primitives for this: signals for fine-grained reactive state, standalone components for composition, and a DI system that makes wiring an agent runtime into an app feel native.

At Soverius, we take local LLMs the whole way through — from the model on your hardware to the person using the app. That last step, the UI, shouldn't be the one that suddenly needs a cloud.

CopilotKit lists Angular as supported. What was missing was someone to make that real and keep it current. That's the job we've taken on: moving the Angular SDK toward the React v2 experience and keeping it aligned with core.

What you get today

Capability Angular API What it does
Drop-in chat UI <copilot-chat /> Compose, send, message actions, suggestions, attachments — all SDK-owned
Provider / runtime wiring provideCopilotKit(...) Runtime URL, A2UI, open generative UI, labels — configured in app config
Generative UI (A2UI) premade renderer → Lit cpk-a2ui-surface The agent authors a component tree; Angular paints it in the chat stream
Open Generative UI openGenerativeUI.sandboxFunctions The agent generates a sandboxed interactive UI that calls back into your app
Frontend tools registerFrontendTool(...) Typed, narrow mutations the agent is allowed to call
Shared agent state connectAgentContext(...) Expose trusted app state to the agent as context
Image input [attachments] Photo upload through the SDK chat

The package supports Angular 19–21 today. Angular 22 is next: our demo already runs on 22 to validate it ahead of the package. And it's framework-native — it composes with NgRx Signal Store, as the demo shows.

The demo: MacroQuest in two prompts

MacroQuest is a working app shell with daily goals, a live macro dashboard, recent meals, and a CopilotKit chat panel, backed by a local Gemma model through llama.cpp. The demo turns on two prompts, each exercising a different kind of generated UI.

MacroQuest app shell: macro dashboard at 0% with the CopilotKit chat panel and a pre-filled prompt

Prompt 1 — a rich A2UI surface:

Analyze a grilled chicken bowl with rice and beans.

Gemma authors an A2UI component tree. The premade Angular renderer paints it as a meal card in the chat stream, and the draft lands in the store as the selected meal.

A2UI meal card in the chat (

Prompt 2 — an Open Generative UI sandbox:

Suggest a lighter version of my current meal.

This time the agent generates an interactive UI inside a sandbox iframe. Its controls call back into the app through a sandbox function to apply the lighter swap, kept deliberately separate from trusted state.

Agent-generated Open Generative UI sandbox in the chat (

The dashboard never re-renders from the agent's word — it recomputes from the store. The agent proposes; the store decides.

The integration is small

All of the code below is real code from the MacroQuest repo. Mounting the full chat experience is one component:

<copilot-chat [attachments]="store.mealPhotoAttachments" />

Wiring the runtime is declarative app config, including the sandbox function that Prompt 2's generated UI calls back into:

provideCopilotKit({  runtimeUrl: '/api/copilotkit',  a2ui: { includeSchema: true },  openGenerativeUI: {    sandboxFunctions: [      {        name: 'applyMacroSwap',        description:          'Apply a generated lighter macro swap to the selected MacroQuest meal.',        parameters: macroSwapSandboxSchema,        handler: applyMacroSwapFromSandbox,      },    ],  },});

The agent integration itself lives next to your state, not scattered through components. In MacroQuest it's an NgRx signalStoreFeature called withCopilot(), whose onInit hook does two things. First, it exposes trusted state to the agent — a computed over store signals, so the context the agent sees is always current:

const agentContext = computed(() => ({  description:    'MacroQuest trusted Angular state from NgRx Signal Store. ' +    'Use this context before proposing meal updates.',  value: JSON.stringify({    activeDate: store.activeDate(),    goals: store.goals(),    dailyTotals: store.dailyTotals(),    remaining: store.remaining(),    selectedMeal: store.selectedMeal(),  }),}));connectAgentContext(agentContext);

Second, it registers the tools the agent may call. Here's setMacroGoals in full — Zod schema, handler, and all:

registerFrontendTool<MacroGoalsToolArgs>({  name: 'setMacroGoals',  description: 'Update MacroQuest daily macro goals in the Angular NgRx Signal Store.',  parameters: z.object({    calories: z.number().optional(),    protein: z.number().optional(),    carbs: z.number().optional(),    fat: z.number().optional(),  }),  handler: async (goals) => {    store.setGoals(goals);    return { ok: true, goals: store.goals() };  },});

Its sibling logMealDraft follows the same pattern with a richer schema for food items. Note what the tool is: a narrow, typed mutation into state you control. The agent can't reach anything else.

The sandbox side is even more constrained. The generated UI runs in an iframe and can only call the functions you listed in sandboxFunctions. The handler is a plain module function that refuses to act when the app isn't in a state to accept the change:

export async function applyMacroSwapFromSandbox(input: MacroSwapSandboxArgs) {  if (!sandboxStore) {    return { ok: false, message: 'MacroQuest is not ready yet.' };  }  const meal = sandboxStore.applyMacroSwap(input);  if (!meal) {    return { ok: false, message: 'Analyze or select a meal before applying a sandbox swap.' };  }  return { ok: true, mealId: meal.id, title: meal.title, totals: getMealTotals(meal) };}

That's the whole shape: declarative provider config, one chat component, and a thin, typed boundary between the agent and your state. The full technical deep-dive walks the entire build.

What "we maintain it" means

  • Tracks core: @copilotkit/angular releases alongside the CopilotKit core version line.
  • Stays current with Angular: keeping peer ranges live, with Angular 22 support as the next milestone (the demo already runs on 22 ahead of the package).
  • Docs and examples: shipping the Angular quickstart and keeping a reference app (MacroQuest) on recent Angular + NgRx Signals.
  • Upstream-first: the work ships in CopilotKit/CopilotKit itself, and the Angular A2UI work is already merged into main. Stewardship, not a fork.
  • React v2 parity as the goal: DI/signals idioms (not literal React hook names), test depth, and API completeness.

Honest status: Angular isn't widely used in CopilotKit production yet, and there are gaps versus React — tests, CI, docs, API surface. During this catch-up phase, expect occasional breaking changes.

The work so far

The Angular work is merged into CopilotKit main:

  • Murat Sari — A2UI support for Angular (6a768ab7d), chat and transcription improvements (ebcbb19ea), OpenRouter support (800b55dac).
  • Rainer Hahnekamp (Angular GDE / NgRx Core Team) — modernized the Angular package to current standards (b5fa76d5f) and hardened the A2UI renderer (10245a35f).

Roadmap

  • Angular 22 peer support + signals-first ergonomics.
  • An Angular quickstart and API docs.
  • A typed custom A2UI catalog (e.g. MealScanCard, MacroRing) over the basic catalog.
  • More examples beyond food tracking, and ongoing parity tracking against the React SDK.

Try it

npm install @copilotkit/angular
  • Run the demo: clone MacroQuest and follow the two-prompt sequence in the README.
  • File issues / PRs: Angular-tagged on the CopilotKit repo — we're triaging them.
  • Read the build: the full technical deep-dive.

If you've been wanting to add an agent to an Angular app without rewriting it in React, this might be worth a look.

Want to learn more? Check out our hands-on workshops.

Browse Workshops

Comments

No comments yet. Be the first.