From 3d8080c3df14a75ed496bd9d670bad31b4ee3119 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Thu, 7 May 2026 14:48:48 -0700 Subject: [PATCH] docs: align public context and remove stale mcp package --- AGENTS.md | 1 - README.md | 4 +- .../content/docs/agent/api/api-docs.json | 6 +- .../agent/concepts/agent-architecture.mdx | 57 +-- .../docs/agent/concepts/angular-signals.mdx | 67 ++- .../docs/agent/concepts/langgraph-basics.mdx | 18 +- .../docs/agent/concepts/state-management.mdx | 10 +- .../agent/getting-started/introduction.mdx | 23 +- .../docs/agent/getting-started/quickstart.mdx | 5 +- .../content/docs/agent/guides/deployment.mdx | 4 +- .../content/docs/agent/guides/interrupts.mdx | 16 +- .../content/docs/agent/guides/memory.mdx | 8 +- .../content/docs/agent/guides/persistence.mdx | 6 +- .../content/docs/agent/guides/streaming.mdx | 18 +- .../content/docs/agent/guides/subgraphs.mdx | 16 +- .../content/docs/agent/guides/testing.mdx | 65 ++- .../content/docs/agent/guides/time-travel.mdx | 2 +- .../content/docs/chat/api/provide-chat.mdx | 2 +- .../docs/chat/components/chat-debug.mdx | 3 +- .../docs/chat/components/chat-input.mdx | 3 +- .../chat/components/chat-interrupt-panel.mdx | 3 +- .../chat/components/chat-message-list.mdx | 17 +- .../chat/components/chat-subagent-card.mdx | 3 +- .../content/docs/chat/components/chat.mdx | 5 +- .../docs/chat/guides/generative-ui.mdx | 3 +- apps/website/content/docs/getting-started.mdx | 2 +- .../content/prompts/getting-started.md | 2 +- apps/website/content/prompts/streaming.md | 4 +- .../public/whitepapers/angular-preview.html | 2 +- apps/website/public/whitepapers/angular.pdf | Bin 500830 -> 508040 bytes apps/website/scripts/generate-whitepaper.ts | 2 +- .../src/components/landing/CodeBlock.tsx | 2 +- .../src/components/landing/ValueProps.tsx | 18 +- .../filesystem/python/docs/guide.md | 18 +- .../deep-agents/memory/python/docs/guide.md | 18 +- .../deep-agents/planning/python/docs/guide.md | 18 +- .../sandboxes/python/docs/guide.md | 16 +- .../deep-agents/skills/python/docs/guide.md | 16 +- .../subagents/python/docs/guide.md | 16 +- .../durable-execution/python/docs/guide.md | 11 +- .../angular/src/app/interrupts.component.ts | 9 +- .../langgraph/interrupts/python/docs/guide.md | 36 +- cockpit/langgraph/memory/python/docs/guide.md | 16 +- .../persistence/python/docs/guide.md | 20 +- .../langgraph/streaming/python/docs/guide.md | 3 +- .../langgraph/subgraphs/python/docs/guide.md | 20 +- .../time-travel/python/docs/guide.md | 12 +- libs/cockpit-docs/project.json | 1 + libs/cockpit-docs/src/lib/docs-bundle.ts | 2 +- libs/cockpit-docs/tsconfig.json | 3 +- libs/langgraph/src/lib/agent.fn.ts | 4 +- .../lib/transport/mock-stream.transport.ts | 6 +- package-lock.json | 400 +++--------------- package.json | 1 - packages/mcp/package-smoke.test.mjs | 63 --- packages/mcp/package.json | 31 -- packages/mcp/project.json | 31 -- packages/mcp/src/data/loader.ts | 54 --- packages/mcp/src/index.js | 16 - packages/mcp/src/index.ts | 48 --- packages/mcp/src/tools/add-agent.ts | 49 --- packages/mcp/src/tools/get-api-reference.ts | 34 -- packages/mcp/src/tools/get-example.ts | 164 ------- .../tools/get-thread-persistence-pattern.ts | 67 --- .../mcp/src/tools/scaffold-chat-component.ts | 73 ---- packages/mcp/src/tools/search-docs.ts | 36 -- packages/mcp/tsconfig.json | 14 - 67 files changed, 360 insertions(+), 1363 deletions(-) delete mode 100644 packages/mcp/package-smoke.test.mjs delete mode 100644 packages/mcp/package.json delete mode 100644 packages/mcp/project.json delete mode 100644 packages/mcp/src/data/loader.ts delete mode 100755 packages/mcp/src/index.js delete mode 100644 packages/mcp/src/index.ts delete mode 100644 packages/mcp/src/tools/add-agent.ts delete mode 100644 packages/mcp/src/tools/get-api-reference.ts delete mode 100644 packages/mcp/src/tools/get-example.ts delete mode 100644 packages/mcp/src/tools/get-thread-persistence-pattern.ts delete mode 100644 packages/mcp/src/tools/scaffold-chat-component.ts delete mode 100644 packages/mcp/src/tools/search-docs.ts delete mode 100644 packages/mcp/tsconfig.json diff --git a/AGENTS.md b/AGENTS.md index 37cca81b6..bf3117de0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,7 +38,6 @@ This file is for agents working in this repository. It is contributor-facing, no - `libs/langgraph`: main Angular library (`@ngaf/langgraph`). - `apps/website`: docs and marketing site. -- `packages/mcp`: MCP server package (`@ngaf/langgraph-mcp`). - `e2e/agent-e2e`: end-to-end coverage for the workspace. ## Working in This Repo diff --git a/README.md b/README.md index d622f51f0..35c026eb2 100644 --- a/README.md +++ b/README.md @@ -87,11 +87,11 @@ That's it. `chat.messages()` and `chat.status()` are Angular Signals. Bind them | Error state | `error()` | — | | Runtime-neutral status | `status()` — `'idle' \| 'running' \| 'error'` | partial | | Interrupt / human-in-the-loop | `interrupt()` / `interrupts()` | `interrupt` / `interrupts` | -| Tool call progress | `toolProgress()` | `toolProgress` | +| Tool call progress | `toolCalls()` | `toolCalls` | | Tool calls with results | `toolCalls()` | `toolCalls` | | Branch / history | `branch()` / `history()` / `experimentalBranchTree()` | `branch` / `history` / `experimental_branchTree` | | Pending run queue | `queue()` | `queue` | -| Subagent streaming and lookup helpers | `subagents()` / `activeSubagents()` / `getSubagent()` | `subagents` / `activeSubagents` / helper methods | +| Subagent streaming and lookup helpers | `subagents()` / `getSubagent()` | `subagents` / helper methods | | Reactive thread switching | `Signal` input | prop | | Submit | `submit(values, opts?)` | `submit(values, opts?)` | | Stop | `stop()` | `stop()` | diff --git a/apps/website/content/docs/agent/api/api-docs.json b/apps/website/content/docs/agent/api/api-docs.json index 7974a5992..7c7ac9bdc 100644 --- a/apps/website/content/docs/agent/api/api-docs.json +++ b/apps/website/content/docs/agent/api/api-docs.json @@ -211,7 +211,7 @@ } ], "examples": [ - "```typescript\nconst transport = new MockAgentTransport([\n [{ type: 'values', data: { messages: [aiMsg('Hello')] } }],\n [{ type: 'values', data: { status: 'done' } }],\n]);\n```" + "```typescript\nconst transport = new MockAgentTransport([\n [{ type: 'values', messages: [aiMsg('Hello')] }],\n [{ type: 'values', messages: [aiMsg('Done')] }],\n]);\n```" ], "properties": [ { @@ -405,7 +405,7 @@ { "name": "nextBatch", "signature": "nextBatch()", - "description": "Advance to the next scripted batch and return its events.", + "description": "Advance to the next scripted batch. Pass the returned events to `emit()`.", "params": [] }, { @@ -1661,7 +1661,7 @@ "description": "" }, "examples": [ - "```typescript\n// In a component field initializer\nconst chat = agent<{ messages: BaseMessage[] }>({\n assistantId: 'chat_agent',\n apiUrl: 'http://localhost:2024',\n threadId: signal(this.savedThreadId),\n onThreadId: (id) => localStorage.setItem('threadId', id),\n});\n\n// Access signals in template\n// chat.messages(), chat.status(), chat.error()\n```" + "```typescript\n// In a component field initializer\nconst chat = agent({\n assistantId: 'chat_agent',\n apiUrl: 'http://localhost:2024',\n threadId: signal(this.savedThreadId),\n onThreadId: (id) => localStorage.setItem('threadId', id),\n});\n\n// Access signals in template\n// chat.messages(), chat.status(), chat.error()\n```" ] }, { diff --git a/apps/website/content/docs/agent/concepts/agent-architecture.mdx b/apps/website/content/docs/agent/concepts/agent-architecture.mdx index 0f9307d11..4ba9f1ba8 100644 --- a/apps/website/content/docs/agent/concepts/agent-architecture.mdx +++ b/apps/website/content/docs/agent/concepts/agent-architecture.mdx @@ -179,11 +179,13 @@ export class ReactAgentComponent { messages = this.agent.messages; - // Tools currently executing (spinner, progress bar) - activeTools = computed(() => this.agent.toolProgress()); - - // Tools that finished with results (expandable cards) - completedTools = computed(() => this.agent.toolCalls()); + // Tool calls with status, args, and result data + activeTools = computed(() => + this.agent.toolCalls().filter((tool) => tool.status === 'running') + ); + completedTools = computed(() => + this.agent.toolCalls().filter((tool) => tool.status === 'complete') + ); send(text: string) { this.agent.submit({ message: text }); @@ -233,21 +235,23 @@ The LLM reads the docstring to decide when to call a tool. A vague docstring lik ### How Tools Surface in Angular -When the agent calls a tool, agent() exposes the execution lifecycle through two signals: +When the agent calls a tool, agent() exposes the execution lifecycle through `toolCalls()`: - + ```typescript -// toolProgress() — tools currently executing +// toolCalls() — tool calls with status, args, and results // Updates in real time as tools start and complete const agent = agent({ assistantId: 'react_agent', }); -// Each entry has: name, args, status -const activeTools = computed(() => agent.toolProgress()); +// Each entry has: id, name, args, status, and optional result +const activeTools = computed(() => + agent.toolCalls().filter((tool) => tool.status === 'running') +); // Template usage @Component({ @@ -263,18 +267,19 @@ const activeTools = computed(() => agent.toolProgress()); `, }) export class ToolProgressComponent { - activeTools = computed(() => this.agent.toolProgress()); + activeTools = computed(() => + this.agent.toolCalls().filter((tool) => tool.status === 'running') + ); } ``` - + ```typescript -// toolCalls() — completed tool calls with results -// Available after each tool finishes - -const completedTools = computed(() => agent.toolCalls()); +const completedTools = computed(() => + agent.toolCalls().filter((tool) => tool.status === 'complete') +); // Each entry has: name, args, result, duration @Component({ @@ -324,7 +329,7 @@ The `should_continue` conditional edge detects `tool_calls` and routes to the `t LangGraph Platform streams the tool call and result as SSE events to the Angular client. -`toolProgress()` updates during execution. `toolCalls()` updates when the tool completes. Both trigger OnPush change detection. +`toolCalls()` updates as the tool moves through pending, running, complete, and error states. Each update triggers OnPush change detection. @@ -442,10 +447,14 @@ export class MultiAgentComponent { messages = this.orchestrator.messages; // Currently running delegated work with live status - activeTools = computed(() => this.orchestrator.toolProgress()); + activeTools = computed(() => + this.orchestrator.toolCalls().filter((tool) => tool.status === 'running') + ); // Completed tool calls with results - completedTools = computed(() => this.orchestrator.toolCalls()); + completedTools = computed(() => + this.orchestrator.toolCalls().filter((tool) => tool.status === 'complete') + ); send(text: string) { this.orchestrator.submit({ message: text }); @@ -518,7 +527,7 @@ export class AgentComponent { |---|---|---| | Tool throws `ToolException` | Error fed back to LLM, agent retries | `toolCalls()` shows error in result | | Tool throws unexpected error | LangGraph catches it, marks tool as failed | `error()` fires with details | -| LLM returns invalid tool args | ToolNode validation fails, error fed to LLM | `toolProgress()` shows failed status | +| LLM returns invalid tool args | ToolNode validation fails, error fed to LLM | `toolCalls()` shows failed status | | Transport error (network) | N/A | `error()` fires, `status()` becomes `'error'` | | Agent exceeds recursion limit | Graph raises `GraphRecursionError` | `error()` fires with recursion message | @@ -594,7 +603,7 @@ export class DebugTimelineComponent { timeTravel(checkpointId: string) { this.currentCheckpoint.set(checkpointId); - this.agent.submit(null, { checkpointId }); + this.agent.submit({}, { checkpointId }); } } ``` @@ -622,7 +631,7 @@ builder.add_edge("tools", "model") graph = builder.compile() ``` -**Angular signals used:** `messages()`, `toolCalls()`, `toolProgress()`, `status()` +**Angular signals used:** `messages()`, `toolCalls()`, `status()` ### Single Agent with Human-in-the-Loop @@ -640,7 +649,7 @@ def execute_action(state: AgentState) -> dict: return perform_action(state["pending_action"]) ``` -**Angular signals used:** `messages()`, `interrupt()`, `status()` plus `submit(null, { resume })` to approve +**Angular signals used:** `messages()`, `interrupt()`, `status()` plus `submit({ resume })` to approve ### Multi-Agent Supervisor @@ -654,7 +663,7 @@ builder.add_node("analyst", analyst_subgraph) builder.add_conditional_edges("supervisor", route_to_agent) ``` -**Angular signals used:** `messages()`, `subagents()`, `activeSubagents()`, `toolCalls()`, `toolProgress()`, `status()` +**Angular signals used:** `messages()`, `subagents()`, `toolCalls()`, `status()` ### Decision Matrix diff --git a/apps/website/content/docs/agent/concepts/angular-signals.mdx b/apps/website/content/docs/agent/concepts/angular-signals.mdx index cc49199f7..5d9fc04d5 100644 --- a/apps/website/content/docs/agent/concepts/angular-signals.mdx +++ b/apps/website/content/docs/agent/concepts/angular-signals.mdx @@ -41,7 +41,7 @@ Under the hood, agent() receives Server-Sent Events (SSE) over HTTP and feeds th // Simplified view of what agent does internally: // 1. SSE events arrive as an observable stream -const messages$ = new BehaviorSubject([]); +const messages$ = new BehaviorSubject([]); const status$ = new BehaviorSubject('idle'); // 2. Each SSE chunk updates the BehaviorSubject @@ -68,8 +68,8 @@ const chat = agent({ assistantId: 'chat_agent', }); -chat.messages(); // Signal -chat.status(); // Signal +chat.messages(); // Signal +chat.status(); // Signal<'idle' | 'running' | 'error'> chat.error(); // Signal chat.isLoading(); // Signal chat.value(); // Signal @@ -84,7 +84,7 @@ The BehaviorSubject-to-Signal conversion means you get the best of both worlds: ## The Streaming Lifecycle as Signals -Every agent() instance moves through a lifecycle: **idle**, **loading**, tokens arriving, then **resolved** (or **error**). The `status()` Signal reflects each transition in real time. +Every agent() instance moves through a lifecycle: **idle**, **running** while work is in flight, then back to **idle** when the stream completes (or **error** when it fails). The `status()` Signal reflects each transition in real time, while `isLoading()` is the convenience signal for loading UI. @@ -101,39 +101,39 @@ console.log(chat.isLoading()); // false ``` - -After calling `submit()`, the status transitions to `'loading'`. The SSE connection is open and the agent is processing. + +After calling `submit()`, the status transitions to `'running'`. The SSE connection is open and the agent is processing. ```typescript chat.submit({ message: 'Explain quantum computing' }); -console.log(chat.status()); // 'loading' +console.log(chat.status()); // 'running' console.log(chat.isLoading()); // true console.log(chat.messages()); // [] (no tokens yet) ``` - -As the agent generates tokens, the `messages()` Signal updates with each chunk. The status remains `'loading'` throughout. + +As the agent generates tokens, the `messages()` Signal updates with each chunk. The status remains `'running'` throughout. ```typescript // After first few tokens arrive: -console.log(chat.status()); // 'loading' (still streaming) -console.log(chat.messages()); // [AIMessageChunk("Quantum computing uses...")] +console.log(chat.status()); // 'running' (still streaming) +console.log(chat.messages()); // [{ role: 'assistant', content: 'Quantum computing uses...' }] // After more tokens: -console.log(chat.messages()); // [AIMessageChunk("Quantum computing uses qubits...")] +console.log(chat.messages()); // [{ role: 'assistant', content: 'Quantum computing uses qubits...' }] // The message content grows as tokens stream in ``` - -The agent has finished. All tokens have arrived. The status transitions to `'resolved'`. + +The agent has finished. All tokens have arrived. The status transitions back to `'idle'`. ```typescript -console.log(chat.status()); // 'resolved' +console.log(chat.status()); // 'idle' console.log(chat.isLoading()); // false -console.log(chat.messages()); // [AIMessage("Quantum computing uses qubits to...")] +console.log(chat.messages()); // [{ role: 'assistant', content: 'Quantum computing uses qubits to...' }] ``` @@ -168,16 +168,11 @@ const lastMessage = computed(() => chat.messages().at(-1)); // Extract just the assistant's messages const assistantMessages = computed(() => - chat.messages().filter(m => m._getType() === 'ai') + chat.messages().filter(m => m.role === 'assistant') ); // Track which tools the agent is actively calling -const activeTools = computed(() => - chat.messages() - .filter(m => m._getType() === 'ai') - .flatMap(m => m.tool_calls ?? []) - .filter(tc => !tc.result) -); +const activeTools = computed(() => chat.toolCalls()); // Build a user-facing error message const errorDisplay = computed(() => { @@ -195,7 +190,7 @@ const errorDisplay = computed(() => { const viewModel = computed(() => ({ messages: chat.messages(), isStreaming: chat.isLoading(), - canSend: chat.status() !== 'loading', + canSend: !chat.isLoading(), messageCount: messageCount(), error: errorDisplay(), })); @@ -238,10 +233,10 @@ effect(() => { // Track streaming duration for performance monitoring effect(() => { const status = chat.status(); - if (status === 'loading') { + if (status === 'running') { this.streamStart = performance.now(); } - if (status === 'resolved' && this.streamStart) { + if (status === 'idle' && this.streamStart) { const duration = performance.now() - this.streamStart; this.analytics.track('stream_duration_ms', { duration }); this.streamStart = null; @@ -267,7 +262,7 @@ import { agent } from '@ngaf/langgraph'; template: ` @switch (chat.status()) { - @case ('loading') { + @case ('running') {
Agent is responding...
@@ -283,18 +278,18 @@ import { agent } from '@ngaf/langgraph';
@for (message of chat.messages(); track $index) { - @switch (message._getType()) { - @case ('human') { + @switch (message.role) { + @case ('user') {
{{ message.content }}
} - @case ('ai') { + @case ('assistant') {
{{ message.content }} - @for (tool of message.tool_calls ?? []; track tool.id) { + @for (tool of chat.toolCalls(); track tool.id) {
Called: {{ tool.name }}
@@ -460,14 +455,14 @@ import { agent } from '@ngaf/langgraph'; changeDetection: ChangeDetectionStrategy.OnPush, template: ` @for (msg of chat.messages(); track $index) { - @switch (msg._getType()) { - @case ('human') { + @switch (msg.role) { + @case ('user') {
{{ msg.content }}
} - @case ('ai') { + @case ('assistant') {
{{ msg.content }} - @for (tc of msg.tool_calls ?? []; track tc.id) { + @for (tc of chat.toolCalls(); track tc.id) { {{ tc.name }} }
@@ -491,7 +486,7 @@ export class ChatComponent { // Derived state from the Python agent's output toolsUsed = computed(() => this.chat.messages() - .filter(m => m._getType() === 'tool') + .filter(m => m.role === 'tool') .map(m => m.name) ); diff --git a/apps/website/content/docs/agent/concepts/langgraph-basics.mdx b/apps/website/content/docs/agent/concepts/langgraph-basics.mdx index b78bc25c0..639001c51 100644 --- a/apps/website/content/docs/agent/concepts/langgraph-basics.mdx +++ b/apps/website/content/docs/agent/concepts/langgraph-basics.mdx @@ -112,12 +112,12 @@ graph = builder.compile() ```typescript // This is all you need on the Angular side -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', }); // chat.messages() updates as the agent streams its response -// chat.status() tells you if it's idle, loading, or done +// chat.status() tells you if it's idle, running, or errored ``` @@ -167,7 +167,7 @@ const agent = agent({ }); // Watch tools execute -const activeTools = computed(() => agent.toolProgress()); +const activeTools = computed(() => agent.toolCalls()); const completedTools = computed(() => agent.toolCalls()); ``` @@ -204,7 +204,7 @@ const pendingAction = computed(() => agent.interrupt()); // User clicks approve → resume the agent approve() { - agent.submit(null, { resume: { approved: true } }); + agent.submit({ resume: { approved: true } }); } ``` @@ -235,7 +235,7 @@ const orchestrator = agent({ filterSubagentMessages: true, }); -const workers = computed(() => orchestrator.activeSubagents()); +const workers = computed(() => [...orchestrator.subagents().values()]); const workerCount = computed(() => workers().length); ``` @@ -309,10 +309,10 @@ Templates re-render automatically via OnPush change detection agent.value() // Signal — full state object // Conversation -agent.messages() // Signal — message history +agent.messages() // Signal — runtime-neutral message history // Lifecycle -agent.status() // Signal — idle/loading/done +agent.status() // Signal — idle/running/error agent.isLoading() // Signal — is the agent running? // Human-in-the-loop @@ -324,11 +324,9 @@ agent.langGraphHistory() // Signal — raw LangGraph checkpoints agent.branch() // Signal — time-travel branch agent.experimentalBranchTree() // Signal> — branch tree -agent.toolCalls() // Signal — tool results -agent.toolProgress() // Signal — active tool execution +agent.toolCalls() // Signal — tool call progress and results agent.queue() // Signal — pending enqueue runs agent.subagents() // Signal> — delegated agents -agent.activeSubagents() // Signal — running workers ``` diff --git a/apps/website/content/docs/agent/concepts/state-management.mdx b/apps/website/content/docs/agent/concepts/state-management.mdx index 3bcfe4f00..a0414c0a8 100644 --- a/apps/website/content/docs/agent/concepts/state-management.mdx +++ b/apps/website/content/docs/agent/concepts/state-management.mdx @@ -199,8 +199,8 @@ const score = computed(() => agent.value().analysis?.score ?? 0); const fileCount = computed(() => agent.value().files.length); const isDone = computed(() => agent.value().progress === 100); -// Direct messages access (shortcut for agent.value().messages) -const messages = agent.messages(); // Signal +// Runtime-neutral message projection for UI +const messages = agent.messages(); // Signal ``` ## State Updates During Streaming @@ -294,9 +294,9 @@ export class ChatComponent { }); // Convenience computed values from thread state - readonly messages = this.agent.messages; // Signal + readonly messages = this.agent.messages; // Signal readonly isLoading = this.agent.isLoading; // Signal - readonly interrupted = this.agent.interrupt; // Signal + readonly interrupted = this.agent.interrupt; // Signal // --- Application state (your Angular signals) --- readonly sidebarOpen = signal(true); @@ -313,7 +313,7 @@ export class ChatComponent { } approve() { - this.agent.submit(null, { resume: { approved: true } }); + this.agent.submit({ resume: { approved: true } }); } } ``` diff --git a/apps/website/content/docs/agent/getting-started/introduction.mdx b/apps/website/content/docs/agent/getting-started/introduction.mdx index afc1f58b0..9eb8b0560 100644 --- a/apps/website/content/docs/agent/getting-started/introduction.mdx +++ b/apps/website/content/docs/agent/getting-started/introduction.mdx @@ -11,17 +11,18 @@ This guide walks you through the complete workflow: build a LangGraph agent in P `agent()` is an Angular function that creates a reactive, streaming connection to a LangGraph agent. It returns an object whose properties are Angular Signals — meaning your templates update automatically as the agent streams responses, token by token. ```typescript -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', }); // Every property is a Signal — reactive, synchronous, no subscriptions -chat.messages() // Signal -chat.status() // Signal<'idle' | 'loading' | 'resolved' | 'error'> -chat.error() // Signal -chat.interrupt() // Signal -chat.history() // Signal -chat.langGraphHistory() // Signal +chat.messages(); // Message[] +chat.status(); // 'idle' | 'running' | 'error' +chat.isLoading(); // boolean +chat.error(); // unknown +chat.interrupt?.(); // AgentInterrupt | undefined +chat.history(); // AgentCheckpoint[] +chat.langGraphHistory(); // ThreadState[] ``` No RxJS. No manual subscriptions. No async pipes. Just Signals that work with Angular's `OnPush` change detection out of the box. @@ -155,9 +156,8 @@ export const appConfig: ApplicationConfig = { ```typescript // chat.component.ts -import { Component, signal, computed } from '@angular/core'; +import { ChangeDetectionStrategy, Component, signal, computed } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; @Component({ selector: 'app-chat', @@ -167,15 +167,14 @@ import type { BaseMessage } from '@langchain/core/messages'; export class ChatComponent { input = signal(''); - // Create the streaming resource — this is the core API - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', threadId: signal(localStorage.getItem('threadId')), onThreadId: (id) => localStorage.setItem('threadId', id), }); // Derived signals — compose with computed() - isStreaming = computed(() => this.chat.status() === 'loading'); + isStreaming = computed(() => this.chat.isLoading()); messageCount = computed(() => this.chat.messages().length); send() { diff --git a/apps/website/content/docs/agent/getting-started/quickstart.mdx b/apps/website/content/docs/agent/getting-started/quickstart.mdx index 9dabdcb83..de19d6134 100644 --- a/apps/website/content/docs/agent/getting-started/quickstart.mdx +++ b/apps/website/content/docs/agent/getting-started/quickstart.mdx @@ -43,7 +43,6 @@ Use `agent()` in a component field initializer. Every property on the returned r // chat.component.ts import { Component, ChangeDetectionStrategy, signal, computed } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; @Component({ selector: 'app-chat', @@ -54,13 +53,13 @@ export class ChatComponent { input = signal(''); // 'chat_agent' maps to the key in your langgraph.json "graphs" config - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', threadId: signal(localStorage.getItem('threadId')), onThreadId: (id) => localStorage.setItem('threadId', id), }); - isStreaming = computed(() => this.chat.status() === 'loading'); + isStreaming = computed(() => this.chat.isLoading()); send() { const msg = this.input(); diff --git a/apps/website/content/docs/agent/guides/deployment.mdx b/apps/website/content/docs/agent/guides/deployment.mdx index 9c26a0494..242da1dc4 100644 --- a/apps/website/content/docs/agent/guides/deployment.mdx +++ b/apps/website/content/docs/agent/guides/deployment.mdx @@ -355,8 +355,8 @@ Key metrics to track in production: Track stream health from your Angular app: ```typescript -const status = this.chat.status(); // 'idle' | 'streaming' | 'error' -const isStreaming = this.chat.isStreaming(); +const status = this.chat.status(); // 'idle' | 'running' | 'error' +const isStreaming = this.chat.isLoading(); // Log stream lifecycle for your APM tool effect(() => { diff --git a/apps/website/content/docs/agent/guides/interrupts.mdx b/apps/website/content/docs/agent/guides/interrupts.mdx index 08309de6b..6b19b50e8 100644 --- a/apps/website/content/docs/agent/guides/interrupts.mdx +++ b/apps/website/content/docs/agent/guides/interrupts.mdx @@ -143,7 +143,8 @@ import { signal, ChangeDetectionStrategy, } from '@angular/core'; -import { agent, BaseMessage } from '@ngaf/langgraph'; +import { agent } from '@ngaf/langgraph'; +import type { BaseMessage } from '@langchain/core/messages'; interface ApprovalPayload { action: string; @@ -186,13 +187,13 @@ export class ApprovalComponent { } approve() { - this.agent.submit(null, { + this.agent.submit({ resume: { approved: true }, }); } reject() { - this.agent.submit(null, { + this.agent.submit({ resume: { approved: false, reason: this.rejectionReason() || 'User rejected', @@ -352,7 +353,8 @@ import { computed, ChangeDetectionStrategy, } from '@angular/core'; -import { agent, BaseMessage } from '@ngaf/langgraph'; +import { agent } from '@ngaf/langgraph'; +import type { BaseMessage } from '@langchain/core/messages'; interface StepApproval { step_number: number; @@ -391,11 +393,11 @@ export class DeployApprovalComponent { allInterrupts = computed(() => this.agent.interrupts()); approveStep() { - this.agent.submit(null, { resume: { approved: true } }); + this.agent.submit({ resume: { approved: true } }); } abortDeploy() { - this.agent.submit(null, { + this.agent.submit({ resume: { approved: false, reason: 'Deployment aborted by user' }, }); } @@ -523,7 +525,7 @@ effect(() => { if (interrupt) { const sub = timer(5 * 60 * 1000).subscribe(() => { // Auto-reject after 5 minutes of inaction - this.agent.submit(null, { + this.agent.submit({ resume: { approved: false, reason: 'Approval timeout' }, }); }); diff --git a/apps/website/content/docs/agent/guides/memory.mdx b/apps/website/content/docs/agent/guides/memory.mdx index 371ed8be0..ad8ea128c 100644 --- a/apps/website/content/docs/agent/guides/memory.mdx +++ b/apps/website/content/docs/agent/guides/memory.mdx @@ -75,7 +75,8 @@ graph = builder.compile() ```typescript import { Component, computed, ChangeDetectionStrategy } from '@angular/core'; -import { agent, BaseMessage } from '@ngaf/langgraph'; +import { agent } from '@ngaf/langgraph'; +import type { BaseMessage } from '@langchain/core/messages'; interface AgentState { messages: BaseMessage[]; @@ -265,7 +266,8 @@ graph = builder.compile() ```typescript import { Component, computed, signal, ChangeDetectionStrategy } from '@angular/core'; -import { agent, BaseMessage } from '@ngaf/langgraph'; +import { agent } from '@ngaf/langgraph'; +import type { BaseMessage } from '@langchain/core/messages'; @Component({ selector: 'app-longterm-chat', @@ -275,7 +277,7 @@ import { agent, BaseMessage } from '@ngaf/langgraph'; export class LongTermChatComponent { // Each conversation gets a new thread, but the agent // remembers the user across all of them via the Store. - agent = agent<{ messages: BaseMessage[] }>({ + agent = agent({ assistantId: 'memory_agent', config: { configurable: { user_id: 'user_42' } }, }); diff --git a/apps/website/content/docs/agent/guides/persistence.mdx b/apps/website/content/docs/agent/guides/persistence.mdx index 90773a2d3..6386ebeb6 100644 --- a/apps/website/content/docs/agent/guides/persistence.mdx +++ b/apps/website/content/docs/agent/guides/persistence.mdx @@ -119,7 +119,7 @@ import { agent } from '@ngaf/langgraph'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChatComponent { - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', // Restore thread from localStorage on mount threadId: signal(localStorage.getItem('threadId')), @@ -178,7 +178,7 @@ export class ThreadListComponent { threads = signal(this.loadThreads()); activeThreadId = signal(null); - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', threadId: this.activeThreadId, onThreadId: (id) => { @@ -257,7 +257,7 @@ When you pass a Signal as `threadId`, agent() reacts to every change. Set the si ```typescript activeThreadId = signal(null); -chat = agent<{ messages: BaseMessage[] }>({ +chat = agent({ assistantId: 'chat_agent', threadId: this.activeThreadId, // Signal — switches reactively onThreadId: (id) => this.activeThreadId.set(id), diff --git a/apps/website/content/docs/agent/guides/streaming.mdx b/apps/website/content/docs/agent/guides/streaming.mdx index 64d7e8d62..71b9a28f9 100644 --- a/apps/website/content/docs/agent/guides/streaming.mdx +++ b/apps/website/content/docs/agent/guides/streaming.mdx @@ -60,7 +60,6 @@ async for event in graph.astream_events( ```typescript import { Component, computed, ChangeDetectionStrategy } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import { BaseMessage } from '@langchain/core/messages'; @Component({ selector: 'app-chat', @@ -68,11 +67,11 @@ import { BaseMessage } from '@langchain/core/messages'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChatComponent { - readonly chat = agent<{ messages: BaseMessage[] }>({ + readonly chat = agent({ assistantId: 'chat_agent', }); - readonly isStreaming = computed(() => this.chat.status() === 'loading'); + readonly isStreaming = computed(() => this.chat.isLoading()); send(text: string) { this.chat.submit({ message: text }); @@ -108,7 +107,7 @@ The `status()` signal reports the current lifecycle state of the SSE connection: No active stream. The resource is ready to accept a new message. - + Tokens are arriving over the SSE connection. Signal values update in real-time with each chunk. @@ -126,7 +125,7 @@ LangGraph supports three stream modes. Pass `streamMode` to control what each SS ```typescript // Receives the full agent state after every node execution. // Best for message-based chat interfaces. -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', streamMode: 'values', }); @@ -140,7 +139,7 @@ const chat = agent<{ messages: BaseMessage[] }>({ ```typescript // Streams individual message tokens as they are generated. // Best for token-by-token rendering with lowest perceived latency. -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', streamMode: 'messages', }); @@ -152,7 +151,7 @@ const chat = agent<{ messages: BaseMessage[] }>({ ```typescript // Emits raw LangGraph run events (on_chain_start, on_llm_stream, etc.). // Best for advanced observability or custom progress indicators. -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', streamMode: 'events', }); @@ -175,7 +174,6 @@ If the SSE connection drops or the agent throws, `status()` transitions to `'err ```typescript import { Component, computed, ChangeDetectionStrategy } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import { BaseMessage } from '@langchain/core/messages'; @Component({ selector: 'app-chat', @@ -183,7 +181,7 @@ import { BaseMessage } from '@langchain/core/messages'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChatComponent { - readonly chat = agent<{ messages: BaseMessage[] }>({ + readonly chat = agent({ assistantId: 'chat_agent', }); @@ -220,7 +218,7 @@ export class ChatComponent { By default Agent emits a signal update for every incoming SSE chunk. On fast connections this can trigger hundreds of renders per second. Use the `throttle` option to coalesce updates. ```typescript -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', // Batch incoming chunks and flush at most once every 50 ms throttle: 50, diff --git a/apps/website/content/docs/agent/guides/subgraphs.mdx b/apps/website/content/docs/agent/guides/subgraphs.mdx index 50382a966..74342a37f 100644 --- a/apps/website/content/docs/agent/guides/subgraphs.mdx +++ b/apps/website/content/docs/agent/guides/subgraphs.mdx @@ -88,7 +88,11 @@ export class OrchestratorComponent { subagentToolNames: ['research', 'analyze'], }); - readonly running = computed(() => this.orchestrator.activeSubagents()); + readonly running = computed(() => + [...this.orchestrator.subagents().values()].filter((subagent) => + subagent.status() === 'pending' || subagent.status() === 'running' + ) + ); readonly runningCount = computed(() => this.running().length); send(text: string) { @@ -114,7 +118,11 @@ const orchestrator = agent({ const subagents = computed(() => orchestrator.subagents()); // Only active ones -const running = computed(() => orchestrator.activeSubagents()); +const running = computed(() => + [...orchestrator.subagents().values()].filter((subagent) => + subagent.status() === 'pending' || subagent.status() === 'running' + ) +); const runningCount = computed(() => running().length); // Lookup helpers for common UI paths @@ -167,7 +175,7 @@ const pipelineStatus = computed(() => { return { total: entries.length, pending: entries.filter(([, a]) => a.status() === 'pending').length, - running: entries.filter(([, a]) => a.status() === 'loading').length, + running: entries.filter(([, a]) => a.status() === 'running').length, done: entries.filter(([, a]) => a.status() === 'complete').length, failed: entries.filter(([, a]) => a.status() === 'error').length, }; @@ -206,7 +214,7 @@ export class SubagentProgressComponent { {{ entry[1].status() }} - @if (entry[1].status() === 'loading') { + @if (entry[1].status() === 'running') { } diff --git a/apps/website/content/docs/agent/guides/testing.mdx b/apps/website/content/docs/agent/guides/testing.mdx index 795fb6935..0a3cc1c51 100644 --- a/apps/website/content/docs/agent/guides/testing.mdx +++ b/apps/website/content/docs/agent/guides/testing.mdx @@ -49,14 +49,13 @@ On the Angular side, MockAgentTransport replaces the real HTTP transport. Create ```typescript import { TestBed } from '@angular/core/testing'; import { MockAgentTransport, agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@ngaf/langgraph'; describe('ChatComponent', () => { it('should display agent messages', () => { const transport = new MockAgentTransport(); TestBed.runInInjectionContext(() => { - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', transport, }); @@ -89,7 +88,7 @@ import { agent } from '@ngaf/langgraph'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChatComponent { - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', }); @@ -104,7 +103,7 @@ export class ChatComponent { ## Scripted Event Sequences -Pass event batches to the constructor for sequential playback. Each call to `nextBatch()` advances one step — giving you frame-by-frame control over what the component sees. +Pass event batches to the constructor for sequential playback. Each call to `nextBatch()` returns one batch; emit that batch to advance what the component sees. ```typescript const transport = new MockAgentTransport([ @@ -115,7 +114,7 @@ const transport = new MockAgentTransport([ ]); TestBed.runInInjectionContext(() => { - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', transport, }); @@ -123,17 +122,17 @@ TestBed.runInInjectionContext(() => { chat.submit({ message: 'Explain signals' }); // Step through each batch - transport.nextBatch(); + transport.emit(transport.nextBatch()); expect(chat.messages()[0].content).toBe('Analyzing...'); - transport.nextBatch(); + transport.emit(transport.nextBatch()); expect(chat.messages()[0].content).toBe('Here is your answer.'); }); ``` ## Testing the Streaming Lifecycle -The most common test pattern verifies the full submit-to-resolved lifecycle: submit triggers loading, values arrive, and the status settles to resolved. +The most common test pattern verifies the full submit-to-idle lifecycle: submit sets the agent running, values arrive, and the status settles back to idle. @@ -143,14 +142,14 @@ import { TestBed } from '@angular/core/testing'; import { MockAgentTransport, agent } from '@ngaf/langgraph'; describe('streaming lifecycle', () => { - it('should transition through loading → values → resolved', () => { + it('should transition through running → values → idle', () => { const transport = new MockAgentTransport([ [{ type: 'values', messages: [{ role: 'assistant', content: 'Thinking...' }] }], [{ type: 'values', messages: [{ role: 'assistant', content: 'Done!' }] }], ]); TestBed.runInInjectionContext(() => { - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', transport, }); @@ -159,23 +158,23 @@ describe('streaming lifecycle', () => { expect(chat.status()).toBe('idle'); expect(chat.messages()).toEqual([]); - // Submit triggers loading + // Submit triggers running chat.submit({ message: 'Hello' }); - expect(chat.status()).toBe('loading'); + expect(chat.status()).toBe('running'); expect(chat.isLoading()).toBe(true); // First batch — partial response - transport.nextBatch(); + transport.emit(transport.nextBatch()); expect(chat.messages()[0].content).toBe('Thinking...'); - expect(chat.status()).toBe('loading'); + expect(chat.status()).toBe('running'); // Second batch — final response - transport.nextBatch(); + transport.emit(transport.nextBatch()); expect(chat.messages()[0].content).toBe('Done!'); // Stream completes - transport.complete(); - expect(chat.status()).toBe('resolved'); + transport.close(); + expect(chat.status()).toBe('idle'); expect(chat.isLoading()).toBe(false); }); }); @@ -202,7 +201,7 @@ import { agent } from '@ngaf/langgraph'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChatComponent { - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', }); @@ -231,7 +230,7 @@ describe('interrupt handling', () => { const transport = new MockAgentTransport(); TestBed.runInInjectionContext(() => { - const agent = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'approval_agent', transport, }); @@ -245,12 +244,12 @@ describe('interrupt handling', () => { ]); // Verify interrupt signal - expect(agent.interrupt()).toBeDefined(); - expect(agent.interrupt()?.value.action).toBe('delete_account'); - expect(agent.interrupt()?.value.risk).toBe('high'); + expect(chat.interrupt()).toBeDefined(); + expect(chat.interrupt()?.value.action).toBe('delete_account'); + expect(chat.interrupt()?.value.risk).toBe('high'); // User approves — resume the agent - agent.submit(null, { resume: { approved: true } }); + chat.submit({ resume: { approved: true } }); // Agent continues after approval transport.emit([ @@ -260,8 +259,8 @@ describe('interrupt handling', () => { }, ]); - expect(agent.interrupt()).toBeNull(); - expect(agent.messages()[0].content).toBe('Account deleted.'); + expect(chat.interrupt()).toBeUndefined(); + expect(chat.messages()[0].content).toBe('Account deleted.'); }); }); }); @@ -289,16 +288,16 @@ import { agent } from '@ngaf/langgraph'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ApprovalComponent { - agent = agent<{ messages: BaseMessage[] }>({ + agent = agent({ assistantId: 'approval_agent', }); approve() { - this.agent.submit(null, { resume: { approved: true } }); + this.agent.submit({ resume: { approved: true } }); } reject() { - this.agent.submit(null, { resume: { approved: false } }); + this.agent.submit({ resume: { approved: false } }); } } ``` @@ -322,7 +321,7 @@ describe('error handling', () => { const transport = new MockAgentTransport(); TestBed.runInInjectionContext(() => { - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', transport, }); @@ -343,7 +342,7 @@ describe('error handling', () => { const transport = new MockAgentTransport(); TestBed.runInInjectionContext(() => { - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', transport, }); @@ -389,7 +388,7 @@ import { agent } from '@ngaf/langgraph'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChatComponent { - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', }); private lastMessage = ''; @@ -420,7 +419,7 @@ describe('thread switching', () => { TestBed.runInInjectionContext(() => { const threadId = signal('thread_A'); - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', threadId, transport, @@ -453,7 +452,7 @@ describe('thread switching', () => { const transport = new MockAgentTransport(); TestBed.runInInjectionContext(() => { - const chat = agent<{ messages: BaseMessage[] }>({ + const chat = agent({ assistantId: 'test_agent', transport, }); diff --git a/apps/website/content/docs/agent/guides/time-travel.mdx b/apps/website/content/docs/agent/guides/time-travel.mdx index b99d4abad..db6947831 100644 --- a/apps/website/content/docs/agent/guides/time-travel.mdx +++ b/apps/website/content/docs/agent/guides/time-travel.mdx @@ -274,7 +274,7 @@ export class ReplayComponent { // Go back one step const previousCheckpoint = this.rawHistory()[history.length - 2]?.checkpoint; if (!previousCheckpoint) return; - this.agent.submit(undefined, { + this.agent.submit({}, { checkpoint: previousCheckpoint, }); } diff --git a/apps/website/content/docs/chat/api/provide-chat.mdx b/apps/website/content/docs/chat/api/provide-chat.mdx index d6343e1fe..71ba457cc 100644 --- a/apps/website/content/docs/chat/api/provide-chat.mdx +++ b/apps/website/content/docs/chat/api/provide-chat.mdx @@ -135,7 +135,7 @@ All chat components work without `provideChat()`. They use defaults: template: ``, }) export class SimpleChatComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'chat_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/components/chat-debug.mdx b/apps/website/content/docs/chat/components/chat-debug.mdx index 718ec6cc2..de77ac7f0 100644 --- a/apps/website/content/docs/chat/components/chat-debug.mdx +++ b/apps/website/content/docs/chat/components/chat-debug.mdx @@ -24,7 +24,6 @@ Use `ChatDebugComponent` during development to understand what your LangGraph ag ```typescript import { Component, signal, ChangeDetectionStrategy } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; import { ChatDebugComponent } from '@ngaf/chat'; @Component({ @@ -39,7 +38,7 @@ import { ChatDebugComponent } from '@ngaf/chat'; `, }) export class DebugPageComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'chat_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/components/chat-input.mdx b/apps/website/content/docs/chat/components/chat-input.mdx index 2fd227b3f..b0aee06cd 100644 --- a/apps/website/content/docs/chat/components/chat-input.mdx +++ b/apps/website/content/docs/chat/components/chat-input.mdx @@ -137,7 +137,6 @@ The component includes accessibility attributes: ```typescript import { Component, signal, ChangeDetectionStrategy } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; import { ChatInputComponent } from '@ngaf/chat'; @Component({ @@ -162,7 +161,7 @@ import { ChatInputComponent } from '@ngaf/chat'; `, }) export class InputDemoComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'chat_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/components/chat-interrupt-panel.mdx b/apps/website/content/docs/chat/components/chat-interrupt-panel.mdx index d7e123f9f..fbc52e0d8 100644 --- a/apps/website/content/docs/chat/components/chat-interrupt-panel.mdx +++ b/apps/website/content/docs/chat/components/chat-interrupt-panel.mdx @@ -123,7 +123,6 @@ const interrupt = getInterrupt(chatRef); // Interrupt | undefined ```typescript import { Component, signal, ChangeDetectionStrategy } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; import { ChatComponent, ChatInterruptPanelComponent } from '@ngaf/chat'; import type { InterruptAction } from '@ngaf/chat'; @@ -146,7 +145,7 @@ import type { InterruptAction } from '@ngaf/chat'; `, }) export class InterruptDemoComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'interrupt_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/components/chat-message-list.mdx b/apps/website/content/docs/chat/components/chat-message-list.mdx index ba45bdf30..a186cce46 100644 --- a/apps/website/content/docs/chat/components/chat-message-list.mdx +++ b/apps/website/content/docs/chat/components/chat-message-list.mdx @@ -98,30 +98,28 @@ The `getMessageType()` function maps a runtime-neutral `Message` role to a `Mess ```typescript import { getMessageType } from '@ngaf/chat'; -import type { BaseMessage } from '@langchain/core/messages'; const type = getMessageType(message); // 'human' | 'ai' | 'tool' | 'system' | 'function' ``` **Mapping logic:** -| Message type string | Returns | -|--------------------|---------| -| `'human'` | `'human'` | -| `'ai'` | `'ai'` | +| Runtime-neutral role | Returns | +|----------------------|---------| +| `'user'` | `'human'` | +| `'assistant'` | `'ai'` | | `'tool'` | `'tool'` | | `'system'` | `'system'` | -| `'function'` | `'function'` | | Any other value | `'ai'` (default fallback) | ## Working with Message Content -LangChain messages have a `content` property that can be either a `string` or a structured array. The library exports a `messageContent()` utility (used internally by compositions) that handles both cases: +Runtime-neutral messages have a `content` property that can be either a `string` or a structured array. The library exports a `messageContent()` utility (used internally by compositions) that handles both cases: ```typescript // If content is a string, returns it directly // If content is structured, serializes to JSON -function messageContent(message: BaseMessage): string +function messageContent(message: Message): string ``` For custom templates, you can access `message.content` directly and handle the type yourself: @@ -142,7 +140,6 @@ For custom templates, you can access `message.content` directly and handle the t import { Component, inject, ChangeDetectionStrategy, signal } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; import { ChatMessageListComponent, MessageTemplateDirective, @@ -187,7 +184,7 @@ import { export class MessagesDemoComponent { private sanitizer = inject(DomSanitizer); - chatAgent = agent<{ messages: BaseMessage[] }>({ + chatAgent = agent({ assistantId: 'chat_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/components/chat-subagent-card.mdx b/apps/website/content/docs/chat/components/chat-subagent-card.mdx index a1a2e2f2e..1f67b3e18 100644 --- a/apps/website/content/docs/chat/components/chat-subagent-card.mdx +++ b/apps/website/content/docs/chat/components/chat-subagent-card.mdx @@ -78,7 +78,6 @@ The `ChatSubagentsComponent` primitive iterates over active subagent streams fro ```typescript import { Component, signal, ChangeDetectionStrategy } from '@angular/core'; import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; import { ChatComponent, ChatSubagentsComponent, @@ -110,7 +109,7 @@ import { `, }) export class SubagentDemoComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'multi_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/components/chat.mdx b/apps/website/content/docs/chat/components/chat.mdx index 7ee2d73eb..5b9a2e5c4 100644 --- a/apps/website/content/docs/chat/components/chat.mdx +++ b/apps/website/content/docs/chat/components/chat.mdx @@ -35,7 +35,6 @@ If you need to customize the message layout, add components between sections, or import { Component, signal } from '@angular/core'; import { agent } from '@ngaf/langgraph'; import { ChatComponent } from '@ngaf/chat'; -import type { BaseMessage } from '@langchain/core/messages'; @Component({ selector: 'app-chat-page', @@ -48,7 +47,7 @@ import type { BaseMessage } from '@langchain/core/messages'; `, }) export class ChatPageComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'chat_agent', threadId: signal(null), }); @@ -100,7 +99,7 @@ When you pass a non-empty `threads` array, a sidebar appears on the left (hidden `, }) export class ChatWithThreadsComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'chat_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/chat/guides/generative-ui.mdx b/apps/website/content/docs/chat/guides/generative-ui.mdx index 613669be3..3fe8936de 100644 --- a/apps/website/content/docs/chat/guides/generative-ui.mdx +++ b/apps/website/content/docs/chat/guides/generative-ui.mdx @@ -26,7 +26,6 @@ Pass a `ViewRegistry` via the `[views]` input on `ChatComponent`: import { Component, signal } from '@angular/core'; import { agent } from '@ngaf/langgraph'; import { ChatComponent, views } from '@ngaf/chat'; -import type { BaseMessage } from '@langchain/core/messages'; import { WeatherCardComponent } from './weather-card.component'; import { ChartComponent } from './chart.component'; @@ -46,7 +45,7 @@ const myViews = views({ `, }) export class ChatPageComponent { - chatRef = agent<{ messages: BaseMessage[] }>({ + chatRef = agent({ assistantId: 'gen_ui_agent', threadId: signal(null), }); diff --git a/apps/website/content/docs/getting-started.mdx b/apps/website/content/docs/getting-started.mdx index 76151a849..471e916f1 100644 --- a/apps/website/content/docs/getting-started.mdx +++ b/apps/website/content/docs/getting-started.mdx @@ -38,7 +38,7 @@ import { agent } from 'angular'; `, }) export class ChatComponent { - chat = agent<{ messages: BaseMessage[] }>({ + chat = agent({ assistantId: 'chat_agent', }); } diff --git a/apps/website/content/prompts/getting-started.md b/apps/website/content/prompts/getting-started.md index 54ee943ea..cc201d7b6 100644 --- a/apps/website/content/prompts/getting-started.md +++ b/apps/website/content/prompts/getting-started.md @@ -4,7 +4,7 @@ Install: npm install @ngaf/langgraph@latest 1. In app.config.ts, add provideAgent({ apiUrl: 'http://localhost:2024' }) to the providers array. Import it from '@ngaf/langgraph'. -2. Create a ChatComponent that calls agent<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' }) in the constructor or as a field initializer. agent() MUST be called inside an Angular injection context — constructor or field initializer is correct; ngOnInit is not. +2. Create a ChatComponent that calls agent({ assistantId: 'chat_agent' }) in the constructor or as a field initializer. agent() MUST be called inside an Angular injection context — constructor or field initializer is correct; ngOnInit is not. 3. The component template should loop over chat.messages() using @for and render each message's content. Add an input field and a button that calls chat.submit({ message: inputValue }). diff --git a/apps/website/content/prompts/streaming.md b/apps/website/content/prompts/streaming.md index dce537582..7e9c764eb 100644 --- a/apps/website/content/prompts/streaming.md +++ b/apps/website/content/prompts/streaming.md @@ -2,12 +2,12 @@ Configure token-by-token streaming in my Angular component that uses angular. The component already has agent() set up. Now: -1. In the template, bind to chat.messages() with @for — each BaseMessage has a .content property. The template re-renders automatically as tokens arrive because messages() is a Signal. +1. In the template, bind to chat.messages() with @for — each runtime-neutral Message has role and content fields. The template re-renders automatically as tokens arrive because messages() is a Signal. 2. Show a loading indicator while streaming: use chat.isLoading() in an @if block. 3. To throttle rapid re-renders (if performance is a concern), pass throttle: 50 to agent() options — this throttles Signal updates to at most one per 50ms while preserving the final value. -4. To show the stream status more precisely, bind to chat.status() which returns 'idle' | 'loading' | 'resolved' | 'error'. +4. To show the stream status more precisely, bind to chat.status() which returns 'idle' | 'running' | 'error'. Use chat.isLoading() for loading UI. Do not use async pipe or subscribe() — the signals update automatically. diff --git a/apps/website/public/whitepapers/angular-preview.html b/apps/website/public/whitepapers/angular-preview.html index 96ddc9354..39548d3c0 100644 --- a/apps/website/public/whitepapers/angular-preview.html +++ b/apps/website/public/whitepapers/angular-preview.html @@ -92,7 +92,7 @@

Signal Architecture

  • `isLoading()` — Boolean signal indicating active stream processing
  • `error()` — The current error state, or `undefined` when healthy
  • `interrupt()` — `AgentInterrupt | undefined`, populated when the agent yields control for human input
  • -
  • `status()` — Granular connection state: `'idle'` | `'connecting'` | `'streaming'` | `'interrupted'` | `'error'`
  • +
  • `status()` — Runtime lifecycle state: `'idle'` | `'running'` | `'error'`; use `isLoading()` for loading UI
  • `toolCalls()` — Active tool invocations extracted from the message stream
  • `state()` — The current agent state object from the LangGraph thread
  • diff --git a/apps/website/public/whitepapers/angular.pdf b/apps/website/public/whitepapers/angular.pdf index 0f8da9ae0e8b2e7a69c3b17e9c43376524c8cabe..463d227cd4f750d7206b81555fb740d4a54d90f3 100644 GIT binary patch delta 140816 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¨Zt)K~ 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 delta 136656 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 NtL?TMH+g)k{{y8z5L*BM diff --git a/apps/website/scripts/generate-whitepaper.ts b/apps/website/scripts/generate-whitepaper.ts index a77ae6b4d..c0d20895f 100644 --- a/apps/website/scripts/generate-whitepaper.ts +++ b/apps/website/scripts/generate-whitepaper.ts @@ -16,7 +16,7 @@ const CURRENT_API_CONTEXT = `You are writing public technical whitepapers for Ca Use only the current API surface: - Package names are @ngaf/langgraph, @ngaf/render, @ngaf/chat, and @ngaf/ag-ui. - @ngaf/langgraph exposes agent(), provideAgent(), LangGraphAgent, MockAgentTransport, FetchStreamTransport, and mockLangGraphAgent(). -- agent() returns a runtime-neutral chat surface with messages(), status(), isLoading(), error(), toolCalls(), state(), submit(), stop(), regenerate(), interrupt(), subagents(), and LangGraph-specific langGraph* signals. interrupt() is AgentInterrupt | undefined on the runtime-neutral surface. +- agent() returns a runtime-neutral chat surface with messages(), status(), isLoading(), error(), toolCalls(), state(), submit(), stop(), regenerate(), interrupt(), subagents(), and LangGraph-specific langGraph* signals. status() returns only 'idle' | 'running' | 'error'. Use isLoading() for loading UI. interrupt() is AgentInterrupt | undefined on the runtime-neutral surface. - Configure LangGraph with assistantId and apiUrl. Do not use graphId or url as @ngaf/langgraph option names. - @ngaf/chat consumes the runtime-neutral Agent contract and exports ChatComponent, ChatMessageListComponent, ChatInputComponent, ChatToolCallsComponent, ChatToolCallCardComponent, ChatInterruptPanelComponent, and ChatDebugComponent. Selectors are , , , , , , and . - Chat messages use Message[] from @ngaf/chat for the runtime-neutral surface. Raw LangGraph messages, when needed, are exposed through langGraphMessages(). diff --git a/apps/website/src/components/landing/CodeBlock.tsx b/apps/website/src/components/landing/CodeBlock.tsx index 95ff070b7..ce2ebdfd7 100644 --- a/apps/website/src/components/landing/CodeBlock.tsx +++ b/apps/website/src/components/landing/CodeBlock.tsx @@ -5,7 +5,7 @@ const EXAMPLE = `// app.config.ts provideAgent({ apiUrl: 'http://localhost:2024' }) // chat.component.ts -const chat = agent<{ messages: BaseMessage[] }>({ +const chat = agent({ assistantId: 'chat_agent', threadId: signal(this.threadId), onThreadId: (id) => localStorage.setItem('threadId', id), diff --git a/apps/website/src/components/landing/ValueProps.tsx b/apps/website/src/components/landing/ValueProps.tsx index d36bced76..5f21c3984 100644 --- a/apps/website/src/components/landing/ValueProps.tsx +++ b/apps/website/src/components/landing/ValueProps.tsx @@ -14,8 +14,8 @@ const chat = agent({ }); // Every property is a Signal -const messages = chat.messages(); // Signal -const status = chat.status(); // Signal<'idle' | 'streaming'> +const messages = chat.messages(); // Signal +const status = chat.status(); // Signal<'idle' | 'running' | 'error'> const error = chat.error(); // Signal // Reactive composition @@ -53,20 +53,20 @@ const branches = agent.history();`, headline: 'Deterministic Agent Testing', description: 'MockAgentTransport lets you script exact event sequences and step through them in your specs. No flaky SSE connections, no timing issues, no running LangGraph server. Test agent behavior the same way you test any Angular service.', code: `// chat.component.spec.ts -const transport = new MockAgentTransport(); - -transport.script([ - { type: 'values', data: { messages: [aiMsg('Hello')] } }, - { type: 'values', data: { status: 'done' } }, +const transport = new MockAgentTransport([ + [{ type: 'values', messages: [aiMsg('Hello')] }], ]); -const chat = agent({ +const chat = agent({ transport, assistantId: 'test_agent', }); +transport.emit(transport.nextBatch()); +transport.close(); + expect(chat.messages()).toEqual([aiMsg('Hello')]); -expect(chat.status()).toBe('done');`, +expect(chat.status()).toBe('idle');`, lang: 'typescript' as const, }, ]; diff --git a/cockpit/deep-agents/filesystem/python/docs/guide.md b/cockpit/deep-agents/filesystem/python/docs/guide.md index e95fc610a..9d2cd5a66 100644 --- a/cockpit/deep-agents/filesystem/python/docs/guide.md +++ b/cockpit/deep-agents/filesystem/python/docs/guide.md @@ -7,7 +7,7 @@ sidebar displays each operation as it happens. -Add a file operations sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.messages()` to access tool call data, derive `toolCallEntries` with `computed()`, and bind them to the sidebar via the `` component from `@ngaf/chat`. +Add a file operations sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.messages()` to access tool call data, derive `toolCallEntries` with `computed()`, and bind them to the sidebar beside the `` component from `@ngaf/chat`. @@ -90,15 +90,12 @@ Tool calls appear inside AI messages as `tool_calls`. Each entry has a `name` (e
    -Use the `` component and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` -The `#sidebar` template is projected into the chat layout. Operations render reactively as the agent calls tools. +The sibling panel renders operations reactively as the agent calls tools. diff --git a/cockpit/deep-agents/memory/python/docs/guide.md b/cockpit/deep-agents/memory/python/docs/guide.md index 358226f2c..418dd1f96 100644 --- a/cockpit/deep-agents/memory/python/docs/guide.md +++ b/cockpit/deep-agents/memory/python/docs/guide.md @@ -5,7 +5,7 @@ Build a chat interface where the agent remembers facts about the user across tur -Add a memory sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.value()` to access the agent's `agent_memory` state, derive `memoryEntries` with `computed()`, and bind them to the sidebar via the `` component from `@ngaf/chat`. +Add a memory sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.value()` to access the agent's `agent_memory` state, derive `memoryEntries` with `computed()`, and bind them to the sidebar beside the `` component from `@ngaf/chat`. @@ -74,15 +74,12 @@ export class MemoryComponent { -Use the `` component and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` -The `#sidebar` template is projected into the chat layout. Memory entries render reactively as the agent learns new facts. +The sibling panel renders memory entries reactively as the agent learns new facts. diff --git a/cockpit/deep-agents/planning/python/docs/guide.md b/cockpit/deep-agents/planning/python/docs/guide.md index 30a762529..b6320ff4b 100644 --- a/cockpit/deep-agents/planning/python/docs/guide.md +++ b/cockpit/deep-agents/planning/python/docs/guide.md @@ -7,7 +7,7 @@ sidebar displays each step's status as the agent works through them. -Add a task planning sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.value()` to access the agent's plan state, derive `planSteps` with `computed()`, and bind them to the sidebar via the `` component from `@ngaf/chat`. +Add a task planning sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.value()` to access the agent's plan state, derive `planSteps` with `computed()`, and bind them to the sidebar beside the `` component from `@ngaf/chat`. @@ -81,15 +81,12 @@ export class PlanningComponent { -Use the `` component and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` -The `#sidebar` template is projected into the chat layout. Steps render reactively as the agent updates the plan state. +The sibling panel renders steps reactively as the agent updates the plan state. diff --git a/cockpit/deep-agents/sandboxes/python/docs/guide.md b/cockpit/deep-agents/sandboxes/python/docs/guide.md index c73d97a5d..886f30d95 100644 --- a/cockpit/deep-agents/sandboxes/python/docs/guide.md +++ b/cockpit/deep-agents/sandboxes/python/docs/guide.md @@ -7,7 +7,7 @@ sidebar displays each execution as a log entry with code input, stdout output, a -Add a code execution log sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.messages()` to access tool call data from the `run_code` tool, derive `executionLogs` with `computed()`, and bind them to the sidebar via the `` component from `@ngaf/chat`. +Add a code execution log sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.messages()` to access tool call data from the `run_code` tool, derive `executionLogs` with `computed()`, and bind them to the sidebar beside the `` component from `@ngaf/chat`. @@ -97,15 +97,12 @@ The tool result (`tc.output`) is populated after the tool finishes executing. Be -Use the `` component and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` Each log entry shows the code that was executed, the exit status badge, and the stdout output. diff --git a/cockpit/deep-agents/skills/python/docs/guide.md b/cockpit/deep-agents/skills/python/docs/guide.md index fd3ca9820..0e514f41b 100644 --- a/cockpit/deep-agents/skills/python/docs/guide.md +++ b/cockpit/deep-agents/skills/python/docs/guide.md @@ -7,7 +7,7 @@ summarizer) based on the user's request, and the sidebar displays each skill inv -Add a skill invocation sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.messages()` to access tool call data, derive `skillInvocations` with `computed()`, and bind them to the sidebar via the `` component from `@ngaf/chat`. +Add a skill invocation sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.messages()` to access tool call data, derive `skillInvocations` with `computed()`, and bind them to the sidebar beside the `` component from `@ngaf/chat`. @@ -94,15 +94,12 @@ Each tool call in an AI message maps to a skill invocation card. The `result` fi -Use the `` component and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` Each invocation card shows the skill name, input args, and result once available. diff --git a/cockpit/deep-agents/subagents/python/docs/guide.md b/cockpit/deep-agents/subagents/python/docs/guide.md index f2ec2ed32..888e6d10e 100644 --- a/cockpit/deep-agents/subagents/python/docs/guide.md +++ b/cockpit/deep-agents/subagents/python/docs/guide.md @@ -7,7 +7,7 @@ agents, and the sidebar displays each subagent's status and message count as the -Add a subagent activity sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.subagents()` to access the live Map of child agent streams, derive `subagentEntries` with `computed()`, and render them in the `` sidebar. +Add a subagent activity sidebar to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.subagents()` to access the live Map of child agent streams, derive `subagentEntries` with `computed()`, and render them beside the `` component. @@ -73,15 +73,12 @@ export class SubagentsComponent { -Use the `` component and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` Each `entry` is a `[toolCallId, SubagentStreamRef]` tuple. The tool call ID identifies which specialist was invoked; the ref's signals update in real time. diff --git a/cockpit/langgraph/durable-execution/python/docs/guide.md b/cockpit/langgraph/durable-execution/python/docs/guide.md index a5b7fc705..b0d7e5d08 100644 --- a/cockpit/langgraph/durable-execution/python/docs/guide.md +++ b/cockpit/langgraph/durable-execution/python/docs/guide.md @@ -8,7 +8,7 @@ status in real time and exposes a "Retry" button when errors occur. -Add a durable multi-step execution workflow to this Angular component using `agent()` from `@ngaf/langgraph`. Display `stream.status()` as a colour-coded badge, show a `stream.hasValue()` indicator, and render a "Retry" button that calls `stream.reload()` when `stream.error()` is set. Bind `stream.messages()` in the template via the `` component from `@ngaf/chat`. +Add a durable multi-step execution workflow to this Angular component using `agent()` from `@ngaf/langgraph`. Display `stream.status()` as a colour-coded badge, show a `stream.hasValue()` indicator, and render a "Retry" button that calls `stream.reload()` when `stream.error()` is set. Bind the conversation with `` from `@ngaf/chat`. @@ -55,7 +55,7 @@ export class DurableExecutionComponent { -Use `stream.status()` to display real-time execution state. The signal returns `'idle'`, `'loading'`, `'resolved'`, or `'error'`: +Use `stream.status()` to display real-time execution state. The signal returns `'idle'`, `'running'`, or `'error'`: ```html @@ -66,9 +66,8 @@ Use `stream.status()` to display real-time execution state. The signal returns ` ```typescript statusBadgeColor(): string { switch (this.stream.status()) { - case 'loading': - case 'reloading': return '#2563eb'; - case 'resolved': return '#16a34a'; + case 'running': return '#2563eb'; + case 'idle': return '#16a34a'; case 'error': return '#dc2626'; default: return '#6b7280'; } @@ -151,7 +150,7 @@ For production, replace `MemorySaver` with `PostgresCheckpointer` for durable pe -The `` component handles message rendering, input, loading states, and error display. Keep your component focused on status monitoring and retry logic. +The `` component handles message rendering, input, loading states, and error display. Keep your component focused on status monitoring and retry logic. diff --git a/cockpit/langgraph/interrupts/angular/src/app/interrupts.component.ts b/cockpit/langgraph/interrupts/angular/src/app/interrupts.component.ts index 1e943b9d3..09a63e329 100644 --- a/cockpit/langgraph/interrupts/angular/src/app/interrupts.component.ts +++ b/cockpit/langgraph/interrupts/angular/src/app/interrupts.component.ts @@ -12,12 +12,12 @@ import { ApprovalCardComponent } from './views/approval-card.component'; * * The LangGraph backend pauses execution when it needs human approval. * The `stream.interrupt()` signal provides the interrupt data, and - * `stream.submit(null)` resumes execution with the human's decision. + * `stream.submit({ resume })` resumes execution with the human's decision. * * Key integration points: * - `stream.interrupt()` — current pause data (undefined when not interrupted) * - `ChatInterruptPanelComponent` — renders the approval UI with action buttons - * - `stream.submit(null)` — resumes the graph (LangGraph convention) + * - `stream.submit({ resume })` — resumes the graph with a payload */ @Component({ selector: 'app-interrupts', @@ -54,8 +54,7 @@ export class InterruptsComponent { /** * Handle an interrupt action from the panel. * - * Submitting null resumes the graph unconditionally — this is the - * LangGraph convention for "proceed without modification". + * Submitting a resume payload continues the graph. * * In a production app, 'edit' would let the user modify the response * before approval, and 'respond' would send a reply payload. @@ -65,6 +64,6 @@ export class InterruptsComponent { // In a production app, 'edit' would let the user modify the response before approval. // For this demo, all actions simply resume the graph. void action; // Each branch intentionally does the same thing in this demo - void this.agent.submit({ resume: null }); + void this.agent.submit({ resume: true }); } } diff --git a/cockpit/langgraph/interrupts/python/docs/guide.md b/cockpit/langgraph/interrupts/python/docs/guide.md index 848da849e..322ce3cf5 100644 --- a/cockpit/langgraph/interrupts/python/docs/guide.md +++ b/cockpit/langgraph/interrupts/python/docs/guide.md @@ -7,7 +7,7 @@ and the frontend resumes it with `stream.submit()`. -Add human-in-the-loop approval to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.interrupt()` to display pending approvals, `stream.submit(null)` to approve and resume execution, and `stream.submit({ resume: false })` to reject. Bind `stream.messages()` in the template via the `` component from `@ngaf/chat`. +Add human-in-the-loop approval to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.interrupt()` to display pending approvals, `stream.submit({ resume: true })` to approve and resume execution, and `stream.submit({ resume: false })` to reject. Bind `stream.messages()` in the template via the `` component from `@ngaf/chat`. @@ -55,23 +55,17 @@ The resource automatically handles streaming, interrupt detection, and state man Use `stream.interrupt()` to conditionally show a pending approval in the sidebar: ```html - - - @if (stream.interrupt()) { -
    -

    {{ stream.interrupt() }}

    - - -
    - } @else { -

    No pending approvals

    - } -
    -
    + + +@if (stream.interrupt(); as interrupt) { + +} @else { +

    No pending approvals

    +} ``` When the graph pauses, `stream.interrupt()` returns the interrupt payload. When no interrupt is active, it returns a falsy value. @@ -83,7 +77,7 @@ Add methods that resume graph execution with the user's decision: ```typescript approve(): void { - this.stream.submit(null); + this.stream.submit({ resume: true }); } reject(): void { @@ -91,7 +85,7 @@ reject(): void { } ``` -Submitting `null` is the LangGraph convention for continuing past an interrupt. Submitting `{ resume: false }` signals rejection so the graph can handle it accordingly. +Submitting a `resume` payload continues past an interrupt. Submitting `{ resume: false }` signals rejection so the graph can handle it accordingly. You can extend this pattern to pass structured data back to the graph. For example, `stream.submit({ resume: true, edits: { ... } })` lets the user modify the response before approving. @@ -141,7 +135,7 @@ A checkpointer is required for interrupts to work. Without it, the graph cannot
    -The `` component handles message rendering, input, loading states, and error display. Focus your component on interrupt handling logic. +The `` component handles message rendering, input, loading states, and error display. Focus your component on interrupt handling logic. diff --git a/cockpit/langgraph/memory/python/docs/guide.md b/cockpit/langgraph/memory/python/docs/guide.md index 2adc9a14b..23d716c27 100644 --- a/cockpit/langgraph/memory/python/docs/guide.md +++ b/cockpit/langgraph/memory/python/docs/guide.md @@ -8,7 +8,7 @@ and displays it in a live sidebar. -Add persistent agent memory to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.value()` to access the `memory` field in graph state, derive a reactive `memoryEntries` signal with Angular's `computed()`, and render the facts in a sidebar panel via the `` component from `@ngaf/chat`. +Add persistent agent memory to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.value()` to access the `memory` field in graph state, derive a reactive `memoryEntries` signal with Angular's `computed()`, and render the facts in a sidebar panel beside the `` component from `@ngaf/chat`. @@ -75,15 +75,12 @@ Cast the return type of `stream.value()` to your state shape to get proper type
    -Use the `` component and project the memory panel via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling memory panel: ```html - - + + +
    } - - + ``` Facts appear in the sidebar in real time as the agent learns them. diff --git a/cockpit/langgraph/persistence/python/docs/guide.md b/cockpit/langgraph/persistence/python/docs/guide.md index d22cc38fb..96f7e79c7 100644 --- a/cockpit/langgraph/persistence/python/docs/guide.md +++ b/cockpit/langgraph/persistence/python/docs/guide.md @@ -7,7 +7,7 @@ can be resumed using `stream.switchThread(id)`. -Add thread persistence to this Angular component using `agent()` from `@ngaf/langgraph`. Use the `onThreadId` callback to capture thread IDs, `stream.switchThread(id)` to resume conversations, and `stream.switchThread(null)` to start fresh. Bind `stream.messages()` in the template via the `` component from `@ngaf/chat`. +Add thread persistence to this Angular component using `agent()` from `@ngaf/langgraph`. Use the `onThreadId` callback to capture thread IDs, `stream.switchThread(id)` to resume conversations, and `stream.switchThread(null)` to start fresh. Bind `stream.messages()` in the template beside the `` component from `@ngaf/chat`. @@ -63,15 +63,12 @@ Store thread IDs in `localStorage` to survive full page reloads. On app init, re -Use the `` component from `@ngaf/chat` and project a sidebar via `ng-template`: +Use the `` component from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` -The `#sidebar` template is projected into the chat layout, giving you a thread picker alongside the conversation. +The sibling panel gives you a thread picker alongside the conversation. @@ -144,7 +140,7 @@ For production, replace `MemorySaver` with `PostgresCheckpointer` for durable pe -The `` component handles message rendering, input, loading states, and error display. Focus your component on thread management logic. +The `` component handles message rendering, input, loading states, and error display. Focus your component on thread management logic. diff --git a/cockpit/langgraph/streaming/python/docs/guide.md b/cockpit/langgraph/streaming/python/docs/guide.md index 989ff85ab..11c196c3a 100644 --- a/cockpit/langgraph/streaming/python/docs/guide.md +++ b/cockpit/langgraph/streaming/python/docs/guide.md @@ -57,7 +57,7 @@ Use Angular's control flow to render messages reactively: ```html @for (msg of stream.messages(); track $index) { -
    +
    {{ msg.content }}
    } @@ -125,4 +125,3 @@ Never expose your LangSmith API key in client-side code. Use server-side environ - [Chat Messages](/chat/core-capabilities/messages/overview/python) — Learn how ChatMessagesComponent renders messages - [Chat Input](/chat/core-capabilities/input/overview/python) — Explore ChatInputComponent for message submission - diff --git a/cockpit/langgraph/subgraphs/python/docs/guide.md b/cockpit/langgraph/subgraphs/python/docs/guide.md index ba4e0c1b0..c4abd5f4d 100644 --- a/cockpit/langgraph/subgraphs/python/docs/guide.md +++ b/cockpit/langgraph/subgraphs/python/docs/guide.md @@ -7,7 +7,7 @@ subgraph, and the sidebar tracks each subagent's status in real time using `stre -Add a subgraph-powered orchestrator to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.subagents()` to track active child subgraph executions, and derive a `subagentEntries` signal with `computed()` for template iteration. Bind `stream.messages()` via the `` component from `@ngaf/chat`. +Add a subgraph-powered orchestrator to this Angular component using `agent()` from `@ngaf/langgraph`. Use `stream.subagents()` to track active child subgraph executions, and derive a `subagentEntries` signal with `computed()` for template iteration. Bind `stream.messages()` beside the `` component from `@ngaf/chat`. @@ -53,15 +53,12 @@ export class SubgraphsComponent { -Use `` from `@ngaf/chat` and project a sidebar via `ng-template`: +Use `` from `@ngaf/chat` and render a sibling sidebar: ```html - - + + + ``` -The `@empty` block renders when no subagents are active. Each entry shows a truncated run ID and the current status (`'running'`, `'done'`, or `'error'`). +The `@empty` block renders when no subagents are active. Each entry shows a truncated run ID and the current status (`'pending'`, `'running'`, `'complete'`, or `'error'`). Use `computed()` to derive `subagentEntries` from the Map. This ensures Angular's change detection picks up updates when subagents are added or their status changes. @@ -124,7 +120,7 @@ Child subgraphs can have their own state, checkpointers, and tools. This pattern -The `` component handles message rendering, input, loading states, and error display. Focus your component on subagent tracking logic. +The `` component handles message rendering, input, loading states, and error display. Focus your component on subagent tracking logic. diff --git a/cockpit/langgraph/time-travel/python/docs/guide.md b/cockpit/langgraph/time-travel/python/docs/guide.md index 6acd58509..542343e21 100644 --- a/cockpit/langgraph/time-travel/python/docs/guide.md +++ b/cockpit/langgraph/time-travel/python/docs/guide.md @@ -54,12 +54,9 @@ Use `stream.history()` to render checkpoints and `stream.branch()` to highlight the active one: ```html - - + + + ``` Each entry in `stream.history()` is a `ThreadState` snapshot with a diff --git a/libs/cockpit-docs/project.json b/libs/cockpit-docs/project.json index e20e63948..d0cd10fa2 100644 --- a/libs/cockpit-docs/project.json +++ b/libs/cockpit-docs/project.json @@ -6,6 +6,7 @@ "targets": { "build": { "executor": "@nx/js:tsc", + "dependsOn": ["^build"], "outputs": ["{workspaceRoot}/dist/libs/cockpit-docs"], "options": { "outputPath": "dist/libs/cockpit-docs", diff --git a/libs/cockpit-docs/src/lib/docs-bundle.ts b/libs/cockpit-docs/src/lib/docs-bundle.ts index 568829766..5333ee214 100644 --- a/libs/cockpit-docs/src/lib/docs-bundle.ts +++ b/libs/cockpit-docs/src/lib/docs-bundle.ts @@ -3,7 +3,7 @@ import { type CockpitLanguage, type CockpitPageId, type CockpitProduct, -} from '../../../cockpit-registry/src/index'; +} from '@ngaf/cockpit-registry'; export interface DocsBundle { product: CockpitProduct; diff --git a/libs/cockpit-docs/tsconfig.json b/libs/cockpit-docs/tsconfig.json index 190834ef3..a29e3d9a4 100644 --- a/libs/cockpit-docs/tsconfig.json +++ b/libs/cockpit-docs/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": false, - "emitDeclarationOnly": false, - "baseUrl": "." + "emitDeclarationOnly": false }, "files": [], "include": [], diff --git a/libs/langgraph/src/lib/agent.fn.ts b/libs/langgraph/src/lib/agent.fn.ts index b173cb447..af7b84b5e 100644 --- a/libs/langgraph/src/lib/agent.fn.ts +++ b/libs/langgraph/src/lib/agent.fn.ts @@ -71,7 +71,7 @@ import { extractCitations } from './internals/extract-citations'; * in real time as LangGraph streams messages, values, tool calls, interrupts, * subagent state, and checkpoint history. * - * @typeParam T - The state shape returned by the agent (e.g., `{ messages: BaseMessage[] }`) + * @typeParam T - The state shape returned by the agent * @typeParam Bag - Optional bag template for typed interrupts and submit payloads * @param options - Configuration for the LangGraph agent * @returns A {@link LangGraphAgent} with reactive signals and action methods @@ -79,7 +79,7 @@ import { extractCitations } from './internals/extract-citations'; * @example * ```typescript * // In a component field initializer - * const chat = agent<{ messages: BaseMessage[] }>({ + * const chat = agent({ * assistantId: 'chat_agent', * apiUrl: 'http://localhost:2024', * threadId: signal(this.savedThreadId), diff --git a/libs/langgraph/src/lib/transport/mock-stream.transport.ts b/libs/langgraph/src/lib/transport/mock-stream.transport.ts index 56db5d2e4..4e0ad3ed0 100644 --- a/libs/langgraph/src/lib/transport/mock-stream.transport.ts +++ b/libs/langgraph/src/lib/transport/mock-stream.transport.ts @@ -11,8 +11,8 @@ import type { ThreadState } from '@langchain/langgraph-sdk'; * @example * ```typescript * const transport = new MockAgentTransport([ - * [{ type: 'values', data: { messages: [aiMsg('Hello')] } }], - * [{ type: 'values', data: { status: 'done' } }], + * [{ type: 'values', messages: [aiMsg('Hello')] }], + * [{ type: 'values', messages: [aiMsg('Done')] }], * ]); * ``` */ @@ -37,7 +37,7 @@ export class MockAgentTransport implements AgentTransport { this.script = script; } - /** Advance to the next scripted batch and return its events. */ + /** Advance to the next scripted batch. Pass the returned events to `emit()`. */ nextBatch(): StreamEvent[] { if (this.scriptIndex >= this.script.length) return []; return this.script[this.scriptIndex++]; diff --git a/package-lock.json b/package-lock.json index 591417529..0eeacfdaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,6 @@ "@cacheplane/partial-markdown": "^0.3.0", "@langchain/core": "^1.1.33", "@langchain/langgraph-sdk": "^1.7.4", - "@modelcontextprotocol/sdk": "^1.27.1", "@noble/ed25519": "^2.3.0", "drizzle-orm": "^0.45.2", "framer-motion": "^12.38.0", @@ -8456,6 +8455,7 @@ "version": "1.19.11", "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "dev": true, "license": "MIT", "engines": { "node": ">=18.14.1" @@ -10544,323 +10544,6 @@ "react": ">=16" } }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", - "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", - "license": "MIT", - "dependencies": { - "@hono/node-server": "^1.19.9", - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", - "express": "^5.2.1", - "express-rate-limit": "^8.2.1", - "hono": "^4.11.4", - "jose": "^6.1.3", - "json-schema-typed": "^8.0.2", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@cfworker/json-schema": "^4.1.1", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "@cfworker/json-schema": { - "optional": true - }, - "zod": { - "optional": false - } - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/@module-federation/bridge-react-webpack-plugin": { "version": "0.21.6", "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.21.6.tgz", @@ -12095,10 +11778,6 @@ "node": ">= 10" } }, - "node_modules/@ngaf/langgraph-mcp": { - "resolved": "packages/mcp", - "link": true - }, "node_modules/@ngaf/minting-service": { "resolved": "apps/minting-service", "link": true @@ -22972,6 +22651,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -22988,6 +22668,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -24365,6 +24046,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -24473,6 +24155,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -24486,6 +24169,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -25243,6 +24927,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25269,6 +24954,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25385,6 +25071,7 @@ "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "dev": true, "license": "MIT", "dependencies": { "object-assign": "^4", @@ -26134,6 +25821,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -27080,6 +26768,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -27222,6 +26911,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, "license": "MIT" }, "node_modules/ejs": { @@ -27268,6 +26958,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -27414,6 +27105,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -27423,6 +27115,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -27439,6 +27132,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -27564,6 +27258,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -28012,6 +27707,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -28057,6 +27753,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "dev": true, "license": "MIT", "dependencies": { "eventsource-parser": "^3.0.1" @@ -28069,6 +27766,7 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "dev": true, "license": "MIT", "engines": { "node": ">=18.0.0" @@ -28179,6 +27877,7 @@ "version": "8.3.1", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "dev": true, "license": "MIT", "dependencies": { "ip-address": "10.1.0" @@ -28316,6 +28015,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, "license": "MIT" }, "node_modules/fast-fifo": { @@ -28372,6 +28072,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, "funding": [ { "type": "github", @@ -29018,6 +28719,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -29153,6 +28855,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -29215,6 +28918,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -29252,6 +28956,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -29495,6 +29200,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -29754,6 +29460,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -29782,6 +29489,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -30026,6 +29734,7 @@ "version": "4.12.8", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz", "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==", + "dev": true, "license": "MIT", "engines": { "node": ">=16.9.0" @@ -30249,6 +29958,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -30551,6 +30261,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -30590,6 +30301,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 12" @@ -31203,6 +30915,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz", "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -31531,12 +31244,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, "license": "MIT" }, "node_modules/json-schema-typed": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, "license": "BSD-2-Clause" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -33112,6 +32827,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -35542,6 +35258,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -35551,6 +35268,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -35591,6 +35309,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -35613,6 +35332,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -36151,6 +35871,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -36451,6 +36172,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=16.20.0" @@ -37751,6 +37473,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -37764,6 +37487,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -37959,6 +37683,7 @@ "version": "6.14.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -38038,6 +37763,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -38506,6 +38232,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -38970,6 +38697,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -38986,12 +38714,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, "license": "MIT" }, "node_modules/router/node_modules/path-to-regexp": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -39079,6 +38809,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, "license": "MIT" }, "node_modules/sass": { @@ -39846,6 +39577,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, "license": "ISC" }, "node_modules/shallow-clone": { @@ -39963,6 +39695,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -39982,6 +39715,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -39998,6 +39732,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -40016,6 +39751,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -40507,6 +40243,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -41460,6 +41197,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -42258,6 +41996,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -42393,6 +42132,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -43455,6 +43195,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, "node_modules/ws": { @@ -43732,6 +43473,7 @@ "version": "3.25.1", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "dev": true, "license": "ISC", "peerDependencies": { "zod": "^3.25 || ^4" @@ -43746,20 +43488,6 @@ "type": "github", "url": "https://github.com/sponsors/wooorm" } - }, - "packages/mcp": { - "name": "@ngaf/langgraph-mcp", - "version": "0.0.1", - "license": "MIT", - "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.0" - }, - "bin": { - "langgraph-mcp": "src/index.js" - }, - "devDependencies": { - "typescript": "^5.4.0" - } } } } diff --git a/package.json b/package.json index a8f24acfb..1adf24e63 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,6 @@ "@cacheplane/partial-markdown": "^0.3.0", "@langchain/core": "^1.1.33", "@langchain/langgraph-sdk": "^1.7.4", - "@modelcontextprotocol/sdk": "^1.27.1", "@noble/ed25519": "^2.3.0", "drizzle-orm": "^0.45.2", "framer-motion": "^12.38.0", diff --git a/packages/mcp/package-smoke.test.mjs b/packages/mcp/package-smoke.test.mjs deleted file mode 100644 index 219e16e53..000000000 --- a/packages/mcp/package-smoke.test.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import test from 'node:test'; -import assert from 'node:assert/strict'; -import fs from 'node:fs'; -import os from 'node:os'; -import path from 'node:path'; -import { createRequire } from 'node:module'; -import { fileURLToPath } from 'node:url'; - -const require = createRequire(import.meta.url); -const workspaceRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); -const outputRoot = path.join(workspaceRoot, 'dist/packages/mcp'); -const projectJsonPath = path.join(workspaceRoot, 'packages/mcp/project.json'); -const packageJsonPath = path.join(outputRoot, 'package.json'); - -test('source package manifest entrypoints exist locally', () => { - const packageJson = require('./package.json'); - const binPath = packageJson.bin['@ngaf/langgraph-mcp']; - - assert.equal(fs.existsSync(path.join(workspaceRoot, 'packages/mcp', packageJson.main)), true); - assert.equal(fs.existsSync(path.join(workspaceRoot, 'packages/mcp', binPath)), true); -}); - -function loadBuiltPackageJson() { - return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); -} - -test('built package manifest entrypoints resolve inside Nx output', () => { - const packageJson = loadBuiltPackageJson(); - const binPath = packageJson.bin['@ngaf/langgraph-mcp']; - - assert.equal(fs.existsSync(path.join(outputRoot, packageJson.main)), true); - assert.equal(fs.existsSync(path.join(outputRoot, binPath)), true); - assert.equal(fs.existsSync(path.join(outputRoot, packageJson.types)), true); -}); - -test('built package can discover bundled api docs from package root', () => { - const loaderPath = path.join(outputRoot, 'src/data/loader.js'); - const originalCwd = process.cwd(); - const tempCwd = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-package-smoke-')); - - process.chdir(tempCwd); - - try { - delete require.cache[require.resolve(loaderPath)]; - const { getAllSymbolNames } = require(loaderPath); - - assert.equal(fs.existsSync(path.join(outputRoot, 'api-docs.json')), true); - assert.equal(fs.existsSync(path.join(tempCwd, 'api-docs.json')), false); - assert.equal(fs.existsSync(path.join(tempCwd, 'apps/website/public/api-docs.json')), false); - assert.equal(getAllSymbolNames().includes('agent'), true); - } finally { - process.chdir(originalCwd); - fs.rmSync(tempCwd, { recursive: true, force: true }); - } -}); - -test('project declares a named MCP smoke target', () => { - const projectJson = JSON.parse(fs.readFileSync(projectJsonPath, 'utf8')); - - assert.equal(projectJson.targets.test.executor, 'nx:run-commands'); - assert.deepEqual(projectJson.targets.test.dependsOn, ['build']); - assert.equal(projectJson.targets.test.options.command, 'npm --prefix packages/mcp run smoke'); -}); diff --git a/packages/mcp/package.json b/packages/mcp/package.json deleted file mode 100644 index 3073dbc0b..000000000 --- a/packages/mcp/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@ngaf/langgraph-mcp", - "version": "0.0.1", - "private": true, - "description": "MCP server for the @ngaf/langgraph library", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/cacheplane/angular-agent-framework.git", - "directory": "packages/mcp" - }, - "homepage": "https://github.com/cacheplane/angular-agent-framework#readme", - "bugs": { - "url": "https://github.com/cacheplane/angular-agent-framework/issues" - }, - "main": "src/index.js", - "bin": { - "@ngaf/langgraph-mcp": "src/index.js" - }, - "scripts": { - "build": "tsc -p tsconfig.json", - "smoke": "node --test package-smoke.test.mjs", - "start": "node src/index.js" - }, - "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.0" - }, - "devDependencies": { - "typescript": "^5.4.0" - } -} diff --git a/packages/mcp/project.json b/packages/mcp/project.json deleted file mode 100644 index f2dd8a732..000000000 --- a/packages/mcp/project.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "mcp", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "packages/mcp/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nx/js:tsc", - "outputs": ["{workspaceRoot}/dist/packages/mcp"], - "options": { - "outputPath": "dist/packages/mcp", - "main": "packages/mcp/src/index.ts", - "tsConfig": "packages/mcp/tsconfig.json", - "assets": [ - { - "input": "apps/website/content/docs/agent/api", - "glob": "api-docs.json", - "output": "." - } - ] - } - }, - "test": { - "executor": "nx:run-commands", - "dependsOn": ["build"], - "options": { - "command": "npm --prefix packages/mcp run smoke" - } - } - } -} diff --git a/packages/mcp/src/data/loader.ts b/packages/mcp/src/data/loader.ts deleted file mode 100644 index b692c115a..000000000 --- a/packages/mcp/src/data/loader.ts +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT -import fs from 'fs'; -import path from 'path'; - -export interface ApiDocsJson { - children?: ApiSymbol[]; -} - -export interface ApiSymbol { - name: string; - kind?: string; - kindString?: string; - description?: string; - params?: { - name: string; - type?: string; - description?: string; - }[]; - comment?: { summary?: { text: string }[] }; - signatures?: { - parameters?: { - name: string; - type: { name?: string }; - comment?: { summary?: { text: string }[] }; - }[]; - }[]; -} - -let cachedDocs: ApiDocsJson | null = null; - -export function getApiDocs(): ApiDocsJson { - if (cachedDocs) return cachedDocs; - const candidates = [ - path.join(__dirname, '../../api-docs.json'), - path.join(__dirname, '../../../../apps/website/content/docs/agent/api/api-docs.json'), - ]; - for (const p of candidates) { - if (fs.existsSync(p)) { - const parsed = JSON.parse(fs.readFileSync(p, 'utf8')) as ApiDocsJson | ApiSymbol[]; - cachedDocs = Array.isArray(parsed) ? { children: parsed } : parsed; - return cachedDocs; - } - } - return { children: [] }; -} - -export function findSymbol(name: string): ApiSymbol | undefined { - const docs = getApiDocs(); - return docs.children?.find((c) => c.name === name); -} - -export function getAllSymbolNames(): string[] { - return getApiDocs().children?.map((c) => c.name) ?? []; -} diff --git a/packages/mcp/src/index.js b/packages/mcp/src/index.js deleted file mode 100755 index b46a53639..000000000 --- a/packages/mcp/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node -const { spawnSync } = require('node:child_process'); -const path = require('node:path'); - -const entrypoint = path.join(__dirname, 'index.ts'); -const result = spawnSync( - process.execPath, - ['--import', 'tsx', entrypoint, ...process.argv.slice(2)], - { stdio: 'inherit' } -); - -if (result.error) { - throw result.error; -} - -process.exit(result.status ?? 1); diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts deleted file mode 100644 index 6c217b6ac..000000000 --- a/packages/mcp/src/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env node -// SPDX-License-Identifier: MIT -import { Server } from '@modelcontextprotocol/sdk/server/index.js'; -import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; -import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; -import { getApiReferenceTool, handleGetApiReference } from './tools/get-api-reference.js'; -import { searchDocsTool, handleSearchDocs } from './tools/search-docs.js'; -import { getExampleTool, handleGetExample } from './tools/get-example.js'; -import { scaffoldChatComponentTool, handleScaffoldChatComponent } from './tools/scaffold-chat-component.js'; -import { addAgentTool, handleAddAgent } from './tools/add-agent.js'; -import { getThreadPersistencePatternTool, handleGetThreadPersistencePattern } from './tools/get-thread-persistence-pattern.js'; - -const server = new Server( - { name: 'angular', version: '0.1.0' }, - { capabilities: { tools: {} } } -); - -const TOOLS = [ - getApiReferenceTool, - searchDocsTool, - getExampleTool, - scaffoldChatComponentTool, - addAgentTool, - getThreadPersistencePatternTool, -]; - -server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS })); - -server.setRequestHandler(CallToolRequestSchema, async (req) => { - const { name, arguments: args } = req.params; - const a = (args ?? {}) as Record; - switch (name) { - case 'get_api_reference': return handleGetApiReference(a); - case 'search_docs': return handleSearchDocs(a); - case 'get_example': return handleGetExample(a); - case 'scaffold_chat_component': return handleScaffoldChatComponent(a); - case 'add_angular': return handleAddAgent(a); - case 'get_thread_persistence_pattern': return handleGetThreadPersistencePattern(a); - default: return { content: [{ type: 'text', text: `Unknown tool: ${name}` }] }; - } -}); - -async function main() { - const transport = new StdioServerTransport(); - await server.connect(transport); -} - -main().catch(console.error); diff --git a/packages/mcp/src/tools/add-agent.ts b/packages/mcp/src/tools/add-agent.ts deleted file mode 100644 index f210af151..000000000 --- a/packages/mcp/src/tools/add-agent.ts +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -import fs from 'fs'; - -export const addAgentTool = { - name: 'add_angular', - description: 'Generate npm install command and app.config.ts diff to add angular', - inputSchema: { - type: 'object', - properties: { - appConfigPath: { type: 'string', description: 'Path to app.config.ts' }, - }, - required: ['appConfigPath'], - }, -}; - -export function handleAddAgent(args: Record) { - const appConfigPath = args['appConfigPath'] as string; - - if (!fs.existsSync(appConfigPath)) { - return { content: [{ type: 'text', text: `File not found or is not an Angular app.config.ts: ${appConfigPath}` }] }; - } - const content = fs.readFileSync(appConfigPath, 'utf8'); - if (!content.includes('ApplicationConfig') && !content.includes('appConfig')) { - return { content: [{ type: 'text', text: `File does not appear to be an Angular app.config.ts: ${appConfigPath}` }] }; - } - - const result = `Steps to add angular: - -1. Install the package: -\`\`\`bash -npm install @ngaf/langgraph -\`\`\` - -2. Apply this change to ${appConfigPath}: -\`\`\`diff -+import { provideAgent } from '@ngaf/langgraph'; - - export const appConfig: ApplicationConfig = { - providers: [ -+ provideAgent({ apiUrl: 'REPLACE_WITH_YOUR_LANGGRAPH_URL' }), - // ... existing providers - ] - }; -\`\`\` - -Replace REPLACE_WITH_YOUR_LANGGRAPH_URL with your LangGraph server URL (e.g. http://localhost:2024).`; - - return { content: [{ type: 'text', text: result }] }; -} diff --git a/packages/mcp/src/tools/get-api-reference.ts b/packages/mcp/src/tools/get-api-reference.ts deleted file mode 100644 index 0ae2a1226..000000000 --- a/packages/mcp/src/tools/get-api-reference.ts +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -import { findSymbol, getAllSymbolNames } from '../data/loader.js'; - -export const getApiReferenceTool = { - name: 'get_api_reference', - description: 'Get the full API documentation for a angular symbol', - inputSchema: { - type: 'object', - properties: { symbol: { type: 'string', description: 'Symbol name, e.g. "agent"' } }, - required: ['symbol'], - }, -}; - -export function handleGetApiReference(args: Record) { - const symbol = args['symbol'] as string; - const entry = findSymbol(symbol); - if (!entry) { - return { content: [{ type: 'text', text: `Symbol not found: "${symbol}". Available: ${getAllSymbolNames().join(', ')}` }] }; - } - const summary = entry.description ?? entry.comment?.summary?.map((s) => s.text).join('') ?? ''; - const params = entry.params?.map((p) => - ` ${p.name}: ${p.type ?? 'unknown'} — ${p.description ?? ''}` - ).join('\n') ?? entry.signatures?.[0]?.parameters?.map((p) => { - const pSummary = p.comment?.summary?.map((s) => s.text).join('') ?? ''; - return ` ${p.name}: ${p.type?.name ?? 'unknown'} — ${pSummary}`; - }).join('\n') ?? ''; - const text = [ - `## ${entry.name}`, - `Kind: ${entry.kind ?? entry.kindString ?? 'unknown'}`, - summary, - params ? `Parameters:\n${params}` : '', - ].filter(Boolean).join('\n\n'); - return { content: [{ type: 'text', text }] }; -} diff --git a/packages/mcp/src/tools/get-example.ts b/packages/mcp/src/tools/get-example.ts deleted file mode 100644 index 18aebe4b4..000000000 --- a/packages/mcp/src/tools/get-example.ts +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT -const EXAMPLES: Record = { - 'basic-chat': `// Basic chat component with angular -import { Component } from '@angular/core'; -import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; - -@Component({ - selector: 'app-chat', - template: \` - @for (msg of chat.messages(); track $index) { -

    {{ msg.content }}

    - } - @if (chat.isLoading()) {

    Thinking…

    } - - - \`, -}) -export class ChatComponent { - chat = agent<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' }); - send(content: string) { - if (!content.trim()) return; - this.chat.submit({ message: content }); - } -}`, - - 'thread-persistence': `// Thread persistence with localStorage -import { Component, signal } from '@angular/core'; -import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; - -@Component({ selector: 'app-chat', template: '' }) -export class ChatComponent { - threadId = signal(localStorage.getItem('chat-thread')); - chat = agent<{ messages: BaseMessage[] }>({ - assistantId: 'chat_agent', - threadId: this.threadId, - onThreadId: (id) => { this.threadId.set(id); localStorage.setItem('chat-thread', id); }, - }); - newThread() { this.threadId.set(null); localStorage.removeItem('chat-thread'); } -}`, - - 'system-prompt': `// System prompt configuration per session -import { Component } from '@angular/core'; -import { agent } from '@ngaf/langgraph'; - -@Component({ selector: 'app-chat', template: '' }) -export class ChatComponent { - chat = agent({ - assistantId: 'chat_agent', - config: { configurable: { system_prompt: 'You are a helpful coding assistant.' } }, - }); -}`, - - 'mock-testing': `// Unit testing with MockAgentTransport -import { TestBed } from '@angular/core/testing'; -import { agent, MockAgentTransport } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; - -describe('ChatComponent', () => { - it('updates messages when transport emits', () => { - TestBed.runInInjectionContext(() => { - const transport = new MockAgentTransport(); - const chat = agent<{ messages: BaseMessage[] }>({ assistantId: 'test', transport }); - transport.emit([ - { type: 'messages', messages: [[{ type: 'ai', content: 'Hello!' }, { id: '1' }]] }, - ]); - expect(chat.messages()).toHaveLength(1); - expect(chat.messages()[0].content).toBe('Hello!'); - }); - }); -});`, - - 'interrupts': `// Handling interrupts (human-in-the-loop) -import { Component } from '@angular/core'; -import { agent } from '@ngaf/langgraph'; - -@Component({ - selector: 'app-chat', - template: \` - @if (chat.interrupt(); as interrupt) { -
    -

    {{ interrupt.value }}

    - - -
    - } - \`, -}) -export class ChatComponent { - chat = agent({ assistantId: 'agent_with_interrupts' }); - approve() { this.chat.submit(null, { command: { resume: true } }); } - reject() { this.chat.submit(null, { command: { resume: false } }); } -}`, - - 'subagent-progress': `// Showing subagent tool call progress -import { Component } from '@angular/core'; -import { agent } from '@ngaf/langgraph'; - -@Component({ - selector: 'app-chat', - template: \` - @for (tool of chat.toolProgress(); track tool.name) { -

    {{ tool.name }}: {{ tool.status }}

    - } - \`, -}) -export class ChatComponent { - chat = agent({ assistantId: 'research_agent' }); -}`, - - 'custom-transport': `// Custom transport with auth headers -import { AgentTransport } from '@ngaf/langgraph'; - -export class AuthTransport implements AgentTransport { - async *stream(input: unknown, _options: unknown): AsyncGenerator { - const token = await getAuthToken(); // your auth logic - const res = await fetch('/api/stream', { - method: 'POST', - headers: { Authorization: \`Bearer \${token}\`, 'Content-Type': 'application/json' }, - body: JSON.stringify(input), - }); - const reader = res.body!.getReader(); - const decoder = new TextDecoder(); - let buffer = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) break; - buffer += decoder.decode(value, { stream: true }); - const lines = buffer.split('\\n'); - buffer = lines.pop()!; - for (const line of lines) { - if (line.startsWith('data: ')) yield JSON.parse(line.slice(6)); - } - } - } -}`, -}; - -const VALID_PATTERNS = Object.keys(EXAMPLES); - -export const getExampleTool = { - name: 'get_example', - description: 'Get a complete runnable code example for a angular pattern', - inputSchema: { - type: 'object', - properties: { - pattern: { - type: 'string', - description: `Pattern name. One of: ${VALID_PATTERNS.join(', ')}`, - }, - }, - required: ['pattern'], - }, -}; - -export function handleGetExample(args: Record) { - const pattern = args['pattern'] as string; - const example = EXAMPLES[pattern]; - if (!example) { - return { content: [{ type: 'text', text: `Unknown pattern: "${pattern}". Available: ${VALID_PATTERNS.join(', ')}` }] }; - } - return { content: [{ type: 'text', text: `\`\`\`typescript\n${example}\n\`\`\`` }] }; -} diff --git a/packages/mcp/src/tools/get-thread-persistence-pattern.ts b/packages/mcp/src/tools/get-thread-persistence-pattern.ts deleted file mode 100644 index 3230482c4..000000000 --- a/packages/mcp/src/tools/get-thread-persistence-pattern.ts +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -const PATTERNS: Record = { - localStorage: `// Thread persistence with localStorage -threadId = signal(localStorage.getItem('chat-thread-id')); - -chat = agent({ - assistantId: 'chat_agent', - threadId: this.threadId, - onThreadId: (id: string) => { - this.threadId.set(id); - localStorage.setItem('chat-thread-id', id); - }, -}); - -// To start a new conversation: -// this.threadId.set(null); localStorage.removeItem('chat-thread-id');`, - - sessionStorage: `// Thread persistence with sessionStorage (clears on tab close) -threadId = signal(sessionStorage.getItem('chat-thread-id')); - -chat = agent({ - assistantId: 'chat_agent', - threadId: this.threadId, - onThreadId: (id: string) => { - this.threadId.set(id); - sessionStorage.setItem('chat-thread-id', id); - }, -});`, - - custom: `// Thread persistence with a custom store -// TODO: replace saveThread / loadThread with your store (e.g. NgRx, a service, IndexedDB) -threadId = signal(loadThread()); - -chat = agent({ - assistantId: 'chat_agent', - threadId: this.threadId, - onThreadId: (id: string) => { - this.threadId.set(id); - saveThread(id); // TODO: replace with your store - }, -});`, -}; - -export const getThreadPersistencePatternTool = { - name: 'get_thread_persistence_pattern', - description: 'Get Angular code pattern for thread persistence with a specific storage type', - inputSchema: { - type: 'object', - properties: { - storageType: { - type: 'string', - enum: ['localStorage', 'sessionStorage', 'custom'], - description: 'Storage mechanism to use', - }, - }, - required: ['storageType'], - }, -}; - -export function handleGetThreadPersistencePattern(args: Record) { - const storageType = args['storageType'] as string; - const pattern = PATTERNS[storageType]; - if (!pattern) { - return { content: [{ type: 'text', text: `Unknown storageType: "${storageType}". Use: localStorage, sessionStorage, or custom` }] }; - } - return { content: [{ type: 'text', text: `\`\`\`typescript\n${pattern}\n\`\`\`` }] }; -} diff --git a/packages/mcp/src/tools/scaffold-chat-component.ts b/packages/mcp/src/tools/scaffold-chat-component.ts deleted file mode 100644 index e4b30e6f4..000000000 --- a/packages/mcp/src/tools/scaffold-chat-component.ts +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -export const scaffoldChatComponentTool = { - name: 'scaffold_chat_component', - description: 'Generate a complete Angular chat component using angular', - inputSchema: { - type: 'object', - properties: { - componentName: { type: 'string', description: 'Component class name, e.g. "ChatComponent"' }, - apiUrl: { type: 'string', description: 'LangGraph server URL' }, - assistantId: { type: 'string', description: 'LangGraph assistant/graph ID' }, - threadPersistence: { type: 'boolean', description: 'Include localStorage thread persistence' }, - }, - required: ['componentName', 'apiUrl', 'assistantId', 'threadPersistence'], - }, -}; - -export function handleScaffoldChatComponent(args: Record) { - const { componentName, apiUrl, assistantId, threadPersistence } = args as { - componentName: string; apiUrl: string; assistantId: string; threadPersistence: boolean; - }; - - const selector = componentName.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, ''); - const persistenceImport = threadPersistence ? ', signal' : ''; - const persistenceFields = threadPersistence - ? `\n threadId = signal(localStorage.getItem('${selector}-thread'));` - : ''; - const persistenceOptions = threadPersistence - ? `\n threadId: this.threadId,\n onThreadId: (id: string) => {\n this.threadId.set(id);\n localStorage.setItem('${selector}-thread', id);\n },` - : ''; - - const code = `import { Component${persistenceImport} } from '@angular/core'; -import { agent } from '@ngaf/langgraph'; -import type { BaseMessage } from '@langchain/core/messages'; - -@Component({ - selector: 'app-${selector}', - template: \` -
    - @for (msg of chat.messages(); track $index) { -
    - {{ msg.content }} -
    - } - @if (chat.isLoading()) { -
    Thinking…
    - } -
    -
    - - -
    - \`, -}) -export class ${componentName} {${persistenceFields} - - chat = agent<{ messages: BaseMessage[] }>({ - apiUrl: '${apiUrl}', - assistantId: '${assistantId}',${persistenceOptions} - }); - - send(e: Event) { - e.preventDefault(); - const form = e.target as HTMLFormElement; - const input = form.querySelector('input') as HTMLInputElement; - const content = input.value.trim(); - if (!content) return; - input.value = ''; - this.chat.submit({ message: content }); - } -}`; - - return { content: [{ type: 'text', text: `\`\`\`typescript\n${code}\n\`\`\`` }] }; -} diff --git a/packages/mcp/src/tools/search-docs.ts b/packages/mcp/src/tools/search-docs.ts deleted file mode 100644 index 858b71570..000000000 --- a/packages/mcp/src/tools/search-docs.ts +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -import { getApiDocs } from '../data/loader.js'; - -export const searchDocsTool = { - name: 'search_docs', - description: 'Search angular documentation by keyword or phrase', - inputSchema: { - type: 'object', - properties: { query: { type: 'string', description: 'Search query' } }, - required: ['query'], - }, -}; - -export function handleSearchDocs(args: Record) { - const query = (args['query'] as string).toLowerCase(); - const docs = getApiDocs(); - const matches: string[] = []; - for (const child of docs.children ?? []) { - const text = [ - child.name, - child.comment?.summary?.map((s) => s.text).join('') ?? '', - ...(child.signatures?.[0]?.parameters?.map( - (p) => `${p.name}: ${p.comment?.summary?.map((s) => s.text).join('') ?? ''}` - ) ?? []), - ].join(' ').toLowerCase(); - if (text.includes(query)) { - const summary = child.comment?.summary?.map((s) => s.text).join('') ?? ''; - matches.push(`## ${child.name}\n${summary}`); - } - if (matches.length >= 5) break; - } - if (matches.length === 0) { - return { content: [{ type: 'text', text: `No results for: "${args['query']}"` }] }; - } - return { content: [{ type: 'text', text: matches.join('\n\n---\n\n') }] }; -} diff --git a/packages/mcp/tsconfig.json b/packages/mcp/tsconfig.json deleted file mode 100644 index f34edc2dd..000000000 --- a/packages/mcp/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "outDir": "dist", - "rootDir": "src", - "target": "ES2020", - "module": "CommonJS", - "moduleResolution": "node", - "esModuleInterop": true, - "strict": true, - "declaration": true, - "skipLibCheck": true - }, - "include": ["src/**/*.ts"] -}