@mtkn/mega-agent 0.1.0 → 0.2.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.
Files changed (82) hide show
  1. package/README.md +624 -0
  2. package/dist/artifact/artifact.repository.d.ts +2 -1
  3. package/dist/artifact/artifact.repository.d.ts.map +1 -1
  4. package/dist/artifact/artifact.repository.js +1 -1
  5. package/dist/artifact/artifact.repository.js.map +1 -1
  6. package/dist/artifact/artifact.service.d.ts +3 -2
  7. package/dist/artifact/artifact.service.d.ts.map +1 -1
  8. package/dist/artifact/artifact.service.js.map +1 -1
  9. package/dist/artifact/artifact.types.d.ts +2 -1
  10. package/dist/artifact/artifact.types.d.ts.map +1 -1
  11. package/dist/artifact/artifact.types.js.map +1 -1
  12. package/dist/chat/chat-memory.integration.d.ts +3 -2
  13. package/dist/chat/chat-memory.integration.d.ts.map +1 -1
  14. package/dist/chat/chat-memory.integration.js.map +1 -1
  15. package/dist/chat/chat.repository.d.ts +2 -1
  16. package/dist/chat/chat.repository.d.ts.map +1 -1
  17. package/dist/chat/chat.repository.js +1 -1
  18. package/dist/chat/chat.repository.js.map +1 -1
  19. package/dist/chat/chat.service.d.ts +3 -2
  20. package/dist/chat/chat.service.d.ts.map +1 -1
  21. package/dist/chat/chat.service.js +108 -33
  22. package/dist/chat/chat.service.js.map +1 -1
  23. package/dist/chat/chat.types.d.ts +7 -5
  24. package/dist/chat/chat.types.d.ts.map +1 -1
  25. package/dist/chat/chat.types.js.map +1 -1
  26. package/dist/chat/prompts/system.prompts.d.ts.map +1 -1
  27. package/dist/chat/prompts/system.prompts.js +9 -6
  28. package/dist/chat/prompts/system.prompts.js.map +1 -1
  29. package/dist/incident/incident.correlator.d.ts +3 -2
  30. package/dist/incident/incident.correlator.d.ts.map +1 -1
  31. package/dist/incident/incident.correlator.js.map +1 -1
  32. package/dist/incident/incident.repository.d.ts +5 -4
  33. package/dist/incident/incident.repository.d.ts.map +1 -1
  34. package/dist/incident/incident.repository.js +6 -6
  35. package/dist/incident/incident.repository.js.map +1 -1
  36. package/dist/incident/incident.service.d.ts +3 -2
  37. package/dist/incident/incident.service.d.ts.map +1 -1
  38. package/dist/incident/incident.service.js.map +1 -1
  39. package/dist/incident/incident.types.d.ts +3 -2
  40. package/dist/incident/incident.types.d.ts.map +1 -1
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/mcp/source.repository.d.ts +5 -4
  45. package/dist/mcp/source.repository.d.ts.map +1 -1
  46. package/dist/mcp/source.repository.js +3 -3
  47. package/dist/mcp/source.repository.js.map +1 -1
  48. package/dist/mcp/source.service.d.ts +3 -2
  49. package/dist/mcp/source.service.d.ts.map +1 -1
  50. package/dist/mcp/source.service.js.map +1 -1
  51. package/dist/memory/memory.repository.d.ts +3 -2
  52. package/dist/memory/memory.repository.d.ts.map +1 -1
  53. package/dist/memory/memory.repository.js +4 -4
  54. package/dist/memory/memory.repository.js.map +1 -1
  55. package/dist/memory/memory.service.d.ts +3 -2
  56. package/dist/memory/memory.service.d.ts.map +1 -1
  57. package/dist/memory/memory.service.js +2 -2
  58. package/dist/memory/memory.service.js.map +1 -1
  59. package/dist/memory/memory.types.d.ts +4 -3
  60. package/dist/memory/memory.types.d.ts.map +1 -1
  61. package/dist/memory/memory.types.js.map +1 -1
  62. package/dist/tools/tool-registry.d.ts +3 -2
  63. package/dist/tools/tool-registry.d.ts.map +1 -1
  64. package/dist/tools/tool-registry.js.map +1 -1
  65. package/dist/types/id.types.d.ts +7 -0
  66. package/dist/types/id.types.d.ts.map +1 -0
  67. package/dist/types/id.types.js +2 -0
  68. package/dist/types/id.types.js.map +1 -0
  69. package/dist/types/index.d.ts +2 -0
  70. package/dist/types/index.d.ts.map +1 -0
  71. package/dist/types/index.js +2 -0
  72. package/dist/types/index.js.map +1 -0
  73. package/dist/workflow/workflow.repository.js.map +1 -1
  74. package/dist/workflow/workflow.service.d.ts.map +1 -1
  75. package/dist/workflow/workflow.service.js +7 -6
  76. package/dist/workflow/workflow.service.js.map +1 -1
  77. package/dist/workflow/workflow.types.d.ts +4 -2
  78. package/dist/workflow/workflow.types.d.ts.map +1 -1
  79. package/dist/workflow/workflow.types.js.map +1 -1
  80. package/package.json +1 -3
  81. package/prisma/schema.prisma +13 -5
  82. package/scripts/prisma-sync.mjs +216 -13
