npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@threadplane/langgraph

v0.0.52

Published

LangGraph adapter for @threadplane/chat — Angular bindings for LangGraph Platform.

Readme

@threadplane/langgraph

Adapter that wraps a LangGraph agent into the runtime-neutral Agent contract from @threadplane/chat. The Angular equivalent of LangGraph's React useStream() hook — signal-driven access to messages, status, tool calls, interrupts, subagents, branch history, and thread persistence.

Talking to a non-LangGraph backend? See @threadplane/ag-ui — same API shape, AG-UI protocol underneath.

What it does

  • provideAgent() — wire the LangGraph adapter into Angular DI. Provided at the root injector or at any component subtree (multi-thread UIs work via Angular's hierarchical DI).
  • injectAgent() — retrieve the configured LangGraphAgent in any component. Returns a LangGraphAgent whose entire state surface (messages, status, isLoading, error, interrupt, toolCalls, subagents, queue, branch, history, and more) is exposed as Angular Signals. No subscriptions, no async pipe, no zone.js required.
  • Human-in-the-loopinterrupt() delivers a runtime-neutral interrupt value; langGraphInterrupts() exposes the raw LangGraph interrupt list when you need it.
  • Subagent streamingsubagents() + getSubagent(toolCallId), getSubagentsByType(type), getSubagentsByMessage(msg), and activeSubagents() surface streaming subgraph state without extra bookkeeping.
  • Time-travel and thread persistencebranch() / history() / experimentalBranchTree() enable checkpoint navigation; LangGraphThreadsAdapter provides SDK-backed thread CRUD so you never have to hand-roll thread management.

Install

npm install @threadplane/langgraph @threadplane/chat

Peer dependencies:

@threadplane/chat          *
@angular/core              ^20.0.0 || ^21.0.0
@langchain/core            ^1.1.33
@langchain/langgraph-sdk   ^1.7.4
rxjs                       ~7.8.0

Quick start

Configure the LangGraph endpoint once in app.config.ts:

// app.config.ts
import { provideAgent } from '@threadplane/langgraph';

export const appConfig: ApplicationConfig = {
  providers: [
    provideAgent({
      apiUrl: 'https://your-langgraph-platform.com',
      assistantId: 'my-agent',
    }),
  ],
};

Then call injectAgent() in any component and pass the result to <chat />:

// chat.component.ts
import { Component } from '@angular/core';
import { injectAgent } from '@threadplane/langgraph';
import { ChatComponent } from '@threadplane/chat';

@Component({
  imports: [ChatComponent],
  template: `<chat [agent]="chat" />`,
})
export class ChatComponentHost {
  protected readonly chat = injectAgent();
}

injectAgent() must be called within an Angular injection context — a component field initializer or constructor. Calling it in ngOnInit or any async context throws NG0203: inject() must be called from an injection context.

Need a different agent for a specific component subtree (e.g., a sidebar showing a separate conversation)? Re-provide provideAgent({...}) in that component's providers: [] array — Angular's hierarchical DI takes care of the rest.

Capabilities

Messages, status, and errors

| Signal | Type | Description | |---|---|---| | messages() | Message[] | Accumulated chat messages from the stream | | status() | 'idle' \| 'running' \| 'error' | Runtime-neutral run status | | isLoading() | boolean | true while a run is streaming | | error() | unknown \| null | Last error, if any |

Human-in-the-loop (interrupts)

const pending = chat.interrupt();       // runtime-neutral interrupt value
const raw = chat.langGraphInterrupts(); // raw LangGraph Interrupt[]

Resume by calling chat.submit(response).

Tool calls

toolCalls() is a Signal of all tool call entries observed in the current run, updated incrementally as the stream progresses.

Subagents

chat.subagents()                       // Signal<Map<string, Subagent>> of all subagents
chat.activeSubagents()                 // currently streaming subagents (SubagentStreamRef[])
chat.getSubagent(toolCallId)           // look up by tool call ID
chat.getSubagentsByType(type)          // filter by subagent type
chat.getSubagentsByMessage(msg)        // filter by parent message

Queue

queue() exposes pending run entries when the agent is configured with a multitask strategy that queues concurrent submissions.

Branch, history, and time-travel

chat.branch()                   // current branch identifier Signal
chat.setBranch(b)               // switch to a checkpoint branch
chat.history()                  // runtime-neutral history entries
chat.langGraphHistory()         // raw LangGraph ThreadState[]
chat.experimentalBranchTree()   // full branching tree for time-travel UI

Actions

chat.submit(input, opts?)                   // send a new message
chat.stop()                                 // cancel the active run
chat.regenerate(assistantMessageIndex)      // re-run from a prior assistant turn
chat.reload()                               // re-run the last submission
chat.switchThread(threadId)                 // load a different thread
chat.joinStream(runId, lastEventId?)        // reconnect to an in-flight run

Thread persistence

LangGraphThreadsAdapter is a drop-in, SDK-backed thread store. Provide it alongside the agent config:

import { provideAgent, LangGraphThreadsAdapter, LANGGRAPH_THREADS_CONFIG } from '@threadplane/langgraph';

export const appConfig: ApplicationConfig = {
  providers: [
    provideAgent({ apiUrl: 'https://your-langgraph-platform.com' }),
    { provide: LANGGRAPH_THREADS_CONFIG, useValue: { apiUrl: 'https://your-langgraph-platform.com' } },
    LangGraphThreadsAdapter,
  ],
};

Pair it with the lifecycle helpers to keep your thread list fresh:

import { refreshOnRunEnd, refreshOnTransition } from '@threadplane/langgraph';

refreshOnRunEnd(chat, () => threadsAdapter.loadThreads());

Citations

extractCitations(msg) reads citation metadata from a LangGraph message's additional_kwargs, returning Citation[] | undefined (undefined when no citation metadata is present). It checks additional_kwargs.citations first, falling back to additional_kwargs.sources.

import { extractCitations } from '@threadplane/langgraph';

const citations = extractCitations(message);

Citation is a type from @threadplane/chat; CitationsResolverService and provideChat also live there.

Testing

// Fake backend — streams canned tokens, no server:
import { provideFakeAgent } from '@threadplane/langgraph';
providers: [provideFakeAgent({ tokens: ['Hello', ' world'] })];

For component/unit tests, use the writable-signal mock mockLangGraphAgent() (it extends the neutral mockAgent from @threadplane/chat). See Choosing an adapter → Testing.

Need to hand-script exact wire events (tool calls, interrupts, multi-batch lifecycles)? MockAgentTransport is the advanced escape hatch — swap the transport, never mock injectAgent() itself.

Reliability

Runtime-neutral contract. LangGraphAgent implements the Agent contract from @threadplane/chat. Components that depend only on that contract are portable across adapters (@threadplane/ag-ui, future adapters) without modification.

Release policy. Patch-only 0.0.x releases — every change, including breaking ones, increments the patch version until the library reaches 1.0.0.

CI. The "Library — lint / test / build" job runs lint, tests, and build on every pull request.

Documentation

License

MIT. See LICENSE.