injectAgentStore
Angular function that subscribes to an AG-UI agent and returns a signal of reactive agent state (messages, state, isRunning) for @copilotkit/angular.
Overview
injectAgentStore subscribes to an AG-UI agent and returns an Angular Signal<AgentStore>. The AgentStore exposes the agent instance plus its reactive state (messages, shared state, and run status) as Angular signals, so your component re-renders automatically when the agent changes.
Read the store by calling the outer signal, then read each member by calling its signal: store().messages(), store().isRunning(), store().state(). The agent member is the plain AG-UI instance (not a signal), so you read it directly: store().agent.
This is the Angular equivalent of React's useAgent(). Call it from an injection context (a constructor or a field initializer). The subscription is torn down automatically when the owning component or service is destroyed.
Resolution of the agent is lazy and reactive. If no agent can be resolved for the given agentId after the runtime has synced (for example, the id does not match any agent reported by your runtime /info or registered via agents__unsafe_dev_only), reading the store signal throws an error listing the known agents.
Signature
import { injectAgentStore } from "@copilotkit/angular";
import type { Signal } from "@angular/core";
function injectAgentStore(
agentId: string | Signal<string | undefined>,
): Signal<AgentStore>;Parameters
Prop
Type
Return Value
Prop
Type
Usage
Basic usage
import { Component } from "@angular/core";
import { injectAgentStore } from "@copilotkit/angular";
@Component({
selector: "app-agent-status",
standalone: true,
template: `
<div>Messages: {{ store().messages().length }}</div>
<div>Running: {{ store().isRunning() ? "Yes" : "No" }}</div>
`,
})
export class AgentStatusComponent {
readonly store = injectAgentStore("default");
}Reading and updating shared state
Read the state via the signal, and write it through the agent instance.
import { Component } from "@angular/core";
import { injectAgentStore } from "@copilotkit/angular";
@Component({
selector: "app-theme-panel",
standalone: true,
template: `
<pre>{{ store().state() | json }}</pre>
<button (click)="setDark()">Dark theme</button>
`,
})
export class ThemePanelComponent {
readonly store = injectAgentStore("default");
setDark() {
const agent = this.store().agent;
agent.setState({ ...(agent.state as object), theme: "dark" });
}
}Switching agents reactively
Pass a signal so the store re-resolves when the selected agent id changes.
import { Component, signal } from "@angular/core";
import { injectAgentStore } from "@copilotkit/angular";
@Component({
selector: "app-multi-agent",
standalone: true,
template: `
<button (click)="agentId.set('support')">Support</button>
<button (click)="agentId.set('sales')">Sales</button>
<div>Active: {{ store().agent.agentId }}</div>
<div>Messages: {{ store().messages().length }}</div>
`,
})
export class MultiAgentComponent {
readonly agentId = signal<string | undefined>("support");
readonly store = injectAgentStore(this.agentId);
}Behavior
- Reactive resolution. The returned signal recomputes when the
agentId, the set of available agents, the runtime connection status, the runtime URL or transport, or the request headers change. - Provisional agents. When a runtime is configured but not yet connected, a provisional proxied runtime agent is created and cached so the store has something to render before the runtime syncs.
- Automatic cleanup. The agent subscription is unsubscribed when the owning component or service is destroyed. Switching to a new agent tears down the previous store's subscription first.
- Error on missing agent. If no agent resolves after the runtime has synced, reading the store signal throws an error that lists the known agent ids.