@hazeljs/agent 0.2.0-alpha.1

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 (166) hide show
  1. package/IMPLEMENTATION_SUMMARY.md +400 -0
  2. package/LICENSE +192 -0
  3. package/PERSISTENCE.md +201 -0
  4. package/PRISMA_INTEGRATION.md +499 -0
  5. package/PRODUCTION_READINESS.md +264 -0
  6. package/QUICKSTART.md +135 -0
  7. package/README.md +541 -0
  8. package/STATE_VS_MEMORY.md +243 -0
  9. package/benchmarks/performance.benchmark.ts +157 -0
  10. package/coverage/clover.xml +1508 -0
  11. package/coverage/lcov-report/base.css +224 -0
  12. package/coverage/lcov-report/block-navigation.js +87 -0
  13. package/coverage/lcov-report/favicon.png +0 -0
  14. package/coverage/lcov-report/index.html +296 -0
  15. package/coverage/lcov-report/prettify.css +1 -0
  16. package/coverage/lcov-report/prettify.js +2 -0
  17. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  18. package/coverage/lcov-report/sorter.js +210 -0
  19. package/coverage/lcov.info +2722 -0
  20. package/dist/agent.module.d.ts +57 -0
  21. package/dist/agent.module.d.ts.map +1 -0
  22. package/dist/agent.module.js +99 -0
  23. package/dist/agent.module.js.map +1 -0
  24. package/dist/context/agent.context.d.ts +27 -0
  25. package/dist/context/agent.context.d.ts.map +1 -0
  26. package/dist/context/agent.context.js +98 -0
  27. package/dist/context/agent.context.js.map +1 -0
  28. package/dist/decorators/agent.decorator.d.ts +21 -0
  29. package/dist/decorators/agent.decorator.d.ts.map +1 -0
  30. package/dist/decorators/agent.decorator.js +38 -0
  31. package/dist/decorators/agent.decorator.js.map +1 -0
  32. package/dist/decorators/delegate.decorator.d.ts +66 -0
  33. package/dist/decorators/delegate.decorator.d.ts.map +1 -0
  34. package/dist/decorators/delegate.decorator.js +108 -0
  35. package/dist/decorators/delegate.decorator.js.map +1 -0
  36. package/dist/decorators/tool.decorator.d.ts +23 -0
  37. package/dist/decorators/tool.decorator.d.ts.map +1 -0
  38. package/dist/decorators/tool.decorator.js +61 -0
  39. package/dist/decorators/tool.decorator.js.map +1 -0
  40. package/dist/events/event.emitter.d.ts +45 -0
  41. package/dist/events/event.emitter.d.ts.map +1 -0
  42. package/dist/events/event.emitter.js +96 -0
  43. package/dist/events/event.emitter.js.map +1 -0
  44. package/dist/executor/agent.executor.d.ts +58 -0
  45. package/dist/executor/agent.executor.d.ts.map +1 -0
  46. package/dist/executor/agent.executor.js +312 -0
  47. package/dist/executor/agent.executor.js.map +1 -0
  48. package/dist/executor/tool.executor.d.ts +55 -0
  49. package/dist/executor/tool.executor.d.ts.map +1 -0
  50. package/dist/executor/tool.executor.js +266 -0
  51. package/dist/executor/tool.executor.js.map +1 -0
  52. package/dist/graph/agent-graph.d.ts +131 -0
  53. package/dist/graph/agent-graph.d.ts.map +1 -0
  54. package/dist/graph/agent-graph.js +462 -0
  55. package/dist/graph/agent-graph.js.map +1 -0
  56. package/dist/graph/agent-graph.types.d.ts +210 -0
  57. package/dist/graph/agent-graph.types.d.ts.map +1 -0
  58. package/dist/graph/agent-graph.types.js +12 -0
  59. package/dist/graph/agent-graph.types.js.map +1 -0
  60. package/dist/index.d.ts +34 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +51 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/prompts/agent-system.prompt.d.ts +10 -0
  65. package/dist/prompts/agent-system.prompt.d.ts.map +1 -0
  66. package/dist/prompts/agent-system.prompt.js +18 -0
  67. package/dist/prompts/agent-system.prompt.js.map +1 -0
  68. package/dist/prompts/index.d.ts +4 -0
  69. package/dist/prompts/index.d.ts.map +1 -0
  70. package/dist/prompts/index.js +20 -0
  71. package/dist/prompts/index.js.map +1 -0
  72. package/dist/prompts/supervisor-routing.prompt.d.ts +9 -0
  73. package/dist/prompts/supervisor-routing.prompt.d.ts.map +1 -0
  74. package/dist/prompts/supervisor-routing.prompt.js +22 -0
  75. package/dist/prompts/supervisor-routing.prompt.js.map +1 -0
  76. package/dist/prompts/supervisor-system.prompt.d.ts +9 -0
  77. package/dist/prompts/supervisor-system.prompt.d.ts.map +1 -0
  78. package/dist/prompts/supervisor-system.prompt.js +21 -0
  79. package/dist/prompts/supervisor-system.prompt.js.map +1 -0
  80. package/dist/registry/agent.registry.d.ts +49 -0
  81. package/dist/registry/agent.registry.d.ts.map +1 -0
  82. package/dist/registry/agent.registry.js +90 -0
  83. package/dist/registry/agent.registry.js.map +1 -0
  84. package/dist/registry/tool.registry.d.ts +54 -0
  85. package/dist/registry/tool.registry.d.ts.map +1 -0
  86. package/dist/registry/tool.registry.js +153 -0
  87. package/dist/registry/tool.registry.js.map +1 -0
  88. package/dist/runtime/agent.runtime.d.ts +218 -0
  89. package/dist/runtime/agent.runtime.d.ts.map +1 -0
  90. package/dist/runtime/agent.runtime.extensions.d.ts +49 -0
  91. package/dist/runtime/agent.runtime.extensions.d.ts.map +1 -0
  92. package/dist/runtime/agent.runtime.extensions.js +93 -0
  93. package/dist/runtime/agent.runtime.extensions.js.map +1 -0
  94. package/dist/runtime/agent.runtime.js +448 -0
  95. package/dist/runtime/agent.runtime.js.map +1 -0
  96. package/dist/state/agent-state.interface.d.ts +63 -0
  97. package/dist/state/agent-state.interface.d.ts.map +1 -0
  98. package/dist/state/agent-state.interface.js +7 -0
  99. package/dist/state/agent-state.interface.js.map +1 -0
  100. package/dist/state/agent.state.d.ts +67 -0
  101. package/dist/state/agent.state.d.ts.map +1 -0
  102. package/dist/state/agent.state.js +172 -0
  103. package/dist/state/agent.state.js.map +1 -0
  104. package/dist/state/database-state.manager.d.ts +63 -0
  105. package/dist/state/database-state.manager.d.ts.map +1 -0
  106. package/dist/state/database-state.manager.js +282 -0
  107. package/dist/state/database-state.manager.js.map +1 -0
  108. package/dist/state/redis-state.manager.d.ts +81 -0
  109. package/dist/state/redis-state.manager.d.ts.map +1 -0
  110. package/dist/state/redis-state.manager.js +253 -0
  111. package/dist/state/redis-state.manager.js.map +1 -0
  112. package/dist/supervisor/supervisor.d.ts +81 -0
  113. package/dist/supervisor/supervisor.d.ts.map +1 -0
  114. package/dist/supervisor/supervisor.js +220 -0
  115. package/dist/supervisor/supervisor.js.map +1 -0
  116. package/dist/types/agent.types.d.ts +166 -0
  117. package/dist/types/agent.types.d.ts.map +1 -0
  118. package/dist/types/agent.types.js +32 -0
  119. package/dist/types/agent.types.js.map +1 -0
  120. package/dist/types/event.types.d.ts +198 -0
  121. package/dist/types/event.types.d.ts.map +1 -0
  122. package/dist/types/event.types.js +46 -0
  123. package/dist/types/event.types.js.map +1 -0
  124. package/dist/types/llm.types.d.ts +66 -0
  125. package/dist/types/llm.types.d.ts.map +1 -0
  126. package/dist/types/llm.types.js +7 -0
  127. package/dist/types/llm.types.js.map +1 -0
  128. package/dist/types/rag.types.d.ts +40 -0
  129. package/dist/types/rag.types.d.ts.map +1 -0
  130. package/dist/types/rag.types.js +7 -0
  131. package/dist/types/rag.types.js.map +1 -0
  132. package/dist/types/tool.types.d.ts +118 -0
  133. package/dist/types/tool.types.d.ts.map +1 -0
  134. package/dist/types/tool.types.js +19 -0
  135. package/dist/types/tool.types.js.map +1 -0
  136. package/dist/utils/circuit-breaker.d.ts +9 -0
  137. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  138. package/dist/utils/circuit-breaker.js +16 -0
  139. package/dist/utils/circuit-breaker.js.map +1 -0
  140. package/dist/utils/health-check.d.ts +71 -0
  141. package/dist/utils/health-check.d.ts.map +1 -0
  142. package/dist/utils/health-check.js +156 -0
  143. package/dist/utils/health-check.js.map +1 -0
  144. package/dist/utils/logger.d.ts +53 -0
  145. package/dist/utils/logger.d.ts.map +1 -0
  146. package/dist/utils/logger.js +133 -0
  147. package/dist/utils/logger.js.map +1 -0
  148. package/dist/utils/metrics.d.ts +90 -0
  149. package/dist/utils/metrics.d.ts.map +1 -0
  150. package/dist/utils/metrics.js +186 -0
  151. package/dist/utils/metrics.js.map +1 -0
  152. package/dist/utils/rate-limiter.d.ts +44 -0
  153. package/dist/utils/rate-limiter.d.ts.map +1 -0
  154. package/dist/utils/rate-limiter.js +82 -0
  155. package/dist/utils/rate-limiter.js.map +1 -0
  156. package/dist/utils/retry.d.ts +42 -0
  157. package/dist/utils/retry.d.ts.map +1 -0
  158. package/dist/utils/retry.js +103 -0
  159. package/dist/utils/retry.js.map +1 -0
  160. package/jest.config.js +30 -0
  161. package/logs/combined.log +1 -0
  162. package/logs/error.log +0 -0
  163. package/package.json +74 -0
  164. package/prisma-schema.example.prisma +76 -0
  165. package/tests/setup.ts +17 -0
  166. package/tsconfig.tsbuildinfo +1 -0
