@mgvdev/nestjs-ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +655 -0
- package/dist/ai-module-options.interface-B5X4AFLC.d.cts +192 -0
- package/dist/ai-module-options.interface-Ca6y_MY2.d.ts +192 -0
- package/dist/conversation-store.interface-CtQY-qcc.d.cts +30 -0
- package/dist/conversation-store.interface-CtQY-qcc.d.ts +30 -0
- package/dist/index.cjs +3209 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1441 -0
- package/dist/index.d.ts +1441 -0
- package/dist/index.js +3163 -0
- package/dist/index.js.map +1 -0
- package/dist/stream-to-socket-fJphU0WN.d.cts +47 -0
- package/dist/stream-to-socket-fJphU0WN.d.ts +47 -0
- package/dist/testing.cjs +2395 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +46 -0
- package/dist/testing.d.ts +46 -0
- package/dist/testing.js +2391 -0
- package/dist/testing.js.map +1 -0
- package/dist/typeorm.cjs +115 -0
- package/dist/typeorm.cjs.map +1 -0
- package/dist/typeorm.d.cts +44 -0
- package/dist/typeorm.d.ts +44 -0
- package/dist/typeorm.js +113 -0
- package/dist/typeorm.js.map +1 -0
- package/dist/websocket.cjs +154 -0
- package/dist/websocket.cjs.map +1 -0
- package/dist/websocket.d.cts +25 -0
- package/dist/websocket.d.ts +25 -0
- package/dist/websocket.js +152 -0
- package/dist/websocket.js.map +1 -0
- package/documentation/README.md +44 -0
- package/documentation/agents-and-tools.md +102 -0
- package/documentation/api-reference.md +117 -0
- package/documentation/configuration.md +87 -0
- package/documentation/content-safety.md +51 -0
- package/documentation/embeddings-and-rag.md +105 -0
- package/documentation/evals-and-testing.md +56 -0
- package/documentation/getting-started.md +96 -0
- package/documentation/guardrails-events-telemetry.md +72 -0
- package/documentation/jobs-and-realtime.md +69 -0
- package/documentation/memory.md +101 -0
- package/documentation/multimodal.md +49 -0
- package/documentation/orchestration-and-mcp.md +68 -0
- package/documentation/prompts.md +51 -0
- package/documentation/reliability.md +90 -0
- package/documentation/structured-output-and-streaming.md +81 -0
- package/package.json +146 -0
- package/skill/nestjs-ai/SKILL.md +154 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nestjs-ai
|
|
3
|
+
description: Use when building AI features in a NestJS app with @mgvdev/nestjs-ai — agents, tools, structured output, streaming, embeddings, RAG, multimodal, prompts, guardrails, orchestration, MCP, caching, fallback, tool approval, jobs, cost/budgets, rate limiting, semantic memory, content safety, reranking, evals, and testing. Triggers on mentions of @mgvdev/nestjs-ai, AiModule, @Agent, @Tool, AiAgent, or "NestJS AI".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Building with @mgvdev/nestjs-ai
|
|
7
|
+
|
|
8
|
+
`@mgvdev/nestjs-ai` is a NestJS toolkit over the Vercel AI SDK (v7). It adds
|
|
9
|
+
DI-native decorators, a dynamic module, automatic tool discovery, and production
|
|
10
|
+
features (cost, rate limiting, guardrails, memory, evals).
|
|
11
|
+
|
|
12
|
+
## Golden rules
|
|
13
|
+
|
|
14
|
+
1. **Configure once** with `AiModule.forRoot()` / `forRootAsync()`. It is global.
|
|
15
|
+
2. **Model ids are `"provider:model"`** — e.g. `"openai:gpt-4o"`. A bare id works
|
|
16
|
+
when a single provider is configured or a `defaultModel` sets the provider.
|
|
17
|
+
3. **Agents extend `AiAgent`** and are annotated `@Agent`. Call `.run()` / `.stream()`.
|
|
18
|
+
4. **Tools are `@Tool` methods on injectable providers** — they keep full DI.
|
|
19
|
+
5. **Register agents/tools/guardrails as providers** (or via `AiModule.forFeature`)
|
|
20
|
+
so discovery finds them.
|
|
21
|
+
6. **Install only the provider SDKs you use** (`@ai-sdk/openai`, etc.) — they are
|
|
22
|
+
optional peers. Same for `bullmq`, `pg`, `@nestjs/websockets`, `msw`.
|
|
23
|
+
|
|
24
|
+
## Minimal setup
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { Module } from '@nestjs/common';
|
|
28
|
+
import { AiModule } from '@mgvdev/nestjs-ai';
|
|
29
|
+
|
|
30
|
+
@Module({
|
|
31
|
+
imports: [
|
|
32
|
+
AiModule.forRoot({
|
|
33
|
+
providers: { openai: { apiKey: process.env.OPENAI_API_KEY } },
|
|
34
|
+
defaultModel: 'openai:gpt-4o',
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
export class AppModule {}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`forRootAsync({ imports, inject, useFactory })` builds options from
|
|
42
|
+
`ConfigService`.
|
|
43
|
+
|
|
44
|
+
## Tools (function calling)
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { Injectable } from '@nestjs/common';
|
|
48
|
+
import { Tool } from '@mgvdev/nestjs-ai';
|
|
49
|
+
import { z } from 'zod';
|
|
50
|
+
|
|
51
|
+
@Injectable()
|
|
52
|
+
export class WeatherTools {
|
|
53
|
+
constructor(private readonly api: WeatherApi) {} // regular DI
|
|
54
|
+
|
|
55
|
+
@Tool({ description: 'Get weather for a city', schema: z.object({ city: z.string() }) })
|
|
56
|
+
getWeather({ city }: { city: string }) {
|
|
57
|
+
return this.api.lookup(city);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- `@Tool({ name?, description, schema, requiresApproval? })`. `schema` is Zod.
|
|
63
|
+
- `requiresApproval: true` gates the call behind the configured `ApprovalGate`.
|
|
64
|
+
|
|
65
|
+
## Agents
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { Agent, AiAgent } from '@mgvdev/nestjs-ai';
|
|
69
|
+
|
|
70
|
+
@Agent({
|
|
71
|
+
model: 'openai:gpt-4o', // or ['openai:gpt-4o', 'anthropic:claude-sonnet-4'] for fallback
|
|
72
|
+
system: 'You are a helpful assistant.',
|
|
73
|
+
tools: [WeatherTools], // @Tool providers, or other @Agent classes (sub-agents)
|
|
74
|
+
maxSteps: 5,
|
|
75
|
+
// output: z.object({...}), // structured output
|
|
76
|
+
})
|
|
77
|
+
export class SupportAgent extends AiAgent {}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Run it (inject the agent class):
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const { text } = await this.support.run('Weather in Paris?');
|
|
84
|
+
const { object } = await this.support.run<MyType>(input); // when `output` is set
|
|
85
|
+
const stream = this.support.stream('Hi'); // Vercel stream result
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`AgentRunOptions`: `{ model?, system?, systemPrompt?, conversationId?, maxSteps?, schema?, temperature?, maxRetries?, recall?, abortSignal? }`.
|
|
89
|
+
|
|
90
|
+
## Register your classes
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
@Module({
|
|
94
|
+
imports: [AiModule.forFeature({ agents: [SupportAgent], tools: [WeatherTools] })],
|
|
95
|
+
providers: [WeatherApi],
|
|
96
|
+
})
|
|
97
|
+
export class SupportModule {}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Feature cheat-sheet
|
|
101
|
+
|
|
102
|
+
| Need | Use |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| Conversation history | `run(input, { conversationId })` — in-memory default; TypeORM (`/typeorm`) or Prisma store |
|
|
105
|
+
| Structured output | `@Agent({ output })` or `run(input, { schema })` |
|
|
106
|
+
| Streaming to HTTP | `pipeAgentStream(agent.stream(x), res, { protocol: 'ui' })` |
|
|
107
|
+
| Streaming over WebSocket | `AgentGateway` from `@mgvdev/nestjs-ai/websocket` |
|
|
108
|
+
| Embeddings | `EmbeddingsService.embed` / `embedMany` |
|
|
109
|
+
| RAG | `RagService.ingest` / `retrieve`; stores: in-memory, `PgVectorStore`, `QdrantVectorStore`, `PineconeVectorStore` |
|
|
110
|
+
| Reranking | `retrieve(q, { rerank: true })` (heuristic) or a `ModelReranker` |
|
|
111
|
+
| Multimodal | `ImageService`, `SpeechService`, `TranscriptionService` |
|
|
112
|
+
| Prompts | `PromptRegistry` + `AiModule.forRoot({ prompts })`; `run(x, { systemPrompt })` |
|
|
113
|
+
| Events | `@OnEvent('ai.agent.run.finish')` (needs `@nestjs/event-emitter`) |
|
|
114
|
+
| Guardrails | `@Guardrail()` classes; `beforeRun` / `afterRun` / `onToolCall` |
|
|
115
|
+
| Tool approval | `@Tool({ requiresApproval: true })` + `approvalGate` option |
|
|
116
|
+
| Multi-agent | list `@Agent` classes in another agent's `tools` |
|
|
117
|
+
| MCP tools | `McpService.connect(name, client)` (bring an `@modelcontextprotocol/sdk` client) |
|
|
118
|
+
| Fallback / retry | model array + `maxRetries` |
|
|
119
|
+
| Caching | `AiModule.forRoot({ cache: InMemoryAiCache })` |
|
|
120
|
+
| Background jobs | `AgentJobsModule.forRoot({ connection })` (BullMQ) |
|
|
121
|
+
| Cost & budgets | `UsageTracker`; `AiModule.forRoot({ maxCostPerConversation })` |
|
|
122
|
+
| Rate limiting | `AiModule.forRoot({ rateLimiter })` |
|
|
123
|
+
| Semantic memory | `SemanticMemory.remember` / `recall`; `run(x, { recall })` |
|
|
124
|
+
| Content safety | `PiiRedactionGuardrail`, `createModerationGuardrail` |
|
|
125
|
+
| Evals | `EvalRunner.run(agent, cases, { judge })` |
|
|
126
|
+
| Testing | `createTestingAiModule`, `createMockModel` from `@mgvdev/nestjs-ai/testing` |
|
|
127
|
+
|
|
128
|
+
## Testing
|
|
129
|
+
|
|
130
|
+
Never call real providers in tests. Use the testing subpath:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { createTestingAiModule, createMockModel } from '@mgvdev/nestjs-ai/testing';
|
|
134
|
+
|
|
135
|
+
const app = await createTestingAiModule({
|
|
136
|
+
model: createMockModel('mocked answer'),
|
|
137
|
+
providers: [SupportAgent],
|
|
138
|
+
});
|
|
139
|
+
const { text } = await app.get(SupportAgent).run('hi');
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Common mistakes
|
|
143
|
+
|
|
144
|
+
- Forgetting to register an agent/tool/guardrail as a provider → discovery misses it.
|
|
145
|
+
- Using a bare model id with multiple providers configured → prefix with `provider:`.
|
|
146
|
+
- Expecting MCP or a rerank model from OpenAI/Google — MCP needs an external client;
|
|
147
|
+
reranking needs a rerank-capable provider (e.g. Cohere).
|
|
148
|
+
- Importing the TypeORM store / WebSocket gateway / testing utils from the main entry —
|
|
149
|
+
they live at `@mgvdev/nestjs-ai/typeorm`, `/websocket`, `/testing`.
|
|
150
|
+
|
|
151
|
+
## Deeper docs
|
|
152
|
+
|
|
153
|
+
Full guides ship in the package under `documentation/` — read them for
|
|
154
|
+
configuration, each feature, and the API reference.
|