@hazeljs/cli 0.5.0 → 0.5.2

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.
@@ -0,0 +1,286 @@
1
+ # HazelJS AI-Native Application
2
+
3
+ A complete AI-native backend application with HazelJS, featuring:
4
+
5
+ - 🤖 **AI Chat Service** - OpenAI-powered chat endpoints
6
+ - 🧠 **AI Agents** - Agents with tools and capabilities
7
+ - 📚 **RAG System** - Document ingestion and semantic search
8
+ - 🏥 **Health Checks** - Application monitoring
9
+ - 📊 **Inspector** - Development tools and debugging
10
+ - 🐳 **Docker Support** - Containerized deployment
11
+ - 📮 **Postman Collection** - Ready-to-use API tests
12
+
13
+ ## Quick Start
14
+
15
+ 1. **Install dependencies**
16
+ ```bash
17
+ npm install
18
+ ```
19
+
20
+ 2. **Configure environment**
21
+ ```bash
22
+ cp .env.example .env
23
+ # Add your OpenAI API key to .env
24
+ ```
25
+
26
+ 3. **Start development server**
27
+ ```bash
28
+ npm run dev
29
+ ```
30
+
31
+ 4. **Visit the application**
32
+ - App: http://localhost:3000
33
+ - Inspector: http://localhost:3000/__hazel
34
+ - Health: http://localhost:3000/health
35
+
36
+ ## Available Endpoints
37
+
38
+ ### AI Chat
39
+ ```bash
40
+ curl -X POST http://localhost:3000/chat \
41
+ -H "Content-Type: application/json" \
42
+ -d '{"message": "What is HazelJS?"}'
43
+ ```
44
+
45
+ ### AI Agent (with tools)
46
+ ```bash
47
+ curl -X POST http://localhost:3000/agent \
48
+ -H "Content-Type: application/json" \
49
+ -d '{"message": "What is the weather in Tokyo?"}'
50
+ ```
51
+
52
+ ### RAG Document Ingestion
53
+ ```bash
54
+ curl -X POST http://localhost:3000/rag/ingest \
55
+ -H "Content-Type: application/json" \
56
+ -d '{"content": "HazelJS is a TypeScript framework for AI-native backends"}'
57
+ ```
58
+
59
+ ### RAG Search
60
+ ```bash
61
+ curl -X POST http://localhost:3000/rag/search \
62
+ -H "Content-Type: application/json" \
63
+ -d '{"query": "What is HazelJS?"}'
64
+ ```
65
+
66
+ ## Docker Deployment
67
+
68
+ ### Using Docker Compose (Recommended)
69
+
70
+ 1. **Configure environment**
71
+ ```bash
72
+ cp .env.example .env
73
+ # Add your OpenAI API key
74
+ ```
75
+
76
+ 2. **Start all services**
77
+ ```bash
78
+ docker-compose up -d
79
+ ```
80
+
81
+ 3. **View logs**
82
+ ```bash
83
+ docker-compose logs -f hazeljs-ai-app
84
+ ```
85
+
86
+ 4. **Stop services**
87
+ ```bash
88
+ docker-compose down
89
+ ```
90
+
91
+ ### Using Docker (Standalone)
92
+
93
+ 1. **Build the image**
94
+ ```bash
95
+ docker build -t hazeljs-ai-app .
96
+ ```
97
+
98
+ 2. **Run the container**
99
+ ```bash
100
+ docker run -p 3000:3000 --env-file .env hazeljs-ai-app
101
+ ```
102
+
103
+ ### Docker Services
104
+
105
+ The `docker-compose.yml` includes:
106
+
107
+ - **hazeljs-ai-app** - Main application (port 3000)
108
+ - **redis** - Caching and queues (port 6379)
109
+ - **postgres** - Database with pgvector extension (port 5432)
110
+
111
+ ## API Testing with Postman
112
+
113
+ 1. **Import the collection**
114
+ ```bash
115
+ # Import HazelJS-AI-Native.postman_collection.json into Postman
116
+ ```
117
+
118
+ 2. **Set environment variable**
119
+ - Create a Postman environment
120
+ - Set `baseUrl` to `http://localhost:3000`
121
+
122
+ 3. **Test the endpoints**
123
+ - Health & Status - Check application health
124
+ - AI Chat - Test chat functionality
125
+ - AI Agent - Test agent with weather tools
126
+ - RAG - Test document ingestion and search
127
+
128
+ ```
129
+ src/
130
+ ├── app.module.ts # Main application module
131
+ ├── index.ts # Application bootstrap
132
+ ├── health.controller.ts # Health check endpoints
133
+ ├── ai/
134
+ │ └── chat.controller.ts # AI chat service
135
+ ├── agent/
136
+ │ └── agent.controller.ts # AI agent with tools
137
+ └── rag/
138
+ └── rag.controller.ts # RAG service
139
+
140
+ prisma/
141
+ ├── schema.prisma # Database schema with vector embeddings
142
+ └── seed.ts # Database seeding script
143
+
144
+ docker/
145
+ └── init-db.sql # Database initialization (pgvector extension)
146
+
147
+ HazelJS-AI-Native.postman_collection.json # API tests
148
+ Dockerfile # Container configuration
149
+ docker-compose.yml # Multi-service deployment
150
+ ```
151
+
152
+ ## Database Setup with Prisma
153
+
154
+ This template uses Prisma for database management. Follow these steps to set up your database:
155
+
156
+ ### 1. Configure Database URL
157
+
158
+ ```bash
159
+ # Add to your .env file
160
+ DATABASE_URL="postgresql://hazeljs:hazeljs123@localhost:5432/hazeljs"
161
+ ```
162
+
163
+ ### 2. Initialize Database
164
+
165
+ ```bash
166
+ # Generate Prisma client
167
+ npm run db:generate
168
+
169
+ # Push schema to database (for development)
170
+ npm run db:push
171
+
172
+ # Seed with sample data
173
+ npm run db:seed
174
+ ```
175
+
176
+ ### 2.1 Vector Indexes
177
+
178
+ The template uses the `pgvector/pgvector` Docker image which includes the vector extension. Prisma automatically handles the vector indexes when you run `db:push`. The schema includes:
179
+
180
+ - **Vector embeddings** stored as `Float[]` for RAG search
181
+ - **Full-text search index** on the `content` field
182
+ - **JSONB index** on the `metadata` field
183
+
184
+ No manual SQL required - Prisma handles everything!
185
+
186
+ ### 3. Database Management
187
+
188
+ ```bash
189
+ # View and edit data
190
+ npm run db:studio
191
+
192
+ # Reset database
193
+ npm run db:reset
194
+
195
+ # Generate client after schema changes
196
+ npm run db:generate
197
+ ```
198
+
199
+ ### Database Schema
200
+
201
+ The template includes:
202
+
203
+ - **Documents** - RAG document storage with vector embeddings
204
+ - **AgentConversations** - AI agent interaction history
205
+ - **ChatHistory** - AI chat session logs
206
+
207
+ ### Using Docker with Database
208
+
209
+ ```bash
210
+ # Start PostgreSQL with Docker
211
+ docker-compose up postgres -d
212
+
213
+ # Run database setup
214
+ npm run db:push
215
+ npm run db:seed
216
+
217
+ # Start the application
218
+ npm run dev
219
+ ```
220
+
221
+ ## Environment Variables
222
+
223
+ - `OPENAI_API_KEY` - Your OpenAI API key (required)
224
+ - `PORT` - Server port (default: 3000)
225
+ - `LOG_LEVEL` - Logging level (default: info)
226
+ - `DATABASE_URL` - Database connection (optional, for PostgreSQL)
227
+ - `REDIS_HOST` - Redis host (default: localhost)
228
+ - `REDIS_PORT` - Redis port (default: 6379)
229
+
230
+ ## Development
231
+
232
+ ```bash
233
+ # Development mode with hot reload
234
+ npm run dev
235
+
236
+ # Build for production
237
+ npm run build
238
+
239
+ # Start production server
240
+ npm start
241
+
242
+ # Run tests
243
+ npm test
244
+
245
+ # Lint code
246
+ npm run lint
247
+
248
+ # Format code
249
+ npm run format
250
+ ```
251
+
252
+ ## Production Deployment
253
+
254
+ ### Environment Setup
255
+
256
+ 1. **Set production variables**
257
+ ```bash
258
+ export NODE_ENV=production
259
+ export OPENAI_API_KEY=your_production_key
260
+ export DATABASE_URL=postgresql://user:pass@host:5432/db
261
+ ```
262
+
263
+ 2. **Deploy with Docker**
264
+ ```bash
265
+ docker-compose -f docker-compose.yml up -d
266
+ ```
267
+
268
+ 3. **Monitor health**
269
+ ```bash
270
+ curl http://localhost:3000/health
271
+ ```
272
+
273
+ ### Scaling
274
+
275
+ - **Horizontal scaling**: Deploy multiple instances behind a load balancer
276
+ - **Database scaling**: Use managed PostgreSQL with connection pooling
277
+ - **Caching**: Redis cluster for distributed caching
278
+ - **Monitoring**: Add Prometheus/Grafana for metrics
279
+
280
+ ## Learn More
281
+
282
+ - [HazelJS Documentation](https://hazeljs.ai/docs)
283
+ - [HazelJS Playground](https://github.com/hazel-js/hazeljs-playground)
284
+ - [AI Agents Guide](https://hazeljs.ai/docs/agents)
285
+ - [RAG Guide](https://hazeljs.ai/docs/rag)
286
+ - [Docker Guide](https://hazeljs.ai/docs/docker)
@@ -0,0 +1,6 @@
1
+ -- Enable pgvector extension for vector similarity search
2
+ CREATE EXTENSION IF NOT EXISTS vector;
3
+
4
+ -- Create index for vector similarity search (cosine distance)
5
+ -- This will be created after running prisma migrate
6
+ CREATE INDEX IF NOT EXISTS documents_embedding_idx ON documents USING ivfflat (embedding vector_cosine_ops);
@@ -0,0 +1,8 @@
1
+ -- Initialize database for HazelJS AI-Native application
2
+ -- This script runs when the PostgreSQL container starts for the first time
3
+
4
+ -- Enable pgvector extension for vector embeddings
5
+ CREATE EXTENSION IF NOT EXISTS vector;
6
+
7
+ -- Create vector index for similarity search (will be used by Prisma)
8
+ -- This ensures the vector extension is ready when Prisma creates indexes
@@ -0,0 +1,64 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ hazeljs-ai-app:
5
+ build: .
6
+ ports:
7
+ - "3000:3000"
8
+ environment:
9
+ - NODE_ENV=production
10
+ - PORT=3000
11
+ - OPENAI_API_KEY=${OPENAI_API_KEY}
12
+ - LOG_LEVEL=info
13
+ volumes:
14
+ - ./logs:/app/logshazeljs-playground/docker-compose.yml
15
+ restart: unless-stopped
16
+ healthcheck:
17
+ test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
18
+ interval: 30s
19
+ timeout: 10s
20
+ retries: 3
21
+ start_period: 40s
22
+
23
+ # Optional: Redis for caching and queue operations
24
+ redis:
25
+ image: redis:7-alpine
26
+ ports:
27
+ - "6379:6379"
28
+ command: redis-server --appendonly yes
29
+ volumes:
30
+ - redis_data:/data
31
+ restart: unless-stopped
32
+ healthcheck:
33
+ test: ["CMD", "redis-cli", "ping"]
34
+ interval: 5s
35
+ timeout: 5s
36
+ retries: 5
37
+
38
+ # Optional: PostgreSQL for database operations
39
+ postgres:
40
+ image: pgvector/pgvector:pg15
41
+ ports:
42
+ - "5432:5432"
43
+ environment:
44
+ - POSTGRES_DB=hazeljs
45
+ - POSTGRES_USER=hazeljs
46
+ - POSTGRES_PASSWORD=hazeljs123
47
+ volumes:
48
+ - postgres_data:/var/lib/postgresql/data
49
+ - ./docker/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
50
+ - ./docker/enable-pgvector.sql:/docker-entrypoint-initdb.d/enable-pgvector.sql
51
+ restart: unless-stopped
52
+ healthcheck:
53
+ test: ["CMD-SHELL", "pg_isready -U hazeljs"]
54
+ interval: 5s
55
+ timeout: 5s
56
+ retries: 5
57
+
58
+ volumes:
59
+ redis_data:
60
+ postgres_data:
61
+
62
+ networks:
63
+ default:
64
+ name: hazeljs-ai-network
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "hazeljs-ai-native-app",
3
+ "version": "0.5.2",
4
+ "description": "A HazelJS AI-native application with agents, RAG, and chat",
5
+ "main": "dist/index.js",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "start": "node dist/index.js",
9
+ "dev": "ts-node-dev --respawn --transpile-only src/index.ts",
10
+ "test": "jest",
11
+ "lint": "eslint \"src/**/*.ts\"",
12
+ "lint:fix": "eslint \"src/**/*.ts\" --fix",
13
+ "format": "prettier --write \"src/**/*.ts\"",
14
+ "db:generate": "prisma generate",
15
+ "db:push": "prisma db push",
16
+ "db:migrate": "prisma migrate dev",
17
+ "db:seed": "ts-node prisma/seed.ts",
18
+ "db:reset": "prisma migrate reset --force",
19
+ "db:studio": "prisma studio"
20
+ },
21
+ "prisma": {
22
+ "seed": "ts-node prisma/seed.ts"
23
+ },
24
+ "dependencies": {
25
+ "@hazeljs/core": "latest",
26
+ "@hazeljs/ai": "latest",
27
+ "@hazeljs/agent": "latest",
28
+ "@hazeljs/rag": "latest",
29
+ "@hazeljs/config": "latest",
30
+ "@hazeljs/cache": "latest",
31
+ "@hazeljs/inspector": "latest",
32
+ "@hazeljs/prisma": "latest",
33
+ "@prisma/client": "^5.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/jest": "^29.5.12",
37
+ "@types/node": "^20.0.0",
38
+ "@typescript-eslint/eslint-plugin": "^8.18.2",
39
+ "@typescript-eslint/parser": "^8.18.2",
40
+ "eslint": "^8.56.0",
41
+ "eslint-config-prettier": "^9.1.0",
42
+ "eslint-plugin-prettier": "^5.1.3",
43
+ "jest": "^29.7.0",
44
+ "prettier": "^3.2.5",
45
+ "prisma": "^5.0.0",
46
+ "ts-jest": "^29.1.2",
47
+ "ts-node": "^10.9.0",
48
+ "ts-node-dev": "^2.0.0",
49
+ "typescript": "^5.3.3"
50
+ },
51
+ "author": "",
52
+ "license": "Apache-2.0"
53
+ }
@@ -0,0 +1,52 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ generator client {
5
+ provider = "prisma-client-js"
6
+ }
7
+
8
+ datasource db {
9
+ provider = "postgresql"
10
+ url = env("DATABASE_URL")
11
+ }
12
+
13
+ model Document {
14
+ id String @id @default(cuid())
15
+ content String
16
+ metadata Json?
17
+ embedding Float[] // Vector embedding for RAG
18
+ createdAt DateTime @default(now())
19
+ updatedAt DateTime @updatedAt
20
+
21
+ @@map("documents")
22
+ // Vector indexes will be created by Prisma when pgvector extension is available
23
+ @@index([content]) // Full-text search
24
+ @@index([metadata]) // JSONB search
25
+ }
26
+
27
+ model AgentConversation {
28
+ id String @id @default(cuid())
29
+ agentName String @map("agent_name")
30
+ sessionId String? @map("session_id")
31
+ userMessage String? @map("user_message")
32
+ agentResponse String? @map("agent_response")
33
+ metadata Json?
34
+ createdAt DateTime @default(now()) @map("created_at")
35
+
36
+ @@map("agent_conversations")
37
+ @@index([sessionId])
38
+ @@index([agentName])
39
+ }
40
+
41
+ model ChatHistory {
42
+ id String @id @default(cuid())
43
+ sessionId String? @map("session_id")
44
+ userMessage String? @map("user_message")
45
+ aiResponse String? @map("ai_response")
46
+ model String?
47
+ tokensUsed Int? @map("tokens_used")
48
+ createdAt DateTime @default(now()) @map("created_at")
49
+
50
+ @@map("chat_history")
51
+ @@index([sessionId])
52
+ }
@@ -0,0 +1,168 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+ import { OpenAIEmbeddings } from '@hazeljs/rag';
3
+
4
+ const prisma = new PrismaClient();
5
+
6
+ async function main() {
7
+ console.log('🌱 Starting database seed...');
8
+
9
+ // Initialize OpenAI embeddings for sample documents
10
+ const embeddings = new OpenAIEmbeddings({
11
+ apiKey: process.env.OPENAI_API_KEY!,
12
+ model: 'text-embedding-3-small',
13
+ });
14
+
15
+ // Sample documents for RAG demonstration
16
+ const sampleDocuments = [
17
+ {
18
+ content: 'HazelJS is a TypeScript framework for building AI-native backend applications. It provides built-in support for AI agents, RAG (Retrieval-Augmented Generation), and seamless integration with LLM providers like OpenAI, Anthropic, and Ollama.',
19
+ metadata: {
20
+ source: 'documentation',
21
+ type: 'introduction',
22
+ category: 'framework',
23
+ tags: ['hazeljs', 'typescript', 'ai', 'backend'],
24
+ },
25
+ },
26
+ {
27
+ content: 'TypeScript decorators provide a way to add metadata and modify the behavior of classes, methods, and properties. In HazelJS, decorators like @Controller, @Get, @Post, @Service, and @Agent are used to define the application structure and routing.',
28
+ metadata: {
29
+ source: 'typescript-guide',
30
+ type: 'tutorial',
31
+ category: 'decorators',
32
+ tags: ['typescript', 'decorators', 'hazeljs', 'patterns'],
33
+ },
34
+ },
35
+ {
36
+ content: 'AI agents in HazelJS can use tools to perform actions like API calls, database queries, or external service integrations. The @Agent decorator defines an agent, and @Tool decorator defines its capabilities.',
37
+ metadata: {
38
+ source: 'agent-guide',
39
+ type: 'tutorial',
40
+ category: 'agents',
41
+ tags: ['agents', 'tools', 'ai', 'automation'],
42
+ },
43
+ },
44
+ {
45
+ content: 'RAG (Retrieval-Augmented Generation) combines document retrieval with LLM generation to provide more accurate and context-aware responses. HazelJS provides built-in RAG services with vector similarity search.',
46
+ metadata: {
47
+ source: 'rag-guide',
48
+ type: 'tutorial',
49
+ category: 'rag',
50
+ tags: ['rag', 'search', 'vectors', 'llm'],
51
+ },
52
+ },
53
+ {
54
+ content: 'The HazelJS Inspector is a development dashboard available at /__hazel that provides real-time insights into your application, including module dependencies, request metrics, and AI agent performance.',
55
+ metadata: {
56
+ source: 'development-guide',
57
+ type: 'tutorial',
58
+ category: 'tools',
59
+ tags: ['inspector', 'development', 'debugging', 'metrics'],
60
+ },
61
+ },
62
+ ];
63
+
64
+ console.log('📚 Creating sample documents...');
65
+ for (const doc of sampleDocuments) {
66
+ try {
67
+ // Generate embedding for the document
68
+ const embedding = await embeddings.embed(doc.content);
69
+
70
+ // Create document with embedding
71
+ await prisma.document.create({
72
+ data: {
73
+ content: doc.content,
74
+ metadata: doc.metadata,
75
+ embedding: embedding,
76
+ },
77
+ });
78
+
79
+ console.log(`✅ Created document: ${doc.metadata.source}`);
80
+ } catch (error) {
81
+ console.error(`❌ Failed to create document: ${doc.metadata.source}`, error);
82
+ }
83
+ }
84
+
85
+ // Sample agent conversations
86
+ console.log('🤖 Creating sample agent conversations...');
87
+ const sampleConversations = [
88
+ {
89
+ agentName: 'WeatherAgent',
90
+ sessionId: 'demo-session-1',
91
+ userMessage: 'What is the weather like in Tokyo?',
92
+ agentResponse: 'The weather in Tokyo is 72°F and sunny with 45% humidity.',
93
+ metadata: {
94
+ toolsUsed: ['getWeather'],
95
+ responseTime: 1.2,
96
+ },
97
+ },
98
+ {
99
+ agentName: 'WeatherAgent',
100
+ sessionId: 'demo-session-2',
101
+ userMessage: 'Tell me about the weather in New York and London',
102
+ agentResponse: 'New York: 65°F and cloudy. London: 58°F and rainy.',
103
+ metadata: {
104
+ toolsUsed: ['getWeather'],
105
+ responseTime: 2.1,
106
+ },
107
+ },
108
+ ];
109
+
110
+ for (const conv of sampleConversations) {
111
+ try {
112
+ await prisma.agentConversation.create({
113
+ data: conv,
114
+ });
115
+ console.log(`✅ Created conversation for ${conv.agentName}`);
116
+ } catch (error) {
117
+ console.error(`❌ Failed to create conversation`, error);
118
+ }
119
+ }
120
+
121
+ // Sample chat history
122
+ console.log('💬 Creating sample chat history...');
123
+ const sampleChatHistory = [
124
+ {
125
+ sessionId: 'chat-session-1',
126
+ userMessage: 'What is HazelJS?',
127
+ aiResponse: 'HazelJS is a TypeScript framework for building AI-native backend applications with built-in support for AI agents, RAG, and LLM integration.',
128
+ model: 'gpt-4',
129
+ tokensUsed: 156,
130
+ },
131
+ {
132
+ sessionId: 'chat-session-1',
133
+ userMessage: 'How do I create an AI agent?',
134
+ aiResponse: 'You can create an AI agent in HazelJS using the @Agent decorator and defining tools with @Tool decorator. Here\'s an example: @Agent({name: "MyAgent"}) class MyAgent { @Tool({description: "My tool"}) async myTool() { return "result"; } }',
135
+ model: 'gpt-4',
136
+ tokensUsed: 234,
137
+ },
138
+ ];
139
+
140
+ for (const chat of sampleChatHistory) {
141
+ try {
142
+ await prisma.chatHistory.create({
143
+ data: chat,
144
+ });
145
+ console.log(`✅ Created chat entry for session ${chat.sessionId}`);
146
+ } catch (error) {
147
+ console.error(`❌ Failed to create chat entry`, error);
148
+ }
149
+ }
150
+
151
+ console.log('🎉 Database seeding completed!');
152
+ console.log('');
153
+ console.log('📊 Summary:');
154
+ console.log(` Documents: ${sampleDocuments.length}`);
155
+ console.log(` Agent Conversations: ${sampleConversations.length}`);
156
+ console.log(` Chat History: ${sampleChatHistory.length}`);
157
+ console.log('');
158
+ console.log('🚀 Your HazelJS AI-Native app is ready to use!');
159
+ }
160
+
161
+ main()
162
+ .catch((e) => {
163
+ console.error('❌ Seeding failed:', e);
164
+ process.exit(1);
165
+ })
166
+ .finally(async () => {
167
+ await prisma.$disconnect();
168
+ });