LangGraph · API Reference

injectAgent()

injectAgent() is the LangGraph adapter for Angular. It connects to a LangGraph Platform assistant, consumes the LangGraph SDK event stream, and projects the result into the runtime-neutral Agent contract used by @threadplane/chat.

Call it in an Angular injection context, usually as a component field initializer. The returned object exposes Angular Signals for UI state and async methods for user actions.

#Overloads

#No-arg form

injectAgent(): LangGraphAgent

Returns the default-typed agent. state() and value() are Record<string, unknown>. Use this form when your component does not need to read typed state fields.

import { injectAgent } from '@threadplane/langgraph';
 
readonly chat = injectAgent();
 
await this.chat.submit({ message: 'Hello' });
injectAgent<T>(ref: AgentRef<T>): LangGraphAgent<T>

Pass a typed ref handle created with createAgentRef<T>() from @threadplane/chat. Returns a LangGraphAgent<T> where state() and value() are typed as T. The same ref is passed to provideAgent() to bind the configuration.

import { createAgentRef } from '@threadplane/chat';
import { injectAgent, provideAgent } from '@threadplane/langgraph';
import type { BaseMessage } from '@langchain/core/messages';
 
// Declare the ref once (e.g. in agent.ts or app.config.ts):
export interface MyState {
  messages: BaseMessage[];
  summary: string;
}
export const MY_AGENT = createAgentRef<MyState>('my-agent');
 
// Register in app.config.ts providers:
provideAgent(MY_AGENT, {
  apiUrl: 'http://localhost:2024',
  assistantId: 'my-graph',
  threadId: () => localStorage.getItem('threadId') ?? undefined,
  onThreadId: (id) => localStorage.setItem('threadId', id),
});
 
// Inject in a component or service:
readonly chat = injectAgent(MY_AGENT);
// chat.value()  →  MyState
// chat.state()  →  MyState

createAgentRef<T>(debugName?) is exported from @threadplane/chat; the ref carries the state shape T. For typed interrupt payloads, pass the BagTemplate as the second generic at the inject site — injectAgent<T, Bag>(ref) — as shown in the Interrupts guide.

Pair it with provideAgent() at bootstrap to configure the API URL, assistant id, thread persistence, and transport:

import { bootstrapApplication } from '@angular/platform-browser';
import { provideAgent } from '@threadplane/langgraph';
import { createAgentRef } from '@threadplane/chat';
import { AppComponent } from './app/app.component';
 
export const MY_AGENT = createAgentRef('my-agent');
 
bootstrapApplication(AppComponent, {
  providers: [
    provideAgent(MY_AGENT, {
      apiUrl: 'http://localhost:2024',
      assistantId: 'my-graph',
      threadId: () => localStorage.getItem('threadId') ?? undefined,
      onThreadId: (id) => localStorage.setItem('threadId', id),
    }),
  ],
});

#Runtime-neutral surface

These fields are stable across runtime adapters and are what chat components consume.

FieldTypeDescription
messages()Message[]Runtime-neutral chat messages with role, content, optional toolCallId, citations, reasoning, and raw extras.
status()'idle' | 'running' | 'error'UI lifecycle status. LangGraph loading and reloading both map to running.
isLoading()booleanConvenience signal for active streaming.
error()unknownLatest runtime error, when present.
toolCalls()ToolCall[]Tool calls projected into the chat contract.
state()Record<string, unknown>Latest state values projected as a plain object.
submit(input, opts?)Promise<void>Submit a user message, resume payload, and/or state patch.
stop()Promise<void>Stop the active run.
regenerate(index)Promise<void>Remove the assistant message at index and all following messages, then rerun from the preceding user message.
interrupt()AgentInterrupt | undefinedOptional current interrupt, when the backend pauses for human input.
subagents()Map<string, Subagent>Optional subagent streams keyed by tool-call id.

#LangGraph-specific surface

injectAgent() also returns LangGraph-specific signals and helpers for apps that need the raw platform model:

  • value() and hasValue() for raw state values.
  • langGraphMessages(), langGraphToolCalls(), and langGraphHistory() for raw SDK-shaped data.
  • history(), branch(), setBranch(), and experimentalBranchTree() for checkpoint and time-travel UIs.
  • queue(), joinStream(), and switchThread() for persisted threads and queued runs.
  • getSubagent(), getSubagentsByType(), and getSubagentsByMessage() for subgraph/subagent inspection.

#Submit and resume

Use the runtime-neutral submit shape for normal chat input:

await chat.submit({ message: 'Explain streaming in Angular' });

Resume an interrupt with resume; combine it with state when the resume action also needs to update graph state:

await chat.submit({
  resume: { approved: true },
  state: { reviewer: 'Ada' },
});

LangGraph run options are still accepted as the second argument:

await chat.submit(
  { message: 'Queue this run' },
  { multitaskStrategy: 'enqueue' },
);

#Regenerate semantics

regenerate(assistantMessageIndex) has replace semantics. It keeps the user message before the selected assistant message, removes the selected assistant message and every later message, synchronizes that rollback with LangGraph state when possible, then reruns with no new user message appended.

await chat.regenerate(3);

The method throws when the selected index is not an assistant message, when no preceding user message exists, or while another response is already loading.

Injection context required

injectAgent() must be called during construction, inside an injection context (e.g. a component constructor, field initializer, or a function passed to runInInjectionContext). Calling it outside an injection context will throw.

#What's Next

injectAgentfunction

Retrieve the LangGraph-backed Agent from the current Angular injection context. Mirrors `@threadplane/ag-ui`'s `injectAgent()` so consumer code is identical regardless of which adapter is wired in `app.config.ts`. The agent is a singleton scoped to the injector that called `provideAgent()` — re-provide in a child component's `providers: []` to scope a different agent to that subtree (Angular's hierarchical DI handles the rest). **Typed state via AgentRef.** Pass the same ref that was supplied to `provideAgent(ref, …)` to carry the state type through DI without repeating the generic at every call site. The no-arg form defaults to `LangGraphAgent<Record<string, unknown>>`.

injectAgent(): LangGraphAgent<Record<string, unknown>>

Returns

LangGraphAgent<Record<string, unknown>>

Examples

const agent = injectAgent(TRIP); // LangGraphAgent<TripState>