package/README.md ADDED
@@ -0,0 +1,624 @@
1
+ # @mtkn/mega-agent
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@mtkn/mega-agent.svg)](https://www.npmjs.com/package/@mtkn/mega-agent)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ AI-powered agent infrastructure for Express + Prisma backends. Drop-in chat API with tool calling, long-term memory, incident detection, workflow automation, and more.
7
+
8
+ ## Features
9
+
10
+ - **Multi-provider LLM** — Anthropic, OpenAI, Gemini, or custom endpoints
11
+ - **Tool calling** with read/write approval workflow
12
+ - **Long-term memory** — embedding + Qdrant vector search (optional)
13
+ - **Chat API** with SSE streaming and 4 chat modes
14
+ - **Incident detection** — anomaly detection with severity levels
15
+ - **Workflow automation** — schedule, event, threshold, and manual triggers
16
+ - **Artifact storage** — reports, tables, charts, code, images, datasets
17
+ - **MCP support** — Model Context Protocol for external data sources
18
+ - **Prisma persistence** — 12 models, fully typed
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ npm install @mtkn/mega-agent
24
+ ```
25
+
26
+ ```typescript
27
+ import { createMegaAgent } from '@mtkn/mega-agent';
28
+
29
+ const agent = await createMegaAgent({
30
+ prisma,
31
+ logger,
32
+ llm: {
33
+ providers: [
34
+ { provider: 'anthropic', apiKey: 'sk-ant-...', defaultModel: 'claude-sonnet-4-20250514' },
35
+ ],
36
+ },
37
+ });
38
+
39
+ app.use('/api/chat', agent.createChatRouter(authMiddleware));
40
+ ```
41
+
42
+ ## Requirements
43
+
44
+ | Requirement | Version |
45
+ |---|---|
46
+ | Node.js | >= 18.17 |
47
+ | TypeScript | 5.x |
48
+ | Express | 4.x |
49
+ | Prisma | 6.x |
50
+ | PostgreSQL | 14+ |
51
+
52
+ **Optional services (for memory system):**
53
+
54
+ | Service | Purpose |
55
+ |---|---|
56
+ | Qdrant | Vector database for semantic search |
57
+ | OpenAI API | Embedding model (`text-embedding-3-small`) |
58
+ | Redis + BullMQ | Job queue (for workflows) |
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ npm install @mtkn/mega-agent
64
+
65
+ # Peer dependencies (should already be in your project)
66
+ npm install @prisma/client express
67
+ npm install -D prisma @types/express typescript
68
+ ```
69
+
70
+ ## Prisma Schema Setup
71
+
72
+ The package requires 16 enums and 12 models in your Prisma schema.
73
+
74
+ ### Option A: Automatic Sync (Recommended)
75
+
76
+ ```bash
77
+ npx mega-agent-prisma-sync --target prisma/schema.prisma
78
+ ```
79
+
80
+ On first run, the CLI interactively asks your preferred ID strategy:
81
+
82
+ ```
83
+ 📋 mega-agent Prisma Schema Configuration
84
+
85
+ Primary key strategy for mega-agent models? (cuid/uuid/autoincrement) [cuid]:
86
+ User ID type in your app? (int/string) [int]:
87
+ ```
88
+
89
+ You can also pass flags directly (useful for CI/CD):
90
+
91
+ ```bash
92
+ # UUID primary keys + String user IDs
93
+ npx mega-agent-prisma-sync --target prisma/schema.prisma --id-type uuid --user-id-type string
94
+
95
+ # Autoincrement (integer) primary keys
96
+ npx mega-agent-prisma-sync --target prisma/schema.prisma --id-type autoincrement
97
+
98
+ # Skip prompts, use previous config or defaults
99
+ npx mega-agent-prisma-sync --target prisma/schema.prisma --no-interactive
100
+
101
+ # Preview without writing
102
+ npx mega-agent-prisma-sync --target prisma/schema.prisma --id-type uuid --dry-run
103
+ ```
104
+
105
+ **Available options:**
106
+
107
+ | Flag | Values | Default | Description |
108
+ |------|--------|---------|-------------|
109
+ | `--id-type` | `cuid`, `uuid`, `autoincrement` | `cuid` | Primary key strategy for all mega-agent models |
110
+ | `--user-id-type` | `int`, `string` | `int` | Type of the `userId` field (must match your User model's ID type) |
111
+ | `--no-interactive` | — | — | Skip prompts, use previous config or defaults |
112
+ | `--dry-run` | — | — | Print result without writing to file |
113
+
114
+ Your selection is saved in the marker comment. Re-running the sync command automatically detects and reuses the previous config.
115
+
116
+ ### Option B: Manual Copy
117
+
118
+ Copy all enums and models from the reference schema:
119
+
120
+ ```bash
121
+ # View the reference schema
122
+ cat node_modules/@mtkn/mega-agent/prisma/schema.prisma
123
+ ```
124
+
125
+ If your app uses UUID or autoincrement IDs, you'll need to manually adjust the `@id` defaults and `userId` field types.
126
+
127
+ ### Add User Relations
128
+
129
+ Each AI model has a `userId` field. Add relations in your `User` model:
130
+
131
+ ```prisma
132
+ model User {
133
+ // ... your existing fields ...
134
+
135
+ // AI Agent relations
136
+ aiMemories AiMemory[]
137
+ aiMemorySuggestions AiMemorySuggestion[]
138
+ aiChats AiChat[]
139
+ aiArtifacts AiArtifact[]
140
+ aiMcpSources AiMcpSource[]
141
+ aiWorkflows AiWorkflow[]
142
+ aiIncidents AiIncident[]
143
+ aiTimelineEvents AiTimelineEvent[]
144
+ aiReports AiReport[]
145
+ aiPreferences AiUserPreferences?
146
+ }
147
+ ```
148
+
149
+ And add the reverse relation in each AI model:
150
+
151
+ ```prisma
152
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
153
+ ```
154
+
155
+ ### Add Notification Model
156
+
157
+ The workflow service uses `prisma.notification.create()`. Your schema needs a Notification model. Adjust the `userId` type to match your User model:
158
+
159
+ ```prisma
160
+ model Notification {
161
+ id Int @id @default(autoincrement())
162
+ userId Int @map("user_id") // Use String if your User.id is String
163
+ type String
164
+ title String
165
+ message String
166
+ isRead Boolean @default(false) @map("is_read")
167
+ createdAt DateTime @default(now()) @map("created_at")
168
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
169
+ @@map("notifications")
170
+ }
171
+ ```
172
+
173
+ ### Run Migration
174
+
175
+ ```bash
176
+ npx prisma migrate dev --name add_mega_agent_models
177
+ npx prisma generate
178
+ ```
179
+
180
+ ## Configuration
181
+
182
+ ```typescript
183
+ interface MegaAgentConfig {
184
+ /** Prisma client instance */
185
+ prisma: PrismaClient;
186
+
187
+ /** Logger with info/error/warn/debug methods */
188
+ logger: LoggerLike;
189
+
190
+ /** LLM provider configs (at least 1 required) */
191
+ llm: {
192
+ providers: Array<{
193
+ provider: 'anthropic' | 'openai' | 'gemini' | 'custom';
194
+ apiKey: string;
195
+ defaultModel?: string;
196
+ baseUrl?: string; // only for 'custom'
197
+ }>;
198
+ };
199
+
200
+ /** Memory system — omit to disable */
201
+ memory?: {
202
+ embedding: {
203
+ apiKey: string;
204
+ provider?: 'openai'; // default: 'openai'
205
+ defaultModel?: string; // default: 'text-embedding-3-small'
206
+ };
207
+ qdrant: {
208
+ host: string; // default: 'localhost'
209
+ port: number; // default: 6333
210
+ apiKey?: string;
211
+ };
212
+ };
213
+
214
+ /** Agent identity (for system prompt customization) */
215
+ agent?: {
216
+ agentName?: string;
217
+ agentDescription?: string;
218
+ customPrompt?: string;
219
+ };
220
+ }
221
+ ```
222
+
223
+ ## Usage
224
+
225
+ ### Basic Setup
226
+
227
+ ```typescript
228
+ import type { Express } from 'express';
229
+ import { createMegaAgent } from '@mtkn/mega-agent';
230
+ import { prisma } from './lib/prisma-client.js';
231
+ import { logger } from './lib/logger.js';
232
+ import { authMiddleware } from './middleware/auth.js';
233
+
234
+ export async function initChatModule(app: Express): Promise<void> {
235
+ const providers = [];
236
+
237
+ if (process.env.ANTHROPIC_API_KEY) {
238
+ providers.push({
239
+ provider: 'anthropic' as const,
240
+ apiKey: process.env.ANTHROPIC_API_KEY,
241
+ defaultModel: process.env.ANTHROPIC_DEFAULT_MODEL || 'claude-sonnet-4-20250514',
242
+ });
243
+ }
244
+
245
+ if (process.env.OPENAI_API_KEY) {
246
+ providers.push({
247
+ provider: 'openai' as const,
248
+ apiKey: process.env.OPENAI_API_KEY,
249
+ defaultModel: process.env.OPENAI_DEFAULT_MODEL || 'gpt-4o',
250
+ });
251
+ }
252
+
253
+ // Memory config (optional — requires OpenAI key + Qdrant)
254
+ const memory = process.env.OPENAI_API_KEY
255
+ ? {
256
+ embedding: {
257
+ apiKey: process.env.OPENAI_API_KEY,
258
+ provider: 'openai' as const,
259
+ defaultModel: process.env.EMBEDDING_MODEL || 'text-embedding-3-small',
260
+ },
261
+ qdrant: {
262
+ host: process.env.QDRANT_HOST || 'localhost',
263
+ port: parseInt(process.env.QDRANT_PORT || '6333', 10),
264
+ apiKey: process.env.QDRANT_API_KEY || undefined,
265
+ },
266
+ }
267
+ : undefined;
268
+
269
+ const agent = await createMegaAgent({
270
+ prisma,
271
+ logger,
272
+ llm: { providers },
273
+ memory,
274
+ agent: {
275
+ agentName: 'ProductionAssistant',
276
+ agentDescription: 'Manufacturing management AI assistant',
277
+ },
278
+ });
279
+
280
+ // Register domain-specific tools (see below)
281
+ registerMyTools();
282
+
283
+ // Mount chat routes
284
+ app.use('/api/chat', agent.createChatRouter(authMiddleware));
285
+ }
286
+ ```
287
+
288
+ ### Auth Middleware
289
+
290
+ The chat router requires an auth middleware that sets `req.user` with at least an `id` field:
291
+
292
+ ```typescript
293
+ type AuthMiddleware = (req: Request, res: Response, next: NextFunction) => void;
294
+
295
+ // Your middleware must set:
296
+ // req.user = { id: number | string, ... }
297
+ ```
298
+
299
+ The `userId` type is flexible — it accepts both `number` and `string` to support different ID strategies (autoincrement integers, CUID strings, UUIDs, etc.).
300
+
301
+ ### Registering Domain Tools
302
+
303
+ Tools give the AI agent access to your application's data and actions. The package comes with 2 built-in tools (`search_memory`, `create_memory`) when memory is enabled. Register your own domain tools after calling `createMegaAgent()`:
304
+
305
+ ```typescript
306
+ import { registerTools } from '@mtkn/mega-agent';
307
+ import type { ToolDefinition } from '@mtkn/mega-agent';
308
+
309
+ const tools: ToolDefinition[] = [
310
+ // Read tools — auto-executed, no user approval needed
311
+ {
312
+ name: 'list_products',
313
+ description: 'List products with optional status filter',
314
+ category: 'read',
315
+ inputSchema: {
316
+ type: 'object',
317
+ properties: {
318
+ status: { type: 'string', description: 'Filter by status', enum: ['ACTIVE', 'ARCHIVED'] },
319
+ limit: { type: 'number', description: 'Max results (default 20)' },
320
+ },
321
+ },
322
+ handler: async (args, userId) => {
323
+ return prisma.product.findMany({
324
+ where: args.status ? { status: args.status as string } : undefined,
325
+ take: (args.limit as number) || 20,
326
+ });
327
+ },
328
+ },
329
+
330
+ // Write tools — require user approval before execution
331
+ {
332
+ name: 'create_order',
333
+ description: 'Create a new order. Requires approval.',
334
+ category: 'write',
335
+ inputSchema: {
336
+ type: 'object',
337
+ properties: {
338
+ productId: { type: 'number', description: 'Product ID' },
339
+ quantity: { type: 'number', description: 'Order quantity' },
340
+ },
341
+ required: ['productId', 'quantity'],
342
+ },
343
+ handler: async (args, userId) => {
344
+ return prisma.order.create({
345
+ data: {
346
+ productId: args.productId as number,
347
+ quantity: args.quantity as number,
348
+ userId,
349
+ },
350
+ });
351
+ },
352
+ },
353
+ ];
354
+
355
+ export function registerMyTools(): void {
356
+ registerTools(tools);
357
+ }
358
+ ```
359
+
360
+ **Tool Categories:**
361
+ - `read` — Auto-executed by the agent, no approval needed
362
+ - `write` — Agent pauses and waits for user approval via `POST /:id/approve`
363
+
364
+ ### Using Services Independently
365
+
366
+ You can use individual services without the full chat stack:
367
+
368
+ ```typescript
369
+ import { initLLMService, LLMService } from '@mtkn/mega-agent';
370
+ import type { LLMProviderConfig } from '@mtkn/mega-agent';
371
+
372
+ // Initialize the LLM service once
373
+ const providers: LLMProviderConfig[] = [
374
+ { provider: 'anthropic', apiKey: process.env.ANTHROPIC_API_KEY!, defaultModel: 'claude-sonnet-4-20250514' },
375
+ ];
376
+ initLLMService({ config: providers, logger });
377
+
378
+ // Use it anywhere
379
+ const llm = new LLMService();
380
+ const response = await llm.complete({
381
+ messages: [
382
+ { role: 'system', content: 'You are a risk analyst.' },
383
+ { role: 'user', content: 'Analyze this production data...' },
384
+ ],
385
+ temperature: 0.3,
386
+ });
387
+ ```
388
+
389
+ Other services (after `createMegaAgent()` has been called):
390
+
391
+ ```typescript
392
+ import {
393
+ IncidentService, getIncidentServiceDeps,
394
+ WorkflowService, getWorkflowServiceDeps,
395
+ ArtifactService, getArtifactServiceDeps,
396
+ } from '@mtkn/mega-agent';
397
+
398
+ // Check if dependencies are initialized
399
+ if (getIncidentServiceDeps()) {
400
+ const incidents = new IncidentService();
401
+ // Use incident detection...
402
+ }
403
+
404
+ if (getWorkflowServiceDeps()) {
405
+ const workflows = new WorkflowService();
406
+ // Use workflow automation...
407
+ }
408
+ ```
409
+
410
+ ## API Endpoints
411
+
412
+ The chat router creates the following endpoints:
413
+
414
+ | Method | Path | Description |
415
+ |--------|------|-------------|
416
+ | `POST` | `/` | Create a new chat session |
417
+ | `GET` | `/` | List user's chats (paginated) |
418
+ | `GET` | `/:id` | Get chat with full message history |
419
+ | `PATCH` | `/:id` | Update chat (title, mode, model, etc.) |
420
+ | `DELETE` | `/:id` | Delete chat and all messages |
421
+ | `POST` | `/:id/messages` | Send message (agent responds) |
422
+ | `POST` | `/:id/approve` | Approve a pending write tool call |
423
+ | `POST` | `/:id/reject` | Reject a pending write tool call |
424
+
425
+ ### Send Message
426
+
427
+ ```bash
428
+ POST /api/chat/:id/messages
429
+ Content-Type: application/json
430
+
431
+ {
432
+ "content": "Show me today's production stats",
433
+ "model": "claude-sonnet-4-20250514", // optional override
434
+ "stream": true // optional SSE streaming
435
+ }
436
+ ```
437
+
438
+ **Response (non-streaming):**
439
+
440
+ ```json
441
+ {
442
+ "success": true,
443
+ "data": {
444
+ "userMessage": { "id": "...", "role": "USER", "content": "..." },
445
+ "assistantMessage": { "id": "...", "role": "ASSISTANT", "content": "..." },
446
+ "memories": [],
447
+ "tokens": { "prompt": 1200, "completion": 350, "total": 1550 },
448
+ "latencyMs": 2340
449
+ }
450
+ }
451
+ ```
452
+
453
+ **SSE Streaming:**
454
+
455
+ When `stream: true`, the response uses Server-Sent Events:
456
+
457
+ ```
458
+ Content-Type: text/event-stream
459
+
460
+ data: {"type":"chunk","content":"Here are"}
461
+ data: {"type":"chunk","content":" today's stats..."}
462
+ data: {"type":"tool_call","name":"get_dashboard","args":{}}
463
+ data: {"type":"done","tokens":{"prompt":1200,"completion":350}}
464
+ ```
465
+
466
+ ## Chat Modes
467
+
468
+ Each chat session has a mode that shapes the agent's behavior:
469
+
470
+ | Mode | Description |
471
+ |------|-------------|
472
+ | `EXPLORE` | Analysis, insights, data exploration. Agent focuses on understanding and explaining. |
473
+ | `GENERATE` | Content creation. Agent produces structured output (reports, tables, code). |
474
+ | `EXECUTE` | Action-oriented. Agent actively uses tools to perform tasks. |
475
+ | `AUTOMATE` | Workflow setup. Agent helps create triggers, conditions, and automated actions. |
476
+
477
+ Set the mode when creating or updating a chat:
478
+
479
+ ```bash
480
+ POST /api/chat
481
+ { "mode": "EXECUTE", "title": "Production Management" }
482
+ ```
483
+
484
+ ## Tool Approval Flow
485
+
486
+ ```
487
+ User sends message
488
+
489
+
490
+ Agent processes with LLM
491
+
492
+ ├── Uses read tool → auto-executes → continues
493
+
494
+ └── Uses write tool → pauses
495
+
496
+
497
+ Returns pending tool call to client
498
+
499
+ ├── POST /:id/approve → executes tool → agent continues
500
+
501
+ └── POST /:id/reject → agent informed → responds accordingly
502
+ ```
503
+
504
+ ## Prisma Models
505
+
506
+ The package uses 12 models and 16 enums:
507
+
508
+ | Model | Purpose |
509
+ |-------|---------|
510
+ | `AiMemory` | Long-term memory with vector embeddings |
511
+ | `AiMemorySuggestion` | AI-suggested memories for user review |
512
+ | `AiChat` | Chat sessions with mode and settings |
513
+ | `AiChatMessage` | Individual messages with token tracking |
514
+ | `AiArtifact` | Generated content (reports, charts, code, etc.) |
515
+ | `AiIncident` | Detected anomalies with severity and status |
516
+ | `AiMcpSource` | Model Context Protocol data sources |
517
+ | `AiWorkflow` | Automated workflows with triggers and actions |
518
+ | `AiWorkflowExecution` | Workflow execution history |
519
+ | `AiReport` | Generated reports (daily, weekly, monthly) |
520
+ | `AiTimelineEvent` | Event log for audit trail |
521
+ | `AiUserPreferences` | Per-user AI settings |
522
+
523
+ ## Environment Variables
524
+
525
+ | Variable | Required | Description | Default |
526
+ |----------|----------|-------------|---------|
527
+ | `ANTHROPIC_API_KEY` | At least 1 LLM key | Anthropic API key | — |
528
+ | `ANTHROPIC_DEFAULT_MODEL` | No | Default Anthropic model | `claude-sonnet-4-20250514` |
529
+ | `OPENAI_API_KEY` | At least 1 LLM key | OpenAI API key | — |
530
+ | `OPENAI_DEFAULT_MODEL` | No | Default OpenAI model | `gpt-4o` |
531
+ | `EMBEDDING_MODEL` | No | OpenAI embedding model | `text-embedding-3-small` |
532
+ | `QDRANT_HOST` | No | Qdrant server host | `localhost` |
533
+ | `QDRANT_PORT` | No | Qdrant server port | `6333` |
534
+ | `QDRANT_API_KEY` | No | Qdrant auth key | — |
535
+
536
+ ## MegaAgent Return Type
537
+
538
+ ```typescript
539
+ interface MegaAgent {
540
+ /** Access to service instances */
541
+ services: {
542
+ chat: ChatService;
543
+ llm: LLMService;
544
+ memory: MemoryService | null; // null if memory not configured
545
+ embedding: EmbeddingService | null;
546
+ qdrant: QdrantService | null;
547
+ };
548
+
549
+ /** Prompt settings */
550
+ promptOptions: {
551
+ agentName?: string;
552
+ agentDescription?: string;
553
+ customPrompt?: string;
554
+ };
555
+
556
+ /** Create Express router with all chat endpoints */
557
+ createChatRouter(authMiddleware: AuthMiddleware): Router;
558
+ }
559
+ ```
560
+
561
+ ## Troubleshooting
562
+
563
+ ### `Module '@prisma/client' has no exported member 'AiChat'`
564
+
565
+ Prisma client needs to be regenerated:
566
+
567
+ ```bash
568
+ npx prisma generate
569
+ ```
570
+
571
+ If using a monorepo with linked packages, ensure there's only one `@prisma/client` instance. Add a postinstall script to deduplicate:
572
+
573
+ ```json
574
+ {
575
+ "scripts": {
576
+ "postinstall": "rm -rf node_modules/@mtkn/mega-agent/node_modules/@prisma node_modules/@mtkn/mega-agent/node_modules/.prisma 2>/dev/null || true"
577
+ }
578
+ }
579
+ ```
580
+
581
+ ### Memory system not starting
582
+
583
+ - Verify `OPENAI_API_KEY` is set and valid
584
+ - Check Qdrant is running: `curl http://localhost:6333/collections`
585
+ - Memory is optional — chat works without it
586
+
587
+ ### Tools not being used by the agent
588
+
589
+ - Call `registerTools()` **after** `createMegaAgent()`
590
+ - Ensure `inputSchema` is valid JSON Schema (`type: 'object'` at root)
591
+ - Tool `handler` must return a `Promise`
592
+ - Check tool `description` — the LLM uses it to decide when to call the tool
593
+
594
+ ### Agent not responding or timing out
595
+
596
+ - The agent loop has a max of 10 iterations per message
597
+ - Up to 20 context messages are sent to the LLM
598
+ - Check LLM API key validity and rate limits
599
+
600
+ ## TypeScript Types
601
+
602
+ The package exports a `UserId` type for use in your application:
603
+
604
+ ```typescript
605
+ import type { UserId } from '@mtkn/mega-agent';
606
+
607
+ // UserId = string | number
608
+ // Matches both integer and string-based ID strategies
609
+ ```
610
+
611
+ All service methods accept `UserId` for the `userId` parameter, so your app works regardless of whether your User model uses `Int @id @default(autoincrement())` or `String @id @default(cuid())`.
612
+
613
+ ## Changelog
614
+
615
+ ### v0.2.0
616
+
617
+ - **ID type selection** — `prisma-sync` CLI now supports `--id-type` (cuid/uuid/autoincrement) and `--user-id-type` (int/string) with interactive prompts
618
+ - **Flexible UserId** — All services accept `string | number` for userId, supporting any ID strategy
619
+ - **Removed `uuid` dependency** — Replaced with Node.js built-in `crypto.randomUUID()`
620
+ - **Bug fix** — Fixed hardcoded `userId: 1` in workflow action handlers
621
+
622
+ ## License
623
+
624
+ MIT
@@ -4,12 +4,13 @@
4
4
  */
5
5
  import type { AiArtifact } from '@prisma/client';
6
6
  import type { CreateArtifactDto, UpdateArtifactDto, ArtifactListQuery, ArtifactServiceDependencies } from './artifact.types.js';
7
+ import type { UserId } from '../types/index.js';
7
8
  export declare function initArtifactRepository(deps: ArtifactServiceDependencies): void;
8
9
  export declare class ArtifactRepository {
9
10
  private get prisma();
10
11
  create(data: CreateArtifactDto): Promise<AiArtifact>;
11
12
  findById(id: string): Promise<AiArtifact | null>;
12
- findByUser(userId: number, query?: ArtifactListQuery): Promise<AiArtifact[]>;
13
+ findByUser(userId: UserId, query?: ArtifactListQuery): Promise<AiArtifact[]>;
13
14
  findByChat(chatId: string): Promise<AiArtifact[]>;
14
15
  update(id: string, data: UpdateArtifactDto): Promise<AiArtifact>;
15
16
  delete(id: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"artifact.repository.d.ts","sourceRoot":"","sources":["../../src/artifact/artifact.repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAIhI,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAE9E;AAED,qBAAa,kBAAkB;IAC7B,OAAO,KAAK,MAAM,GAGjB;IAEK,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAgBpD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIhD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAY5E,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAOjD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAahE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxC"}
1
+ {"version":3,"file":"artifact.repository.d.ts","sourceRoot":"","sources":["../../src/artifact/artifact.repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAChI,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAIhD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAE9E;AAED,qBAAa,kBAAkB;IAC7B,OAAO,KAAK,MAAM,GAGjB;IAEK,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAgBpD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIhD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAY5E,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAOjD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAahE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxC"}
@@ -33,7 +33,7 @@ export class ArtifactRepository {
33
33
  async findByUser(userId, query) {
34
34
  return this.prisma.aiArtifact.findMany({
35
35
  where: {
36
- userId,
36
+ userId: userId,
37
37
  ...(query?.type && { type: query.type }),
38
38
  },
39
39
  orderBy: { createdAt: 'desc' },
@@ -1 +1 @@
1
- {"version":3,"file":"artifact.repository.js","sourceRoot":"","sources":["../../src/artifact/artifact.repository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"artifact.repository.js","sourceRoot":"","sources":["../../src/artifact/artifact.repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,IAAI,KAAK,GAAuC,IAAI,CAAC;AAErD,MAAM,UAAU,sBAAsB,CAAC,IAAiC;IACtE,KAAK,GAAG,IAAI,CAAC;AACf,CAAC;AAED,MAAM,OAAO,kBAAkB;IAC7B,IAAY,MAAM;QAChB,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAuB;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;YACnC,IAAI,EAAE;gBACJ,MAAM,EAAE,IAAI,CAAC,MAAa;gBAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAiB;gBAC/B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBAC5C,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM;gBACvC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;gBACrB,QAAQ,EAAE,IAAI,CAAC,QAAkB,IAAI,SAAS;aAC/C;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAU;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,KAAyB;QACxD,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;YACrC,KAAK,EAAE;gBACL,MAAM,EAAE,MAAa;gBACrB,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;aACzC;YACD,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;YAC9B,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE;YACxB,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;SACzB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;YACrC,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;YAC/C,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,IAAuB;QAC9C,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;YACnC,KAAK,EAAE,EAAE,EAAE,EAAE;YACb,IAAI,EAAE;gBACJ,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxC,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACxE,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAiB,EAAE,CAAC;gBACtE,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;gBACrC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAkB,EAAE,CAAC;aAC5D;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;CACF"}
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import type { AiArtifact } from '@prisma/client';
6
6
  import type { CreateArtifactDto, UpdateArtifactDto, ArtifactListQuery, ArtifactServiceDependencies } from './artifact.types.js';
7
+ import type { UserId } from '../types/index.js';
7
8
  export declare function initArtifactService(deps: ArtifactServiceDependencies): void;
8
9
  export declare function getArtifactServiceDeps(): ArtifactServiceDependencies | null;
9
10
  export declare class ArtifactService {
@@ -12,11 +13,11 @@ export declare class ArtifactService {
12
13
  private get logger();
13
14
  create(data: CreateArtifactDto): Promise<AiArtifact>;
14
15
  getById(id: string): Promise<AiArtifact | null>;
15
- listByUser(userId: number, query?: ArtifactListQuery): Promise<AiArtifact[]>;
16
+ listByUser(userId: UserId, query?: ArtifactListQuery): Promise<AiArtifact[]>;
16
17
  listByChat(chatId: string): Promise<AiArtifact[]>;
17
18
  update(id: string, data: UpdateArtifactDto): Promise<AiArtifact>;
18
19
  delete(id: string): Promise<void>;
19
- createFromMessage(userId: number, chatId: string, messageId: string, data: Partial<CreateArtifactDto>): Promise<AiArtifact>;
20
+ createFromMessage(userId: UserId, chatId: string, messageId: string, data: Partial<CreateArtifactDto>): Promise<AiArtifact>;
20
21
  export(id: string, format: 'json' | 'csv' | 'md'): Promise<string>;
21
22
  }
22
23
  //# sourceMappingURL=artifact.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"artifact.service.d.ts","sourceRoot":"","sources":["../../src/artifact/artifact.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,qBAAqB,CAAC;AAK7B,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAG3E;AAED,wBAAgB,sBAAsB,IAAI,2BAA2B,GAAG,IAAI,CAE3E;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAqB;;IAQvC,OAAO,KAAK,MAAM,GAA4B;IAIxC,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAMpD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAI/C,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAI5E,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIjD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAIhE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjC,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/B,OAAO,CAAC,UAAU,CAAC;IAahB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CA6BzE"}
1
+ {"version":3,"file":"artifact.service.d.ts","sourceRoot":"","sources":["../../src/artifact/artifact.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAIhD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAG3E;AAED,wBAAgB,sBAAsB,IAAI,2BAA2B,GAAG,IAAI,CAE3E;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAqB;;IAQvC,OAAO,KAAK,MAAM,GAA4B;IAIxC,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAMpD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAI/C,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAI5E,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIjD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IAIhE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjC,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/B,OAAO,CAAC,UAAU,CAAC;IAahB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CA6BzE"}