package/PERSISTENCE.md ADDED
@@ -0,0 +1,201 @@
1
+ # Agent State Persistence
2
+
3
+ > **Note**: This document covers **Agent State Persistence** (execution flow, steps, state transitions).
4
+ > For information about **Memory Persistence** (conversation history, entities, facts), see `@hazeljs/rag` documentation.
5
+ > For understanding the difference between State and Memory, see [STATE_VS_MEMORY.md](./STATE_VS_MEMORY.md).
6
+
7
+ The `@hazeljs/agent` package supports multiple persistence backends for agent execution state. Choose the right backend based on your needs:
8
+
9
+ ## Available Backends
10
+
11
+ ### 1. In-Memory (Default)
12
+ - **Best for**: Development, testing, single-instance deployments
13
+ - **Pros**: Fast, no setup required
14
+ - **Cons**: Data lost on restart, not suitable for distributed systems
15
+
16
+ ### 2. Redis
17
+ - **Best for**: Production, distributed systems, high-performance scenarios
18
+ - **Pros**: Fast, distributed, TTL support, pub/sub capabilities
19
+ - **Cons**: Requires Redis infrastructure
20
+
21
+ ### 3. Database (Prisma)
22
+ - **Best for**: Long-term persistence, audit trails, analytics
23
+ - **Pros**: Durable, queryable, full audit trail
24
+ - **Cons**: Slower than Redis, requires database setup
25
+
26
+ ## Usage
27
+
28
+ ### In-Memory (Default)
29
+
30
+ No configuration needed - this is the default:
31
+
32
+ ```typescript
33
+ import { AgentRuntime } from '@hazeljs/agent';
34
+
35
+ const runtime = new AgentRuntime({
36
+ // Uses in-memory state manager by default
37
+ });
38
+ ```
39
+
40
+ ### Redis Backend
41
+
42
+ 1. Install Redis client:
43
+ ```bash
44
+ npm install redis
45
+ ```
46
+
47
+ 2. Configure Redis state manager:
48
+
49
+ ```typescript
50
+ import { AgentRuntime, RedisStateManager } from '@hazeljs/agent';
51
+ import { createClient } from 'redis';
52
+
53
+ // Create Redis client
54
+ const redisClient = createClient({
55
+ url: process.env.REDIS_URL || 'redis://localhost:6379',
56
+ });
57
+
58
+ await redisClient.connect();
59
+
60
+ // Create Redis state manager
61
+ const stateManager = new RedisStateManager({
62
+ client: redisClient,
63
+ keyPrefix: 'agent:state:', // Optional
64
+ defaultTTL: 3600, // 1 hour for active contexts
65
+ completedTTL: 86400, // 24 hours for completed contexts
66
+ failedTTL: 604800, // 7 days for failed contexts
67
+ });
68
+
69
+ // Use with runtime
70
+ const runtime = new AgentRuntime({
71
+ stateManager,
72
+ });
73
+ ```
74
+
75
+ ### Database Backend (Prisma)
76
+
77
+ 1. Install Prisma:
78
+ ```bash
79
+ npm install @prisma/client
80
+ ```
81
+
82
+ 2. Add schema to your Prisma schema:
83
+ - Copy models from `prisma-schema.example.prisma` to your `prisma/schema.prisma`
84
+ - See [PRISMA_INTEGRATION.md](./PRISMA_INTEGRATION.md) for detailed instructions
85
+
86
+ 3. Run migrations:
87
+ ```bash
88
+ npx prisma migrate dev --name add_agent_state_models
89
+ npx prisma generate
90
+ ```
91
+
92
+ 4. Configure database state manager:
93
+
94
+ ```typescript
95
+ import { AgentRuntime, DatabaseStateManager } from '@hazeljs/agent';
96
+ import { PrismaClient } from '@prisma/client';
97
+
98
+ // Create Prisma client
99
+ const prisma = new PrismaClient();
100
+
101
+ // Create database state manager
102
+ const stateManager = new DatabaseStateManager({
103
+ client: prisma,
104
+ softDelete: true, // Keep deleted contexts for audit
105
+ autoArchive: false, // Optional: auto-archive old contexts
106
+ archiveThresholdDays: 30,
107
+ });
108
+
109
+ // Use with runtime
110
+ const runtime = new AgentRuntime({
111
+ stateManager,
112
+ });
113
+ ```
114
+
115
+ ## Hybrid Approach (Recommended for Production)
116
+
117
+ Use Redis for hot data and Database for cold/archived data:
118
+
119
+ ```typescript
120
+ import { AgentRuntime, RedisStateManager, DatabaseStateManager } from '@hazeljs/agent';
121
+
122
+ // Redis for active executions
123
+ const redisStateManager = new RedisStateManager({
124
+ client: redisClient,
125
+ defaultTTL: 3600,
126
+ });
127
+
128
+ // Database for persistence and audit
129
+ const dbStateManager = new DatabaseStateManager({
130
+ client: prisma,
131
+ });
132
+
133
+ // Use Redis for runtime
134
+ const runtime = new AgentRuntime({
135
+ stateManager: redisStateManager,
136
+ });
137
+
138
+ // Optionally sync to database periodically
139
+ setInterval(async () => {
140
+ const activeContexts = await redisStateManager.getSessionContexts(sessionId);
141
+ for (const context of activeContexts) {
142
+ if (context.state === 'completed' || context.state === 'failed') {
143
+ // Archive to database
144
+ await dbStateManager.createContext(
145
+ context.agentId,
146
+ context.sessionId,
147
+ context.input,
148
+ context.userId,
149
+ context.metadata
150
+ );
151
+ }
152
+ }
153
+ }, 60000); // Every minute
154
+ ```
155
+
156
+ ## RAG Memory Persistence
157
+
158
+ RAG memory (conversation history, entities, facts) uses the `@hazeljs/rag` package's `MemoryManager`, which supports:
159
+
160
+ - **BufferMemory**: In-memory (default)
161
+ - **VectorMemory**: Vector stores (Pinecone, Weaviate, Qdrant, ChromaDB)
162
+ - **HybridMemory**: Combination of both
163
+
164
+ See `@hazeljs/rag` documentation for RAG memory configuration.
165
+
166
+ ## Performance Considerations
167
+
168
+ - **Redis**: Best for high-frequency reads/writes, distributed systems
169
+ - **Database**: Best for long-term storage, complex queries, analytics
170
+ - **In-Memory**: Best for development, single-instance deployments
171
+
172
+ ## Migration Guide
173
+
174
+ ### From In-Memory to Redis
175
+
176
+ 1. Install Redis and client
177
+ 2. Create RedisStateManager
178
+ 3. Pass to AgentRuntime config
179
+ 4. No code changes needed - interface is compatible
180
+
181
+ ### From In-Memory to Database
182
+
183
+ 1. Install Prisma
184
+ 2. Add schema and run migrations
185
+ 3. Create DatabaseStateManager
186
+ 4. Pass to AgentRuntime config
187
+ 5. No code changes needed - interface is compatible
188
+
189
+ ## Best Practices
190
+
191
+ 1. **Development**: Use in-memory (default)
192
+ 2. **Staging**: Use Redis for testing distributed scenarios
193
+ 3. **Production**: Use Redis for active state, Database for audit/analytics
194
+ 4. **High Volume**: Use Redis with appropriate TTL settings
195
+ 5. **Compliance**: Use Database for full audit trails
196
+
197
+ ## Related Documentation
198
+
199
+ - **[PRISMA_INTEGRATION.md](./PRISMA_INTEGRATION.md)** - Step-by-step guide for integrating Prisma schema
200
+ - **[STATE_VS_MEMORY.md](./STATE_VS_MEMORY.md)** - Understanding the difference between Agent State and Memory
201
+ - **[prisma-schema.example.prisma](./prisma-schema.example.prisma)** - Example Prisma schema file
@@ -0,0 +1,499 @@
1
+ # Prisma Integration Guide
2
+
3
+ This guide shows you how to integrate the Agent State Persistence models into your existing Prisma schema.
4
+
5
+ ## Quick Start
6
+
7
+ ### Step 1: Add Models to Your Schema
8
+
9
+ Copy the models from `prisma-schema.example.prisma` into your existing `prisma/schema.prisma` file:
10
+
11
+ ```prisma
12
+ // Your existing schema.prisma
13
+ generator client {
14
+ provider = "prisma-client-js"
15
+ }
16
+
17
+ datasource db {
18
+ provider = "postgresql" // or "mysql", "sqlite", etc.
19
+ url = env("DATABASE_URL")
20
+ }
21
+
22
+ // Your existing models...
23
+ model User {
24
+ id Int @id @default(autoincrement())
25
+ name String
26
+ email String @unique
27
+ }
28
+
29
+ // Add these Agent State models:
30
+ model AgentContext {
31
+ id String @id @default(uuid())
32
+ executionId String @unique
33
+ agentId String
34
+ sessionId String
35
+ userId String?
36
+ input String
37
+ state String // AgentState enum as string
38
+ steps Json // AgentStep[]
39
+ conversationHistory Json // ConversationMessage[]
40
+ workingMemory Json // Record<string, unknown>
41
+ facts Json // string[]
42
+ entities Json // Entity[]
43
+ ragContext Json? // string[]
44
+ metadata Json // Record<string, unknown>
45
+ createdAt DateTime @default(now())
46
+ updatedAt DateTime @updatedAt
47
+ deletedAt DateTime? // For soft deletes
48
+ agentSteps AgentStep[] // Relation to steps table (optional)
49
+
50
+ @@index([sessionId])
51
+ @@index([userId])
52
+ @@index([agentId])
53
+ @@index([state])
54
+ @@index([createdAt])
55
+ @@index([deletedAt])
56
+ @@map("agent_contexts")
57
+ }
58
+
59
+ // Optional: Separate table for execution steps (for better querying)
60
+ model AgentStep {
61
+ id String @id @default(uuid())
62
+ executionId String
63
+ stepNumber Int
64
+ state String
65
+ action Json?
66
+ result Json?
67
+ error String?
68
+ timestamp DateTime @default(now())
69
+ duration Int?
70
+
71
+ context AgentContext @relation(fields: [executionId], references: [executionId], onDelete: Cascade)
72
+
73
+ @@index([executionId])
74
+ @@index([timestamp])
75
+ @@map("agent_steps")
76
+ }
77
+
78
+ // Optional: Session tracking
79
+ model AgentSession {
80
+ id String @id @default(uuid())
81
+ sessionId String @unique
82
+ userId String?
83
+ agentId String
84
+ createdAt DateTime @default(now())
85
+ updatedAt DateTime @updatedAt
86
+ completedAt DateTime?
87
+
88
+ @@index([userId])
89
+ @@index([agentId])
90
+ @@index([createdAt])
91
+ @@map("agent_sessions")
92
+ }
93
+ ```
94
+
95
+ ### Step 2: Create Migration
96
+
97
+ ```bash
98
+ # Create a new migration
99
+ npx prisma migrate dev --name add_agent_state_models
100
+
101
+ # Or if using migrate manually
102
+ npx prisma migrate dev
103
+ ```
104
+
105
+ ### Step 3: Generate Prisma Client
106
+
107
+ ```bash
108
+ npx prisma generate
109
+ ```
110
+
111
+ ### Step 4: Use in Your Code
112
+
113
+ ```typescript
114
+ import { AgentRuntime, DatabaseStateManager } from '@hazeljs/agent';
115
+ import { PrismaClient } from '@prisma/client';
116
+
117
+ const prisma = new PrismaClient();
118
+
119
+ const stateManager = new DatabaseStateManager({
120
+ client: prisma,
121
+ softDelete: true,
122
+ });
123
+
124
+ const runtime = new AgentRuntime({
125
+ stateManager,
126
+ });
127
+ ```
128
+
129
+ ## Integration Options
130
+
131
+ ### Option 1: Minimal (Recommended)
132
+
133
+ Add only the `AgentContext` model. Steps are stored as JSON in the context:
134
+
135
+ ```prisma
136
+ model AgentContext {
137
+ id String @id @default(uuid())
138
+ executionId String @unique
139
+ agentId String
140
+ sessionId String
141
+ userId String?
142
+ input String
143
+ state String
144
+ steps Json // All steps stored here
145
+ conversationHistory Json
146
+ workingMemory Json
147
+ facts Json
148
+ entities Json
149
+ ragContext Json?
150
+ metadata Json
151
+ createdAt DateTime @default(now())
152
+ updatedAt DateTime @updatedAt
153
+ deletedAt DateTime?
154
+
155
+ @@index([sessionId])
156
+ @@index([userId])
157
+ @@index([agentId])
158
+ @@index([state])
159
+ @@map("agent_contexts")
160
+ }
161
+ ```
162
+
163
+ **Pros**: Simple, single table, fast writes
164
+ **Cons**: Can't query steps independently
165
+
166
+ ### Option 2: Full (For Analytics)
167
+
168
+ Add all three models (`AgentContext`, `AgentStep`, `AgentSession`) for better querying:
169
+
170
+ ```prisma
171
+ model AgentContext {
172
+ // ... fields ...
173
+ agentSteps AgentStep[] // Relation
174
+ }
175
+
176
+ model AgentStep {
177
+ // ... fields ...
178
+ context AgentContext @relation(...)
179
+ }
180
+
181
+ model AgentSession {
182
+ // ... fields ...
183
+ }
184
+ ```
185
+
186
+ **Pros**: Can query steps independently, better for analytics
187
+ **Cons**: More complex, requires joins
188
+
189
+ ### Option 3: Custom Schema
190
+
191
+ Adapt the schema to your needs:
192
+
193
+ ```prisma
194
+ // Example: Add relation to your User model
195
+ model User {
196
+ id Int @id @default(autoincrement())
197
+ name String
198
+ email String @unique
199
+ agentContexts AgentContext[] // Add this
200
+ }
201
+
202
+ model AgentContext {
203
+ // ... fields ...
204
+ userId String?
205
+ user User? @relation(fields: [userId], references: [id]) // Add this
206
+ }
207
+ ```
208
+
209
+ ## Database Compatibility
210
+
211
+ ### PostgreSQL (Recommended)
212
+
213
+ ```prisma
214
+ datasource db {
215
+ provider = "postgresql"
216
+ url = env("DATABASE_URL")
217
+ }
218
+ ```
219
+
220
+ ✅ Full support for JSON fields
221
+ ✅ Excellent indexing
222
+ ✅ Best performance
223
+
224
+ ### MySQL
225
+
226
+ ```prisma
227
+ datasource db {
228
+ provider = "mysql"
229
+ url = env("DATABASE_URL")
230
+ }
231
+ ```
232
+
233
+ ✅ JSON support (MySQL 5.7+)
234
+ ✅ Good performance
235
+ ⚠️ Use `Json` type for JSON fields
236
+
237
+ ### SQLite
238
+
239
+ ```prisma
240
+ datasource db {
241
+ provider = "sqlite"
242
+ url = env("DATABASE_URL")
243
+ }
244
+ ```
245
+
246
+ ✅ Works for development
247
+ ⚠️ JSON stored as TEXT (slower queries)
248
+ ⚠️ Not recommended for production
249
+
250
+ ### SQL Server
251
+
252
+ ```prisma
253
+ datasource db {
254
+ provider = "sqlserver"
255
+ url = env("DATABASE_URL")
256
+ }
257
+ ```
258
+
259
+ ✅ JSON support (SQL Server 2016+)
260
+ ✅ Good for enterprise
261
+
262
+ ## Migration Examples
263
+
264
+ ### Initial Migration
265
+
266
+ ```bash
267
+ # Create migration
268
+ npx prisma migrate dev --name add_agent_state_models
269
+
270
+ # This will create:
271
+ # - agent_contexts table
272
+ # - agent_steps table (if included)
273
+ # - agent_sessions table (if included)
274
+ # - All indexes
275
+ ```
276
+
277
+ ### Adding to Existing Database
278
+
279
+ If you already have a database with other tables:
280
+
281
+ ```bash
282
+ # Prisma will detect the new models
283
+ npx prisma migrate dev --name add_agent_state
284
+
285
+ # Review the migration SQL before applying
286
+ npx prisma migrate dev --create-only
287
+ # Edit the migration file if needed
288
+ npx prisma migrate dev
289
+ ```
290
+
291
+ ## Schema Customization
292
+
293
+ ### Customize Field Types
294
+
295
+ ```prisma
296
+ model AgentContext {
297
+ // Use your own ID format
298
+ id String @id @default(cuid()) // or @default(uuid())
299
+
300
+ // Add custom fields
301
+ priority Int @default(0)
302
+ tags String[]
303
+
304
+ // Customize JSON fields
305
+ metadata Json @default("{}")
306
+ }
307
+ ```
308
+
309
+ ### Add Relations
310
+
311
+ ```prisma
312
+ model User {
313
+ id Int @id @default(autoincrement())
314
+ agentContexts AgentContext[]
315
+ }
316
+
317
+ model AgentContext {
318
+ userId String?
319
+ user User? @relation(fields: [userId], references: [id])
320
+ }
321
+ ```
322
+
323
+ ### Custom Indexes
324
+
325
+ ```prisma
326
+ model AgentContext {
327
+ // ... fields ...
328
+
329
+ // Add composite indexes
330
+ @@index([agentId, state])
331
+ @@index([sessionId, createdAt])
332
+
333
+ // Add full-text search (PostgreSQL)
334
+ @@index([input(ops: Raw("gin_trgm_ops"))])
335
+ }
336
+ ```
337
+
338
+ ## Using with HazelJS Prisma Module
339
+
340
+ If you're using `@hazeljs/prisma`:
341
+
342
+ ```typescript
343
+ import { HazelModule } from '@hazeljs/core';
344
+ import { PrismaModule } from '@hazeljs/prisma';
345
+ import { AgentModule } from '@hazeljs/agent';
346
+ import { PrismaClient } from '@prisma/client';
347
+ import { DatabaseStateManager } from '@hazeljs/agent';
348
+
349
+ @HazelModule({
350
+ imports: [
351
+ PrismaModule.forRoot({
352
+ // Your Prisma config
353
+ }),
354
+ AgentModule.forRoot({
355
+ // Agent config
356
+ }),
357
+ ],
358
+ })
359
+ export class AppModule {
360
+ constructor(private prisma: PrismaClient) {
361
+ // Create state manager
362
+ const stateManager = new DatabaseStateManager({
363
+ client: this.prisma,
364
+ });
365
+
366
+ // Use with AgentRuntime
367
+ // (configure in your agent service)
368
+ }
369
+ }
370
+ ```
371
+
372
+ ## Troubleshooting
373
+
374
+ ### Error: "Model AgentContext not found"
375
+
376
+ **Solution**: Make sure you've:
377
+ 1. Added the model to your schema
378
+ 2. Run `npx prisma generate`
379
+ 3. Restarted your application
380
+
381
+ ### Error: "Column does not exist"
382
+
383
+ **Solution**: Run migrations:
384
+ ```bash
385
+ npx prisma migrate dev
386
+ ```
387
+
388
+ ### JSON Field Issues
389
+
390
+ **PostgreSQL**: Use `Json` type (works out of the box)
391
+ **MySQL**: Use `Json` type (MySQL 5.7+)
392
+ **SQLite**: Use `String` type and parse manually, or use `Json` (stored as TEXT)
393
+
394
+ ### Performance Issues
395
+
396
+ 1. **Add indexes** on frequently queried fields:
397
+ ```prisma
398
+ @@index([sessionId])
399
+ @@index([userId])
400
+ @@index([state])
401
+ ```
402
+
403
+ 2. **Use soft deletes** to avoid expensive DELETE operations:
404
+ ```prisma
405
+ deletedAt DateTime?
406
+ @@index([deletedAt])
407
+ ```
408
+
409
+ 3. **Partition large tables** (PostgreSQL):
410
+ ```sql
411
+ -- Partition by date for very large tables
412
+ CREATE TABLE agent_contexts_2024_12 PARTITION OF agent_contexts
413
+ FOR VALUES FROM ('2024-12-01') TO ('2025-01-01');
414
+ ```
415
+
416
+ ## Example: Complete Integration
417
+
418
+ ```prisma
419
+ // prisma/schema.prisma
420
+ generator client {
421
+ provider = "prisma-client-js"
422
+ }
423
+
424
+ datasource db {
425
+ provider = "postgresql"
426
+ url = env("DATABASE_URL")
427
+ }
428
+
429
+ // Your existing models
430
+ model User {
431
+ id Int @id @default(autoincrement())
432
+ email String @unique
433
+ name String
434
+ agentContexts AgentContext[] // Relation
435
+ }
436
+
437
+ // Agent State models
438
+ model AgentContext {
439
+ id String @id @default(uuid())
440
+ executionId String @unique
441
+ agentId String
442
+ sessionId String
443
+ userId String?
444
+ user User? @relation(fields: [userId], references: [id])
445
+ input String
446
+ state String
447
+ steps Json
448
+ conversationHistory Json
449
+ workingMemory Json
450
+ facts Json
451
+ entities Json
452
+ ragContext Json?
453
+ metadata Json
454
+ createdAt DateTime @default(now())
455
+ updatedAt DateTime @updatedAt
456
+ deletedAt DateTime?
457
+
458
+ @@index([sessionId])
459
+ @@index([userId])
460
+ @@index([agentId])
461
+ @@index([state])
462
+ @@index([createdAt])
463
+ @@map("agent_contexts")
464
+ }
465
+ ```
466
+
467
+ ```typescript
468
+ // app.module.ts
469
+ import { HazelModule } from '@hazeljs/core';
470
+ import { PrismaModule } from '@hazeljs/prisma';
471
+ import { AgentModule } from '@hazeljs/agent';
472
+ import { DatabaseStateManager } from '@hazeljs/agent';
473
+
474
+ @HazelModule({
475
+ imports: [
476
+ PrismaModule.forRoot({}),
477
+ AgentModule.forRoot({
478
+ stateManager: new DatabaseStateManager({
479
+ client: prismaClient, // From PrismaModule
480
+ softDelete: true,
481
+ }),
482
+ }),
483
+ ],
484
+ })
485
+ export class AppModule {}
486
+ ```
487
+
488
+ ## Next Steps
489
+
490
+ 1. ✅ Add models to your schema
491
+ 2. ✅ Run migrations
492
+ 3. ✅ Generate Prisma client
493
+ 4. ✅ Configure DatabaseStateManager
494
+ 5. ✅ Test with your agents
495
+
496
+ For more details, see:
497
+ - [PERSISTENCE.md](./PERSISTENCE.md) - Configuration guide
498
+ - [STATE_VS_MEMORY.md](./STATE_VS_MEMORY.md) - Understanding State vs Memory
499
+ - [prisma-schema.example.prisma](./prisma-schema.example.prisma) - Full schema example