Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions apps/website/content/AGENTS.md.template
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
# Angular Agent Framework v@VERSION@

Angular agent framework for LangChain/LangGraph. Provides `agent()` — Signal-native streaming for Angular agents, built for LangGraph.
Agent UI primitives and LangGraph streaming adapters for Angular.

## Install
npm install @ngaf/langgraph
npm install @ngaf/chat @ngaf/langgraph

## Key requirement
`agent()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".

## Basic usage
```typescript
// app.config.ts
import type { ApplicationConfig } from '@angular/core';
import { provideAgent } from '@ngaf/langgraph';
export const appConfig: ApplicationConfig = {
providers: [provideAgent({ apiUrl: 'http://localhost:2024' })]
};

// chat.component.ts
import { Component } from '@angular/core';
import { agent } from '@ngaf/langgraph';
import type { BaseMessage } from '@langchain/core/messages';

@Component({ template: `
@for (msg of chat.messages(); track $index) { <p>{{ msg.content }}</p> }
<button (click)="send()">Send</button>
`})
import { ChatComponent as NgafChatComponent } from '@ngaf/chat';

@Component({
imports: [NgafChatComponent],
template: `
<chat [agent]="chat" />
`,
})
export class ChatComponent {
chat = agent<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' });
send() { this.chat.submit({ message: 'Hello' }); }
chat = agent({ assistantId: 'chat_agent' });
}
```

Expand All @@ -36,9 +39,5 @@ export class ChatComponent {
- Per-call override: pass `apiUrl` directly to `agent()`
- Testing: use `MockAgentTransport` — never mock `agent()` itself

## MCP server (for tool access)
Add to ~/.claude/settings.json:
{"mcpServers":{"angular-agent":{"command":"npx","args":["@ngaf/langgraph-mcp"]}}}

## Version check
If this file is stale, fetch the latest: https://cacheplane.ai/llms-full.txt
27 changes: 13 additions & 14 deletions apps/website/content/CLAUDE.md.template
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
# Angular Agent Framework v@VERSION@

Angular agent framework for LangChain/LangGraph. Provides `agent()` — Signal-native streaming for Angular agents, built for LangGraph.
Agent UI primitives and LangGraph streaming adapters for Angular.

## Install
npm install @ngaf/langgraph
npm install @ngaf/chat @ngaf/langgraph

## Key requirement
`agent()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".

## Basic usage
```typescript
// app.config.ts
import type { ApplicationConfig } from '@angular/core';
import { provideAgent } from '@ngaf/langgraph';
export const appConfig: ApplicationConfig = {
providers: [provideAgent({ apiUrl: 'http://localhost:2024' })]
};

// chat.component.ts
import { Component } from '@angular/core';
import { agent } from '@ngaf/langgraph';
import type { BaseMessage } from '@langchain/core/messages';

@Component({ template: `
@for (msg of chat.messages(); track $index) { <p>{{ msg.content }}</p> }
<button (click)="send()">Send</button>
`})
import { ChatComponent as NgafChatComponent } from '@ngaf/chat';

@Component({
imports: [NgafChatComponent],
template: `
<chat [agent]="chat" />
`,
})
export class ChatComponent {
chat = agent<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' });
send() { this.chat.submit({ message: 'Hello' }); }
chat = agent({ assistantId: 'chat_agent' });
}
```

Expand All @@ -36,9 +39,5 @@ export class ChatComponent {
- Per-call override: pass `apiUrl` directly to `agent()`
- Testing: use `MockAgentTransport` — never mock `agent()` itself

## MCP server (for tool access)
Add to ~/.claude/settings.json:
{"mcpServers":{"angular-agent":{"command":"npx","args":["@ngaf/langgraph-mcp"]}}}

## Version check
If this file is stale, fetch the latest: https://cacheplane.ai/llms-full.txt
91 changes: 91 additions & 0 deletions apps/website/content/docs/chat/api/mock-agent.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# mockAgent()

`mockAgent()` creates a runtime-neutral `Agent` mock with writable signals for testing `@ngaf/chat` components. Use it when you are testing chat UI behavior and do not need LangGraph-specific fields.

**Import:**

```typescript
import { mockAgent } from '@ngaf/chat';
import type { MockAgent } from '@ngaf/chat';
```

## Signature

```typescript
function mockAgent(options?: MockAgentOptions): MockAgent
```

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `messages` | `Message[]` | `[]` | Initial runtime-neutral messages |
| `status` | `AgentStatus` | `'idle'` | Initial agent status |
| `isLoading` | `boolean` | `false` | Whether the agent is currently running |
| `error` | `unknown` | `null` | Initial error value |
| `toolCalls` | `ToolCall[]` | `[]` | Initial tool-call list |
| `state` | `Record<string, unknown>` | `{}` | Initial agent state |
| `withInterrupt` | `boolean` | `false` | Include a writable `interrupt` signal |
| `withSubagents` | `boolean` | `false` | Include a writable `subagents` signal |
| `history` | `AgentCheckpoint[]` | `undefined` | Include history and return an `AgentWithHistory`-compatible mock |

## Basic Test Usage

```typescript
import { TestBed } from '@angular/core/testing';
import { ChatComponent, mockAgent } from '@ngaf/chat';

it('renders messages from an agent', async () => {
const agent = mockAgent({
messages: [
{ id: 'm1', role: 'user', content: 'Hello' },
{ id: 'm2', role: 'assistant', content: 'Hi there' },
],
});

await TestBed.configureTestingModule({
imports: [ChatComponent],
}).compileComponents();

const fixture = TestBed.createComponent(ChatComponent);
fixture.componentRef.setInput('agent', agent);
fixture.detectChanges();

expect(fixture.nativeElement.textContent).toContain('Hello');
expect(fixture.nativeElement.textContent).toContain('Hi there');
});
```

## Controlling State

The returned mock exposes writable signals, so tests can update state directly:

```typescript
const agent = mockAgent();

agent.isLoading.set(true);
agent.error.set(new Error('Connection failed'));
agent.messages.set([{ id: 'm1', role: 'assistant', content: 'Retry?' }]);
```

## Spying on Actions

The mock records calls to core actions:

```typescript
const agent = mockAgent();

await agent.submit({ message: 'Hello' });
await agent.stop();
await agent.regenerate(1);

expect(agent.submitCalls[0]?.input).toEqual({ message: 'Hello' });
expect(agent.stopCount).toBe(1);
expect(agent.submitCalls[1]?.input).toEqual({
regenerate: { assistantMessageIndex: 1 },
});
```

## LangGraph-Specific Tests

Use `mockLangGraphAgent()` from `@ngaf/langgraph` only when the test needs LangGraph-specific signals such as raw LangGraph messages, checkpoint state, branches, queued runs, or transport metadata.
Loading
Loading