dank-ai 1.0.5 → 1.0.7

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/README.md CHANGED
@@ -1,107 +1,1734 @@
1
- # my-interactive-project
1
+ # 🚀 Dank Agent Service
2
2
 
3
- A Dank AI agent project with modern event handling and Docker orchestration.
3
+ **Docker-based AI Agent Orchestration Platform**
4
4
 
5
- ## Features
5
+ Dank is a powerful Node.js service that allows you to define, deploy, and manage AI agents using Docker containers. Each agent runs in its own isolated environment with configurable resources, LLM providers, and custom handlers. Built for production with comprehensive CI/CD support and Docker registry integration.
6
6
 
7
- - 🤖 **AI Agents**: Powered by multiple LLM providers (OpenAI, Anthropic, Google AI)
8
- - 🐳 **Docker Integration**: Containerized agents with automatic management
9
- - 📡 **Event System**: Real-time event handling for prompts, responses, and tools
10
- - 🔧 **Auto-Detection**: Automatically enables features based on usage
11
- - 📊 **Monitoring**: Built-in logging and status monitoring
7
+ ## Features
12
8
 
13
- ## Quick Start
9
+ - **🤖 Multi-LLM Support**: OpenAI, Anthropic, Cohere, Ollama, and custom providers
10
+ - **🐳 Docker Orchestration**: Isolated agent containers with resource management
11
+ - **⚡ Easy Configuration**: Define agents with simple JavaScript configuration
12
+ - **📊 Real-time Monitoring**: Built-in health checks and status monitoring
13
+ - **🔧 Flexible Handlers**: Custom event handlers for agent outputs and errors
14
+ - **🎯 CLI Interface**: Powerful command-line tools for agent management
15
+ - **🏗️ Production Builds**: Build and push Docker images to registries with custom naming
16
+ - **🔄 CI/CD Ready**: Seamless integration with GitHub Actions, GitLab CI, and other platforms
14
17
 
15
- 1. **Install dependencies:**
16
- ```bash
17
- npm install
18
- ```
18
+ ## 🚀 Quick Start
19
19
 
20
- 2. **Set up environment:**
21
- ```bash
22
- cp .env.example .env
23
- # Edit .env with your API keys
24
- ```
20
+ ### Prerequisites
21
+ Before you begin, make sure you have:
22
+ - **Node.js 16+** installed
23
+ - **Docker Desktop** or **Docker Engine** (will be installed automatically if missing)
24
+ - **API keys** for your chosen LLM provider(s)
25
25
 
26
- 3. **Configure your agents:**
27
- Edit `dank.config.js` to define your agents and their capabilities.
26
+ > **🆕 Auto-Docker Installation**: Dank will automatically detect, install, and start Docker if it's not available on your system. No manual setup required!
28
27
 
29
- 4. **Start your agents:**
30
- ```bash
31
- npm start
32
- # or
33
- dank run
34
- ```
28
+ ### 1. Install Dank globally
29
+ ```bash
30
+ npm install -g dank-ai
31
+ ```
32
+
33
+ ### 2. Initialize a new project
34
+ ```bash
35
+ # Create and navigate to your project directory
36
+ mkdir my-agent-project
37
+ cd my-agent-project
38
+
39
+ # Initialize Dank project
40
+ dank init my-agent-project
41
+ ```
42
+
43
+ This creates:
44
+ ```
45
+ my-agent-project/
46
+ ├── dank.config.js # Your agent configuration
47
+ ├── agents/ # Custom agent code (optional)
48
+ │ └── example-agent.js
49
+ └── .dank/ # Generated files
50
+ └── project.yaml
51
+ ```
52
+
53
+ ### 3. Set up environment variables
54
+ Create a `.env` file or export environment variables:
55
+
56
+ ```bash
57
+ # For OpenAI
58
+ export OPENAI_API_KEY="your-openai-api-key"
59
+
60
+ # For Anthropic
61
+ export ANTHROPIC_API_KEY="your-anthropic-api-key"
62
+
63
+ # For Cohere
64
+ export COHERE_API_KEY="your-cohere-api-key"
65
+ ```
66
+
67
+ ### 4. Configure your agents
68
+ Edit `dank.config.js` to define your agents:
69
+
70
+ ```javascript
71
+ const { createAgent } = require('dank');
72
+
73
+ module.exports = {
74
+ name: 'my-agent-project',
75
+
76
+ agents: [
77
+ createAgent('assistant')
78
+ .setLLM('openai', {
79
+ apiKey: process.env.OPENAI_API_KEY,
80
+ model: 'gpt-3.5-turbo',
81
+ temperature: 0.7
82
+ })
83
+ .setPrompt('You are a helpful assistant that responds with enthusiasm!')
84
+ .setResources({
85
+ memory: '512m',
86
+ cpu: 1
87
+ })
88
+ .addHandler('output', (data) => {
89
+ console.log('Assistant says:', data);
90
+ })
91
+ ]
92
+ };
93
+ ```
94
+
95
+ ### 5. Build Docker images (optional)
96
+ ```bash
97
+ # Build agent images (base image is pulled automatically)
98
+ dank build
99
+
100
+ # Or build only the base image
101
+ dank build --base
102
+ ```
103
+
104
+ ### 6. Start your agents
105
+ ```bash
106
+ # Start all agents
107
+ dank run
108
+
109
+ # Or run in detached mode (background)
110
+ dank run --detached
111
+ ```
112
+
113
+ ### 7. Monitor your agents
114
+ ```bash
115
+ # Check agent status
116
+ dank status
117
+
118
+ # Watch status in real-time
119
+ dank status --watch
120
+
121
+ # View agent logs
122
+ dank logs assistant
123
+
124
+ # Follow logs in real-time
125
+ dank logs assistant --follow
126
+ ```
127
+
128
+ ### 8. Build for production (optional)
129
+ ```bash
130
+ # Build production images with custom naming
131
+ dank build:prod
132
+
133
+ # Build and push to registry
134
+ dank build:prod --push
135
+
136
+ # Build with custom tag and registry
137
+ dank build:prod --tag v1.0.0 --registry ghcr.io --namespace myorg --push
138
+ ```
139
+
140
+ ## 📋 CLI Commands
141
+
142
+ ### Core Commands
143
+ ```bash
144
+ dank run # Start all defined agents
145
+ dank status # Show agent status
146
+ dank stop [agents...] # Stop specific agents
147
+ dank stop --all # Stop all agents
148
+ dank logs [agent] # View agent logs
149
+ ```
150
+
151
+ ### Management Commands
152
+ ```bash
153
+ dank init [name] # Initialize new project
154
+ dank build # Build Docker images
155
+ dank build:prod # Build agent images with custom naming
156
+ dank clean # Clean up Docker resources
157
+ ```
158
+
159
+ ### Agent Image Build Commands
160
+ ```bash
161
+ dank build:prod # Build with agent image config
162
+ dank build:prod --push # Build and push to registry (CLI only)
163
+ dank build:prod --tag v1.0.0 # Build with custom tag
164
+ dank build:prod --registry ghcr.io # Build for specific registry
165
+ dank build:prod --force # Force rebuild without cache
166
+ ```
167
+
168
+ > **💡 Push Control**: The `--push` option is the only way to push images to registries. Agent configuration defines naming, CLI controls pushing.
35
169
 
36
- ## Available Commands
170
+ ### Advanced Options
171
+ ```bash
172
+ dank run --detached # Run in background
173
+ dank run --no-build # Skip rebuilding images (default is to rebuild)
174
+ dank run --pull # Pull latest base image before building
175
+ dank status --watch # Live status monitoring
176
+ dank logs --follow # Follow log output
177
+ ```
178
+
179
+ ### Production Build Options
180
+ ```bash
181
+ dank build:prod --push # Build and push to registry
182
+ dank build:prod --tag v1.0.0 # Build with custom tag
183
+ dank build:prod --registry ghcr.io # Build for GitHub Container Registry
184
+ dank build:prod --namespace mycompany # Build with custom namespace
185
+ dank build:prod --force # Force rebuild without cache
186
+ ```
187
+
188
+ ## 🤖 Agent Configuration
189
+
190
+ ### Basic Agent Setup
191
+ ```javascript
192
+ const agent = createAgent('my-agent')
193
+ .setLLM('openai', {
194
+ apiKey: process.env.OPENAI_API_KEY,
195
+ model: 'gpt-4',
196
+ temperature: 0.8
197
+ })
198
+ .setPrompt('Your system prompt here')
199
+ .setPromptingServer({
200
+ protocol: 'http',
201
+ port: 3000,
202
+ authentication: false,
203
+ maxConnections: 50
204
+ })
205
+ .setResources({
206
+ memory: '1g',
207
+ cpu: 2,
208
+ timeout: 60000
209
+ });
210
+ ```
211
+
212
+ ### Supported LLM Providers
213
+
214
+ #### OpenAI
215
+ ```javascript
216
+ .setLLM('openai', {
217
+ apiKey: 'your-api-key',
218
+ model: 'gpt-4',
219
+ temperature: 0.7,
220
+ maxTokens: 1000
221
+ })
222
+ ```
223
+
224
+ #### Anthropic
225
+ ```javascript
226
+ .setLLM('anthropic', {
227
+ apiKey: 'your-api-key',
228
+ model: 'claude-3-sonnet-20240229',
229
+ maxTokens: 1000
230
+ })
231
+ ```
232
+
233
+ #### Ollama (Local)
234
+ ```javascript
235
+ .setLLM('ollama', {
236
+ baseURL: 'http://localhost:11434',
237
+ model: 'llama2'
238
+ })
239
+ ```
240
+
241
+ #### Cohere
242
+ ```javascript
243
+ .setLLM('cohere', {
244
+ apiKey: 'your-api-key',
245
+ model: 'command',
246
+ temperature: 0.7
247
+ })
248
+ ```
249
+
250
+ #### Hugging Face
251
+ ```javascript
252
+ .setLLM('huggingface', {
253
+ apiKey: 'your-api-key',
254
+ model: 'microsoft/DialoGPT-medium'
255
+ })
256
+ ```
257
+
258
+ #### Custom Provider
259
+ ```javascript
260
+ .setLLM('custom', {
261
+ baseURL: 'https://api.your-provider.com',
262
+ apiKey: 'your-key',
263
+ model: 'your-model'
264
+ })
265
+ ```
37
266
 
38
- - `npm start` - Start all agents
39
- - `npm run dev` - Start in development mode
40
- - `npm run stop` - Stop all agents
41
- - `npm run status` - Check agent status
42
- - `npm run logs` - View agent logs
43
- - `npm run build` - Build agent images
44
- - `npm run clean` - Clean up containers and images
267
+ ### Event Handlers
45
268
 
46
- ## Event Handlers
269
+ Dank provides a comprehensive event system with three main sources of events. Each event handler follows specific naming patterns for maximum flexibility and control.
47
270
 
48
- This project includes examples of the three main event types:
271
+ > **🆕 Auto-Detection**: Dank automatically enables communication features based on your usage:
272
+ > - **Event Handlers**: Auto-enabled when you add `.addHandler()` calls
273
+ > - **Direct Prompting**: Auto-enabled when you use `.setPrompt()` + `.setLLM()`
274
+ > - **HTTP API**: Auto-enabled when you add routes with `.get()`, `.post()`, etc.
49
275
 
50
- ### 1. Direct Prompting Events (`request_output`)
51
- Handle LLM interactions and modify prompts/responses:
276
+ #### 🎯 **Event Handler Patterns**
277
+
278
+ ##### **1. Direct Prompting Events** (`request_output`)
279
+ Events triggered when agents receive and respond to direct prompts via WebSocket or HTTP:
52
280
 
53
281
  ```javascript
282
+ agent
283
+ // Main LLM response event
284
+ .addHandler('request_output', (data) => {
285
+ console.log('LLM Response:', {
286
+ prompt: data.prompt, // Original prompt
287
+ finalPrompt: data.finalPrompt, // Modified prompt (if changed)
288
+ response: data.response, // LLM response
289
+ conversationId: data.conversationId,
290
+ processingTime: data.processingTime,
291
+ promptModified: data.promptModified, // Boolean: was prompt modified?
292
+ usage: data.usage,
293
+ model: data.model
294
+ });
295
+ })
296
+
297
+ // Lifecycle events with modification capabilities
298
+ .addHandler('request_output:start', (data) => {
299
+ console.log('Processing prompt:', data.conversationId);
300
+ console.log('Original prompt:', data.prompt);
301
+
302
+ // ✨ MODIFY PROMPT: Return modified data to change the prompt sent to LLM
303
+ const enhancedPrompt = `Context: You are a helpful assistant. Please be concise and friendly.\n\nUser Question: ${data.prompt}`;
304
+
305
+ return {
306
+ prompt: enhancedPrompt // This will replace the original prompt
307
+ };
308
+ })
309
+
310
+ .addHandler('request_output:end', (data) => {
311
+ console.log('Completed in:', data.processingTime + 'ms');
312
+ console.log('Original response:', data.response.substring(0, 50) + '...');
313
+
314
+ // ✨ MODIFY RESPONSE: Return modified data to change the response sent to caller
315
+ const enhancedResponse = `${data.response}\n\n---\n💡 This response was generated by Dank Framework`;
316
+
317
+ return {
318
+ response: enhancedResponse // This will replace the original response
319
+ };
320
+ })
321
+
322
+ .addHandler('request_output:error', (data) => {
323
+ console.error('Prompt processing failed:', data.error);
324
+ });
325
+ ```
326
+
327
+ **🔄 Event Modification Capabilities:**
328
+
329
+ - **`request_output:start`**: Can modify the prompt before it's sent to the LLM by returning an object with a `prompt` property
330
+ - **`request_output:end`**: Can modify the response before it's sent back to the caller by returning an object with a `response` property
331
+ - **Event Data**: All events include both original and final values, plus modification flags for tracking changes
332
+
333
+ **⏱️ Event Flow Timeline:**
334
+
335
+ 1. **`request_output:start`** → Fires when prompt is received
336
+ - Can modify prompt before LLM processing
337
+ - Contains: `{ prompt, conversationId, context, timestamp }`
338
+
339
+ 2. **LLM Processing** → The (potentially modified) prompt is sent to the LLM
340
+
341
+ 3. **`request_output`** → Fires after LLM responds successfully
342
+ - Contains: `{ prompt, finalPrompt, response, conversationId, promptModified, ... }`
343
+
344
+ 4. **`request_output:end`** → Fires after `request_output`, before sending to caller
345
+ - Can modify response before returning to client
346
+ - Contains: `{ prompt, finalPrompt, response, conversationId, promptModified, success, ... }`
347
+
348
+ 5. **Response Sent** → The (potentially modified) response is sent back to the caller
349
+
350
+ **💡 Practical Examples:**
351
+
352
+ ```javascript
353
+ // Example 1: Add context and formatting to prompts
54
354
  .addHandler('request_output:start', (data) => {
55
- // Modify the prompt before sending to LLM
56
- return { prompt: `Enhanced: ${data.prompt}` };
355
+ // Add system context and format the user's question
356
+ const enhancedPrompt = `System: You are a helpful AI assistant. Be concise and professional.
357
+
358
+ User Question: ${data.prompt}
359
+
360
+ Please provide a clear, helpful response.`;
361
+
362
+ return { prompt: enhancedPrompt };
57
363
  })
58
364
 
365
+ // Example 2: Add metadata and branding to responses
59
366
  .addHandler('request_output:end', (data) => {
60
- // Modify the response before sending back
61
- return { response: `${data.response} [Enhanced by Dank]` };
367
+ // Add footer with metadata and branding
368
+ const brandedResponse = `${data.response}
369
+
370
+ ---
371
+ 🤖 Generated by Dank Framework Agent
372
+ ⏱️ Processing time: ${data.processingTime}ms
373
+ 🆔 Conversation: ${data.conversationId}`;
374
+
375
+ return { response: brandedResponse };
376
+ })
377
+
378
+ // Example 3: Log and analyze all interactions
379
+ .addHandler('request_output', (data) => {
380
+ // Log for analytics
381
+ console.log('Interaction logged:', {
382
+ originalPrompt: data.prompt,
383
+ modifiedPrompt: data.finalPrompt,
384
+ wasModified: data.promptModified,
385
+ responseLength: data.response.length,
386
+ model: data.model,
387
+ usage: data.usage
388
+ });
62
389
  })
63
390
  ```
64
391
 
65
- ### 2. HTTP API Events (`tool:http-server`)
66
- Handle HTTP requests and responses:
392
+ ##### **2. Tool Events** (`tool:*`)
393
+ Events triggered by tool usage, following the pattern `tool:<tool-name>:<action>:<specifics>`:
394
+
395
+ ```javascript
396
+ agent
397
+ // HTTP Server Tool Events
398
+ .addHandler('tool:http-server:*', (data) => {
399
+ // Listen to ALL HTTP server events
400
+ console.log('HTTP Activity:', data.type, data.method, data.path);
401
+ })
402
+
403
+ .addHandler('tool:http-server:call', (data) => {
404
+ // All incoming HTTP requests
405
+ console.log('Request:', data.method, data.path, data.body);
406
+ })
407
+
408
+ .addHandler('tool:http-server:response', (data) => {
409
+ // All HTTP responses
410
+ console.log('Response:', data.statusCode, data.processingTime);
411
+ })
412
+
413
+ .addHandler('tool:http-server:call:post', (data) => {
414
+ // Only POST requests
415
+ console.log('POST Request:', data.path, data.body);
416
+ })
417
+
418
+ .addHandler('tool:http-server:response:get', (data) => {
419
+ // Only GET responses
420
+ console.log('GET Response:', data.path, data.responseData);
421
+ })
422
+
423
+ .addHandler('tool:http-server:error', (data) => {
424
+ // HTTP server errors
425
+ console.error('HTTP Error:', data.error);
426
+ });
427
+ ```
428
+
429
+ **Tool Event Pattern Structure:**
430
+ - `tool:<tool-name>:*` - All events for a specific tool
431
+ - `tool:<tool-name>:call` - Tool invocation/input events
432
+ - `tool:<tool-name>:response` - Tool output/result events
433
+ - `tool:<tool-name>:call:<method>` - Specific method calls (e.g., POST, GET)
434
+ - `tool:<tool-name>:response:<method>` - Specific method responses
435
+ - `tool:<tool-name>:error` - Tool-specific errors
436
+
437
+ ##### **3. System Events** (Legacy/System)
438
+ Traditional system-level events:
67
439
 
68
440
  ```javascript
69
- .addHandler('tool:http-server:call', (data) => {
70
- console.log('HTTP request received:', data.method, data.path);
441
+ agent
442
+ .addHandler('output', (data) => {
443
+ console.log('General output:', data);
444
+ })
445
+
446
+ .addHandler('error', (error) => {
447
+ console.error('System error:', error);
448
+ })
449
+
450
+ .addHandler('heartbeat', () => {
451
+ console.log('Agent heartbeat');
452
+ })
453
+
454
+ .addHandler('start', () => {
455
+ console.log('Agent started');
456
+ })
457
+
458
+ .addHandler('stop', () => {
459
+ console.log('Agent stopped');
460
+ });
461
+ ```
462
+
463
+ #### 🔥 **Advanced Event Patterns**
464
+
465
+ **Wildcard Matching:**
466
+ ```javascript
467
+ // Listen to all tool events
468
+ .addHandler('tool:*', (data) => {
469
+ console.log('Any tool activity:', data);
470
+ })
471
+
472
+ // Listen to all HTTP responses
473
+ .addHandler('tool:http-server:response:*', (data) => {
474
+ console.log('Any HTTP response:', data);
71
475
  })
72
476
 
73
- .addHandler('tool:http-server:response', (data) => {
74
- console.log('HTTP response sent:', data.statusCode);
477
+ // Listen to all request outputs
478
+ .addHandler('request_output:*', (data) => {
479
+ console.log('Any request event:', data);
75
480
  })
76
481
  ```
77
482
 
78
- ### 3. System Events
79
- Handle agent lifecycle and errors:
483
+ **Multiple Handlers:**
484
+ ```javascript
485
+ // Multiple handlers for the same event
486
+ agent
487
+ .addHandler('request_output', (data) => {
488
+ // Log to console
489
+ console.log('Response:', data.response);
490
+ })
491
+ .addHandler('request_output', (data) => {
492
+ // Save to database
493
+ saveToDatabase(data);
494
+ })
495
+ .addHandler('request_output', (data) => {
496
+ // Send to analytics
497
+ trackAnalytics(data);
498
+ });
499
+ ```
500
+
501
+ #### 📊 **Event Data Structures**
502
+
503
+ **Request Output Event Data:**
504
+ ```javascript
505
+ {
506
+ prompt: "User's input prompt",
507
+ response: "LLM's response",
508
+ conversationId: "unique-conversation-id",
509
+ context: { protocol: "websocket", clientId: "..." },
510
+ usage: { total_tokens: 150, prompt_tokens: 50, completion_tokens: 100 },
511
+ model: "gpt-3.5-turbo",
512
+ processingTime: 1250,
513
+ timestamp: "2024-01-15T10:30:00.000Z"
514
+ }
515
+ ```
516
+
517
+ **Tool HTTP Event Data:**
518
+ ```javascript
519
+ {
520
+ requestId: "unique-request-id",
521
+ method: "POST",
522
+ path: "/api/chat",
523
+ headers: { "content-type": "application/json" },
524
+ body: { message: "Hello" },
525
+ query: {},
526
+ params: {},
527
+ statusCode: 200,
528
+ responseData: { response: "Hi there!" },
529
+ processingTime: 45,
530
+ timestamp: "2024-01-15T10:30:00.000Z"
531
+ }
532
+ ```
533
+
534
+ #### 🎛️ **Communication Method Control**
535
+
536
+ Each communication method can be enabled/disabled independently:
537
+
538
+ ```javascript
539
+ createAgent('flexible-agent')
540
+ // Configure direct prompting with specific settings
541
+ .setPromptingServer({
542
+ protocol: 'websocket',
543
+ port: 3000,
544
+ authentication: false,
545
+ maxConnections: 50
546
+ })
547
+ .disableDirectPrompting() // Disable if needed
548
+
549
+ // Enable HTTP API
550
+ .enableHttp({ port: 3001 })
551
+
552
+ // Listen to direct prompting events only
553
+ .addHandler('request_output', (data) => {
554
+ console.log('WebSocket response:', data.response);
555
+ })
556
+
557
+ // HTTP events will fire when routes are added
558
+ .get('/api/status', (req, res) => {
559
+ res.json({ status: 'ok' });
560
+ })
561
+ .addHandler('tool:http-server:*', (data) => {
562
+ console.log('HTTP activity:', data);
563
+ });
564
+ ```
565
+
566
+ ### Resource Management
567
+
568
+ Configure container resources:
80
569
 
81
570
  ```javascript
82
- .addHandler('output', (data) => {
83
- console.log('Agent output:', data);
571
+ .setResources({
572
+ memory: '512m', // Memory limit (512m, 1g, etc.)
573
+ cpu: 1, // CPU allocation (0.5, 1, 2, etc.)
574
+ timeout: 30000, // Request timeout in ms
575
+ maxRestarts: 3 // Max container restarts
84
576
  })
577
+ ```
85
578
 
86
- .addHandler('error', (error) => {
87
- console.error('Agent error:', error);
579
+ ### Agent Image Configuration
580
+
581
+ Configure Docker image naming and registry settings for agent builds:
582
+
583
+ ```javascript
584
+ // Complete agent image configuration
585
+ .setAgentImageConfig({
586
+ registry: 'ghcr.io', // Docker registry URL
587
+ namespace: 'mycompany', // Organization/namespace
588
+ tag: 'v1.0.0' // Image tag
88
589
  })
89
590
  ```
90
591
 
91
- ## Configuration
592
+ #### 🏗️ **Agent Image Build Workflow**
593
+
594
+ The agent image build feature allows you to create properly tagged Docker images for deployment to container registries. This is essential for:
595
+
596
+ - **CI/CD Pipelines**: Automated builds and deployments
597
+ - **Container Orchestration**: Kubernetes, Docker Swarm, etc.
598
+ - **Multi-Environment Deployments**: Dev, staging, production
599
+ - **Version Management**: Semantic versioning with tags
600
+
601
+ > **📝 Note**: Image pushing is controlled exclusively by the CLI `--push` option. Agent configuration only defines image naming (registry, namespace, tag) - not push behavior.
602
+
603
+ #### 📋 **Complete Agent Image Example**
604
+
605
+ ```javascript
606
+ const { createAgent } = require('dank');
607
+
608
+ module.exports = {
609
+ name: 'production-system',
610
+
611
+ agents: [
612
+ // Production-ready customer service agent
613
+ createAgent('customer-service')
614
+ .setLLM('openai', {
615
+ apiKey: process.env.OPENAI_API_KEY,
616
+ model: 'gpt-4',
617
+ temperature: 0.7
618
+ })
619
+ .setPrompt('You are a professional customer service representative.')
620
+ .setPromptingServer({
621
+ protocol: 'http',
622
+ port: 3000,
623
+ authentication: true,
624
+ maxConnections: 100
625
+ })
626
+ .setResources({
627
+ memory: '1g',
628
+ cpu: 2,
629
+ timeout: 60000
630
+ })
631
+ // Agent image configuration
632
+ .setAgentImageConfig({
633
+ registry: 'ghcr.io',
634
+ namespace: 'mycompany',
635
+ tag: 'v1.2.0'
636
+ })
637
+ .addHandler('request_output', (data) => {
638
+ // Log for production monitoring
639
+ console.log(`[${new Date().toISOString()}] Customer Service: ${data.response.substring(0, 100)}...`);
640
+ }),
641
+
642
+ // Data processing agent with different registry
643
+ createAgent('data-processor')
644
+ .setLLM('openai', {
645
+ apiKey: process.env.OPENAI_API_KEY,
646
+ model: 'gpt-4',
647
+ temperature: 0.1
648
+ })
649
+ .setPrompt('You are a data analysis expert.')
650
+ .setPromptingServer({
651
+ protocol: 'http',
652
+ port: 3001,
653
+ authentication: false,
654
+ maxConnections: 50
655
+ })
656
+ .setResources({
657
+ memory: '2g',
658
+ cpu: 4,
659
+ timeout: 120000
660
+ })
661
+ // Different agent image configuration
662
+ .setAgentImageConfig({
663
+ registry: 'docker.io',
664
+ namespace: 'mycompany',
665
+ tag: 'latest'
666
+ })
667
+ .addHandler('request_output', (data) => {
668
+ console.log(`[Data Processor] Analysis completed: ${data.processingTime}ms`);
669
+ })
670
+ ]
671
+ };
672
+ ```
673
+
674
+ #### 🚀 **Production Build Commands**
675
+
676
+ **Basic Production Build:**
677
+ ```bash
678
+ # Build all agents with their image configuration
679
+ dank build:prod
680
+
681
+ # Build with custom configuration file
682
+ dank build:prod --config production.config.js
683
+ ```
684
+
685
+ **Registry and Tagging:**
686
+ ```bash
687
+ # Build with custom tag
688
+ dank build:prod --tag v2.1.0
689
+
690
+ # Build for GitHub Container Registry
691
+ dank build:prod --registry ghcr.io --namespace myorg
692
+
693
+ # Build for Docker Hub
694
+ dank build:prod --registry docker.io --namespace mycompany
695
+
696
+ # Build for private registry
697
+ dank build:prod --registry registry.company.com --namespace ai-agents
698
+ ```
699
+
700
+ **Push and Force Rebuild:**
701
+ ```bash
702
+ # Build and push to registry
703
+ dank build:prod --push
704
+
705
+ # Force rebuild without cache
706
+ dank build:prod --force
707
+
708
+ # Force rebuild and push
709
+ dank build:prod --force --push
710
+
711
+ # Build with custom tag and push
712
+ dank build:prod --tag release-2024.1 --push
713
+ ```
714
+
715
+ #### 🏷️ **Image Naming Convention**
716
+
717
+ **With Agent Configuration:**
718
+ - Format: `{registry}/{namespace}/{agent-name}:{tag}`
719
+ - Example: `ghcr.io/mycompany/customer-service:v1.2.0`
720
+
721
+ **With CLI Override:**
722
+ - CLI options override agent configuration
723
+ - Example: `dank build:prod --tag v2.0.0` overrides agent's tag
724
+
725
+ **Without Configuration:**
726
+ - Format: `{agent-name}:{tag}`
727
+ - Example: `customer-service:latest`
728
+
729
+ #### 🔧 **Registry Authentication**
730
+
731
+ **Docker Hub:**
732
+ ```bash
733
+ # Login to Docker Hub
734
+ docker login
735
+
736
+ # Build and push
737
+ dank build:prod --registry docker.io --namespace myusername --push
738
+ ```
739
+
740
+ **GitHub Container Registry:**
741
+ ```bash
742
+ # Login to GHCR
743
+ echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
744
+
745
+ # Build and push
746
+ dank build:prod --registry ghcr.io --namespace myorg --push
747
+ ```
748
+
749
+ **Private Registry:**
750
+ ```bash
751
+ # Login to private registry
752
+ docker login registry.company.com
753
+
754
+ # Build and push
755
+ dank build:prod --registry registry.company.com --namespace ai-agents --push
756
+ ```
757
+
758
+ #### 📊 **Build Output Example**
759
+
760
+ ```bash
761
+ $ dank build:prod --push
762
+
763
+ 🏗️ Building production Docker images...
764
+
765
+ 📦 Building production image for agent: customer-service
766
+ info: Building production image for agent: customer-service -> ghcr.io/mycompany/customer-service:v1.2.0
767
+ Step 1/3 : FROM deltadarkly/dank-agent-base:latest
768
+ ---> 7b560f235fe3
769
+ Step 2/3 : COPY agent-code/ /app/agent-code/
770
+ ---> d766de6e95c4
771
+ Step 3/3 : USER dankuser
772
+ ---> Running in c773e808270c
773
+ Successfully built 43a664c636a2
774
+ Successfully tagged ghcr.io/mycompany/customer-service:v1.2.0
775
+ info: Production image 'ghcr.io/mycompany/customer-service:v1.2.0' built successfully
776
+ info: Pushing image to registry: ghcr.io/mycompany/customer-service:v1.2.0
777
+ info: Successfully pushed image: ghcr.io/mycompany/customer-service:v1.2.0
778
+ ✅ Successfully built: ghcr.io/mycompany/customer-service:v1.2.0
779
+ 🚀 Successfully pushed: ghcr.io/mycompany/customer-service:v1.2.0
780
+
781
+ 📊 Build Summary:
782
+ ================
783
+ ✅ Successful builds: 2
784
+ 🚀 Pushed to registry: 2
785
+
786
+ 📦 Built Images:
787
+ - ghcr.io/mycompany/customer-service:v1.2.0
788
+ - docker.io/mycompany/data-processor:latest
789
+
790
+ 🎉 Production build completed successfully!
791
+ ```
792
+
793
+ #### 🔄 **CI/CD Integration**
794
+
795
+ **GitHub Actions Example:**
796
+ ```yaml
797
+ name: Build and Push Production Images
798
+
799
+ on:
800
+ push:
801
+ tags:
802
+ - 'v*'
803
+
804
+ jobs:
805
+ build:
806
+ runs-on: ubuntu-latest
807
+ steps:
808
+ - uses: actions/checkout@v3
809
+
810
+ - name: Setup Node.js
811
+ uses: actions/setup-node@v3
812
+ with:
813
+ node-version: '18'
814
+
815
+ - name: Install Dank
816
+ run: npm install -g dank-ai
817
+
818
+ - name: Login to GHCR
819
+ uses: docker/login-action@v2
820
+ with:
821
+ registry: ghcr.io
822
+ username: ${{ github.actor }}
823
+ password: ${{ secrets.GITHUB_TOKEN }}
824
+
825
+ - name: Build and Push Production Images
826
+ run: |
827
+ dank build:prod \
828
+ --registry ghcr.io \
829
+ --namespace ${{ github.repository_owner }} \
830
+ --tag ${{ github.ref_name }} \
831
+ --push
832
+ ```
833
+
834
+ **GitLab CI Example:**
835
+ ```yaml
836
+ build_production:
837
+ stage: build
838
+ image: node:18
839
+ before_script:
840
+ - npm install -g dank-ai
841
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
842
+ script:
843
+ - dank build:prod --registry $CI_REGISTRY --namespace $CI_PROJECT_NAMESPACE --tag $CI_COMMIT_TAG --push
844
+ only:
845
+ - tags
846
+ ```
847
+
848
+ #### 🐳 **Docker Compose Integration**
849
+
850
+ Use your production images in Docker Compose:
851
+
852
+ ```yaml
853
+ version: '3.8'
854
+
855
+ services:
856
+ customer-service:
857
+ image: ghcr.io/mycompany/customer-service:v1.2.0
858
+ ports:
859
+ - "3000:3000"
860
+ environment:
861
+ - OPENAI_API_KEY=${OPENAI_API_KEY}
862
+ restart: unless-stopped
863
+
864
+ data-processor:
865
+ image: docker.io/mycompany/data-processor:latest
866
+ ports:
867
+ - "3001:3001"
868
+ environment:
869
+ - OPENAI_API_KEY=${OPENAI_API_KEY}
870
+ restart: unless-stopped
871
+ ```
872
+
873
+ #### 🚨 **Troubleshooting Production Builds**
874
+
875
+ **Common Issues:**
876
+
877
+ 1. **Registry Authentication:**
878
+ ```bash
879
+ # Error: authentication required
880
+ # Solution: Login to registry first
881
+ docker login ghcr.io
882
+ ```
883
+
884
+ 2. **Push Permissions:**
885
+ ```bash
886
+ # Error: denied: push access denied
887
+ # Solution: Check namespace permissions or use personal namespace
888
+ dank build:prod --namespace your-username --push
889
+ ```
890
+
891
+ 3. **Image Already Exists:**
892
+ ```bash
893
+ # Error: image already exists
894
+ # Solution: Use different tag or force rebuild
895
+ dank build:prod --tag v1.2.1 --push
896
+ ```
897
+
898
+ 4. **Build Context Issues:**
899
+ ```bash
900
+ # Error: build context too large
901
+ # Solution: Add .dockerignore file
902
+ echo "node_modules/" > .dockerignore
903
+ echo "*.log" >> .dockerignore
904
+ ```
905
+
906
+ ## 🏗️ Project Structure
907
+
908
+ ```
909
+ my-project/
910
+ ├── dank.config.js # Agent configuration
911
+ ├── agents/ # Custom agent code (optional)
912
+ │ └── example-agent.js
913
+ └── .dank/ # Generated files
914
+ ├── project.yaml # Project state
915
+ └── logs/ # Agent logs
916
+ ```
917
+
918
+ ## 📦 Package Exports
919
+
920
+ When you install Dank via npm, you can import the following:
921
+
922
+ ```javascript
923
+ const {
924
+ createAgent, // Convenience function to create agents
925
+ DankAgent, // Main agent class
926
+ DankProject, // Project management class
927
+ SUPPORTED_LLMS, // List of supported LLM providers
928
+ DEFAULT_CONFIG // Default configuration values
929
+ } = require("dank");
930
+ ```
931
+
932
+ ## 📋 Example Files
933
+
934
+ The `examples/` directory contains two configuration files:
935
+
936
+ - **`dank.config.js`** - Local development example (uses `../lib/index.js`)
937
+ - **`dank.config.template.js`** - Production template (uses `require("dank")`)
938
+
939
+ ### For Local Development
940
+ ```bash
941
+ # Use the example file directly
942
+ dank run --config example/dank.config.js
943
+ ```
944
+
945
+ ### For Production Use
946
+ ```bash
947
+ # 1. Copy the template to your project
948
+ cp example/dank.config.template.js ./dank.config.js
949
+
950
+ # 2. Install dank as a dependency
951
+ npm install dank-ai
952
+
953
+ # 3. The template already uses the correct import
954
+ # const { createAgent } = require("dank");
955
+
956
+ # 4. Run your agents
957
+ dank run
958
+ ```
959
+
960
+ ## 🐳 Docker Architecture
961
+
962
+ Dank uses a layered Docker approach:
963
+
964
+ 1. **Base Image** (`deltadarkly/dank-agent-base`): Common runtime with Node.js, LLM clients
965
+ 2. **Agent Images**: Extend base image with agent-specific code and custom tags
966
+ 3. **Containers**: Running instances with resource limits and networking
967
+
968
+ ### Container Features
969
+ - **Isolated Environments**: Each agent runs in its own container
970
+ - **Resource Limits**: Memory and CPU constraints per agent
971
+ - **Health Monitoring**: Built-in health checks and status reporting
972
+ - **Automatic Restarts**: Container restart policies for reliability
973
+ - **Logging**: Centralized log collection and viewing
974
+
975
+ ### 🚀 Automatic Docker Management
976
+
977
+ Dank automatically handles Docker installation and startup for you:
978
+
979
+ #### **Auto-Detection & Installation**
980
+ When you run any Dank command, it will:
981
+ 1. **Check if Docker is installed** - Runs `docker --version` to detect installation
982
+ 2. **Install Docker if missing** - Automatically installs Docker for your platform:
983
+ - **macOS**: Uses Homebrew to install Docker Desktop
984
+ - **Linux**: Installs Docker CE via apt package manager
985
+ - **Windows**: Uses Chocolatey to install Docker Desktop
986
+ 3. **Start Docker if stopped** - Automatically starts Docker service
987
+ 4. **Wait for availability** - Ensures Docker is ready before proceeding
988
+
989
+ #### **Platform-Specific Installation**
990
+
991
+ **macOS:**
992
+ ```bash
993
+ # Dank will automatically run:
994
+ brew install --cask docker
995
+ open -a Docker
996
+ ```
997
+
998
+ **Linux (Ubuntu/Debian):**
999
+ ```bash
1000
+ # Dank will automatically run:
1001
+ sudo apt-get update
1002
+ sudo apt-get install -y docker-ce docker-ce-cli containerd.io
1003
+ sudo systemctl start docker
1004
+ sudo systemctl enable docker
1005
+ sudo usermod -aG docker $USER
1006
+ ```
1007
+
1008
+ **Windows:**
1009
+ ```bash
1010
+ # Dank will automatically run:
1011
+ choco install docker-desktop -y
1012
+ start "" "C:\Program Files\Docker\Docker\Docker Desktop.exe"
1013
+ ```
1014
+
1015
+ #### **Manual Fallback**
1016
+ If automatic installation fails, Dank will provide clear instructions:
1017
+ ```bash
1018
+ # Example output when manual installation is needed
1019
+ ❌ Docker installation failed: Homebrew not found
1020
+ 💡 Please install Docker Desktop manually from:
1021
+ https://www.docker.com/products/docker-desktop/
1022
+ ```
1023
+
1024
+ #### **Status Messages**
1025
+ Dank provides clear feedback during the process:
1026
+ ```bash
1027
+ 🔍 Checking Docker availability...
1028
+ 📦 Docker is not installed. Installing Docker...
1029
+ 🖥️ Installing Docker Desktop for macOS...
1030
+ ⏳ Installing Docker Desktop via Homebrew...
1031
+ ✅ Docker installation completed
1032
+ 🚀 Starting Docker Desktop...
1033
+ ⏳ Waiting for Docker to become available...
1034
+ ✅ Docker is now available
1035
+ 🐳 Docker connection established
1036
+ ```
1037
+
1038
+ ## 💼 Using Dank in Your Project
1039
+
1040
+ ### Step-by-Step Integration Guide
1041
+
1042
+ #### 1. Project Setup
1043
+ ```bash
1044
+ # In your existing project directory
1045
+ npm install -g dank-ai
1046
+
1047
+ # Initialize Dank configuration
1048
+ dank init
1049
+
1050
+ # This creates dank.config.js in your current directory
1051
+ ```
1052
+
1053
+ #### 2. Basic Agent Configuration
1054
+ Start with a simple agent configuration in `dank.config.js`:
1055
+
1056
+ ```javascript
1057
+ const { createAgent } = require('dank');
1058
+
1059
+ module.exports = {
1060
+ name: 'my-project',
1061
+
1062
+ agents: [
1063
+ // Simple assistant agent
1064
+ createAgent('helper')
1065
+ .setLLM('openai', {
1066
+ apiKey: process.env.OPENAI_API_KEY,
1067
+ model: 'gpt-3.5-turbo'
1068
+ })
1069
+ .setPrompt('You are a helpful assistant.')
1070
+ .addHandler('output', console.log)
1071
+ ]
1072
+ };
1073
+ ```
1074
+
1075
+ #### 3. Multi-Agent Setup
1076
+ Configure multiple specialized agents:
1077
+
1078
+ ```javascript
1079
+ const { createAgent } = require('dank');
1080
+
1081
+ module.exports = {
1082
+ name: 'multi-agent-system',
1083
+
1084
+ agents: [
1085
+ // Customer service agent
1086
+ createAgent('customer-service')
1087
+ .setLLM('openai', {
1088
+ apiKey: process.env.OPENAI_API_KEY,
1089
+ model: 'gpt-3.5-turbo',
1090
+ temperature: 0.7
1091
+ })
1092
+ .setPrompt(`
1093
+ You are a friendly customer service representative.
1094
+ - Be helpful and professional
1095
+ - Resolve customer issues quickly
1096
+ - Escalate complex problems appropriately
1097
+ `)
1098
+ .setResources({ memory: '512m', cpu: 1 })
1099
+ .addHandler('output', (data) => {
1100
+ console.log('[Customer Service]:', data);
1101
+ // Add your business logic here
1102
+ }),
1103
+
1104
+ // Data analyst agent
1105
+ createAgent('analyst')
1106
+ .setLLM('openai', {
1107
+ apiKey: process.env.OPENAI_API_KEY,
1108
+ model: 'gpt-4',
1109
+ temperature: 0.3
1110
+ })
1111
+ .setPrompt(`
1112
+ You are a data analyst expert.
1113
+ - Analyze trends and patterns
1114
+ - Provide statistical insights
1115
+ - Create actionable recommendations
1116
+ `)
1117
+ .setResources({ memory: '1g', cpu: 2 })
1118
+ .addHandler('output', (data) => {
1119
+ console.log('[Analyst]:', data);
1120
+ // Save analysis results to database
1121
+ }),
1122
+
1123
+ // Content creator agent
1124
+ createAgent('content-creator')
1125
+ .setLLM('anthropic', {
1126
+ apiKey: process.env.ANTHROPIC_API_KEY,
1127
+ model: 'claude-3-sonnet-20240229'
1128
+ })
1129
+ .setPrompt(`
1130
+ You are a creative content writer.
1131
+ - Write engaging, original content
1132
+ - Adapt tone to target audience
1133
+ - Follow brand guidelines
1134
+ `)
1135
+ .setResources({ memory: '512m', cpu: 1 })
1136
+ .addHandler('output', (data) => {
1137
+ console.log('[Content Creator]:', data);
1138
+ // Process and publish content
1139
+ })
1140
+ ]
1141
+ };
1142
+ ```
1143
+
1144
+ ### 🎯 Common Use Cases
1145
+
1146
+ #### Use Case 1: Customer Support Automation
1147
+ ```javascript
1148
+ createAgent('support-bot')
1149
+ .setLLM('openai', {
1150
+ apiKey: process.env.OPENAI_API_KEY,
1151
+ model: 'gpt-3.5-turbo'
1152
+ })
1153
+ .setPrompt(`
1154
+ You are a customer support specialist for [Your Company].
1155
+
1156
+ Guidelines:
1157
+ - Always be polite and helpful
1158
+ - For technical issues, provide step-by-step solutions
1159
+ - If you cannot resolve an issue, escalate to human support
1160
+ - Use the customer's name when available
1161
+
1162
+ Knowledge Base:
1163
+ - Product features: [list your features]
1164
+ - Common issues: [list common problems and solutions]
1165
+ - Contact info: support@yourcompany.com
1166
+ `)
1167
+ .addHandler('output', (response) => {
1168
+ // Send response back to customer via your chat system
1169
+ sendToCustomer(response);
1170
+ })
1171
+ .addHandler('error', (error) => {
1172
+ // Fallback to human support
1173
+ escalateToHuman(error);
1174
+ });
1175
+ ```
1176
+
1177
+ #### Use Case 2: Content Generation Pipeline
1178
+ ```javascript
1179
+ const contentAgents = [
1180
+ // Research agent
1181
+ createAgent('researcher')
1182
+ .setLLM('openai', { model: 'gpt-4' })
1183
+ .setPrompt('Research and gather information on given topics')
1184
+ .addHandler('output', (research) => {
1185
+ // Pass research to writer agent
1186
+ triggerContentCreation(research);
1187
+ }),
1188
+
1189
+ // Writer agent
1190
+ createAgent('writer')
1191
+ .setLLM('anthropic', { model: 'claude-3-sonnet' })
1192
+ .setPrompt('Write engaging blog posts based on research data')
1193
+ .addHandler('output', (article) => {
1194
+ // Save draft and notify editor
1195
+ saveDraft(article);
1196
+ notifyEditor(article);
1197
+ }),
1198
+
1199
+ // SEO optimizer agent
1200
+ createAgent('seo-optimizer')
1201
+ .setLLM('openai', { model: 'gpt-3.5-turbo' })
1202
+ .setPrompt('Optimize content for SEO and readability')
1203
+ .addHandler('output', (optimizedContent) => {
1204
+ // Publish optimized content
1205
+ publishContent(optimizedContent);
1206
+ })
1207
+ ];
1208
+ ```
1209
+
1210
+ #### Use Case 3: Data Analysis Workflow
1211
+ ```javascript
1212
+ createAgent('data-processor')
1213
+ .setLLM('openai', {
1214
+ apiKey: process.env.OPENAI_API_KEY,
1215
+ model: 'gpt-4',
1216
+ temperature: 0.1 // Low temperature for consistent analysis
1217
+ })
1218
+ .setPrompt(`
1219
+ You are a data analyst. Analyze the provided data and:
1220
+ 1. Identify key trends and patterns
1221
+ 2. Calculate important metrics
1222
+ 3. Provide actionable insights
1223
+ 4. Format results as JSON
1224
+ `)
1225
+ .setResources({
1226
+ memory: '2g', // More memory for data processing
1227
+ cpu: 2, // More CPU for complex calculations
1228
+ timeout: 120000 // Longer timeout for large datasets
1229
+ })
1230
+ .addHandler('output', (analysis) => {
1231
+ try {
1232
+ const results = JSON.parse(analysis);
1233
+ // Store results in database
1234
+ saveAnalysisResults(results);
1235
+ // Generate reports
1236
+ generateReport(results);
1237
+ // Send alerts if thresholds are met
1238
+ checkAlerts(results);
1239
+ } catch (error) {
1240
+ console.error('Failed to parse analysis:', error);
1241
+ }
1242
+ });
1243
+ ```
1244
+
1245
+ ### 🔧 Advanced Configuration
1246
+
1247
+ #### Custom Agent Code
1248
+ For complex logic, create custom agent files in the `agents/` directory:
1249
+
1250
+ ```javascript
1251
+ // agents/custom-agent.js
1252
+ module.exports = {
1253
+ async main(llmClient, handlers) {
1254
+ console.log('Custom agent starting...');
1255
+
1256
+ // Your custom agent logic
1257
+ setInterval(async () => {
1258
+ try {
1259
+ // Make LLM request
1260
+ const response = await llmClient.chat.completions.create({
1261
+ model: 'gpt-3.5-turbo',
1262
+ messages: [
1263
+ { role: 'system', content: 'You are a helpful assistant' },
1264
+ { role: 'user', content: 'Generate a daily report' }
1265
+ ]
1266
+ });
1267
+
1268
+ // Trigger output handlers
1269
+ const outputHandlers = handlers.get('output') || [];
1270
+ outputHandlers.forEach(handler =>
1271
+ handler(response.choices[0].message.content)
1272
+ );
1273
+
1274
+ } catch (error) {
1275
+ // Trigger error handlers
1276
+ const errorHandlers = handlers.get('error') || [];
1277
+ errorHandlers.forEach(handler => handler(error));
1278
+ }
1279
+ }, 60000); // Run every minute
1280
+ },
1281
+
1282
+ // Define custom handlers
1283
+ handlers: {
1284
+ output: [
1285
+ (data) => console.log('Custom output:', data)
1286
+ ],
1287
+ error: [
1288
+ (error) => console.error('Custom error:', error)
1289
+ ]
1290
+ }
1291
+ };
1292
+ ```
1293
+
1294
+ #### Environment-Specific Configuration
1295
+ ```javascript
1296
+ // dank.config.js
1297
+ const { createAgent } = require('dank');
1298
+
1299
+ const isDevelopment = process.env.NODE_ENV === 'development';
1300
+ const isProduction = process.env.NODE_ENV === 'production';
1301
+
1302
+ module.exports = {
1303
+ name: 'my-project',
1304
+
1305
+ agents: [
1306
+ createAgent('main-agent')
1307
+ .setLLM('openai', {
1308
+ apiKey: process.env.OPENAI_API_KEY,
1309
+ model: isDevelopment ? 'gpt-3.5-turbo' : 'gpt-4',
1310
+ temperature: isDevelopment ? 0.9 : 0.7
1311
+ })
1312
+ .setResources({
1313
+ memory: isDevelopment ? '256m' : '1g',
1314
+ cpu: isDevelopment ? 0.5 : 2
1315
+ })
1316
+ .addHandler('output', (data) => {
1317
+ if (isDevelopment) {
1318
+ console.log('DEV:', data);
1319
+ } else {
1320
+ // Production logging
1321
+ logger.info('Agent output', { data });
1322
+ }
1323
+ })
1324
+ ]
1325
+ };
1326
+ ```
1327
+
1328
+ ### 🔧 Advanced Usage
1329
+
1330
+ #### Environment Variables
1331
+ ```bash
1332
+ export OPENAI_API_KEY="your-key"
1333
+ export ANTHROPIC_API_KEY="your-key"
1334
+ export LOG_LEVEL="debug"
1335
+ export DOCKER_HOST="unix:///var/run/docker.sock"
1336
+ export NODE_ENV="production"
1337
+ ```
1338
+
1339
+ #### Integration with Existing Applications
1340
+ ```javascript
1341
+ // In your existing Node.js application
1342
+ const { spawn } = require('child_process');
1343
+
1344
+ // Start Dank agents programmatically
1345
+ function startAgents() {
1346
+ const dankProcess = spawn('dank', ['run', '--detached'], {
1347
+ stdio: 'inherit',
1348
+ env: { ...process.env, NODE_ENV: 'production' }
1349
+ });
1350
+
1351
+ dankProcess.on('close', (code) => {
1352
+ console.log(`Dank agents exited with code ${code}`);
1353
+ });
1354
+
1355
+ return dankProcess;
1356
+ }
1357
+
1358
+ // Stop agents gracefully
1359
+ function stopAgents() {
1360
+ spawn('dank', ['stop', '--all'], { stdio: 'inherit' });
1361
+ }
1362
+
1363
+ // Check agent status
1364
+ async function getAgentStatus() {
1365
+ return new Promise((resolve) => {
1366
+ const statusProcess = spawn('dank', ['status', '--json'], {
1367
+ stdio: ['pipe', 'pipe', 'pipe']
1368
+ });
1369
+
1370
+ let output = '';
1371
+ statusProcess.stdout.on('data', (data) => {
1372
+ output += data.toString();
1373
+ });
1374
+
1375
+ statusProcess.on('close', () => {
1376
+ try {
1377
+ resolve(JSON.parse(output));
1378
+ } catch {
1379
+ resolve(null);
1380
+ }
1381
+ });
1382
+ });
1383
+ }
1384
+ ```
1385
+
1386
+ ### 🚨 Troubleshooting
1387
+
1388
+ #### Common Issues and Solutions
1389
+
1390
+ **1. Docker Connection Issues**
1391
+ ```bash
1392
+ # Error: Cannot connect to Docker daemon
1393
+ # Solution: Dank will automatically handle this!
1394
+
1395
+ # If automatic installation fails, manual steps:
1396
+ docker --version
1397
+ docker ps
1398
+
1399
+ # On macOS/Windows: Start Docker Desktop manually
1400
+ # On Linux: Start Docker service
1401
+ sudo systemctl start docker
1402
+ ```
1403
+
1404
+ **1a. Docker Installation Issues**
1405
+ ```bash
1406
+ # If automatic installation fails, try manual installation:
1407
+
1408
+ # macOS (with Homebrew):
1409
+ brew install --cask docker
1410
+ open -a Docker
1411
+
1412
+ # Linux (Ubuntu/Debian):
1413
+ sudo apt-get update
1414
+ sudo apt-get install -y docker-ce docker-ce-cli containerd.io
1415
+ sudo systemctl start docker
1416
+ sudo usermod -aG docker $USER
1417
+
1418
+ # Windows (with Chocolatey):
1419
+ choco install docker-desktop -y
1420
+ # Then start Docker Desktop from Start Menu
1421
+ ```
1422
+
1423
+ **2. API Key Issues**
1424
+ ```bash
1425
+ # Error: Invalid API key
1426
+ # Solution: Check your environment variables
1427
+ echo $OPENAI_API_KEY
1428
+
1429
+ # Set the key properly
1430
+ export OPENAI_API_KEY="sk-your-actual-key-here"
1431
+
1432
+ # Or create a .env file in your project
1433
+ echo "OPENAI_API_KEY=sk-your-actual-key-here" > .env
1434
+ ```
1435
+
1436
+ **3. Base Image Not Found**
1437
+ ```bash
1438
+ # Error: Base image 'deltadarkly/dank-agent-base' not found
1439
+ # Solution: The base image is pulled automatically, but you can build it manually
1440
+ dank build --base
1441
+ ```
1442
+
1443
+ **4. Container Resource Issues**
1444
+ ```bash
1445
+ # Error: Container exits with code 137 (out of memory)
1446
+ # Solution: Increase memory allocation
1447
+ createAgent('my-agent')
1448
+ .setResources({
1449
+ memory: '1g', // Increase from 512m to 1g
1450
+ cpu: 2
1451
+ })
1452
+ ```
1453
+
1454
+ **5. Agent Not Starting**
1455
+ ```bash
1456
+ # Check agent logs for detailed error information
1457
+ dank logs agent-name
1458
+
1459
+ # Check container status
1460
+ docker ps -f name=dank-
1461
+
1462
+ # View Docker logs directly
1463
+ docker logs container-id
1464
+ ```
1465
+
1466
+ ### 💡 Best Practices
1467
+
1468
+ #### 1. Resource Management
1469
+ ```javascript
1470
+ // Good: Appropriate resource allocation
1471
+ createAgent('light-agent')
1472
+ .setResources({
1473
+ memory: '256m', // Light tasks
1474
+ cpu: 0.5
1475
+ });
1476
+
1477
+ createAgent('heavy-agent')
1478
+ .setResources({
1479
+ memory: '2g', // Heavy processing
1480
+ cpu: 2,
1481
+ timeout: 120000 // Longer timeout
1482
+ });
1483
+ ```
1484
+
1485
+ #### 2. Error Handling
1486
+ ```javascript
1487
+ // Good: Comprehensive error handling
1488
+ createAgent('robust-agent')
1489
+ .addHandler('error', (error) => {
1490
+ console.error('Agent error:', error.message);
1491
+
1492
+ // Log to monitoring system
1493
+ logError(error);
1494
+
1495
+ // Send alert if critical
1496
+ if (error.type === 'CRITICAL') {
1497
+ sendAlert(error);
1498
+ }
1499
+
1500
+ // Implement retry logic
1501
+ scheduleRetry(error.context);
1502
+ })
1503
+ .addHandler('output', (data) => {
1504
+ try {
1505
+ processOutput(data);
1506
+ } catch (error) {
1507
+ console.error('Output processing failed:', error);
1508
+ }
1509
+ });
1510
+ ```
1511
+
1512
+ #### 3. Environment Configuration
1513
+ ```javascript
1514
+ // Good: Environment-specific settings
1515
+ const config = {
1516
+ development: {
1517
+ model: 'gpt-3.5-turbo',
1518
+ memory: '256m',
1519
+ logLevel: 'debug'
1520
+ },
1521
+ production: {
1522
+ model: 'gpt-4',
1523
+ memory: '1g',
1524
+ logLevel: 'info'
1525
+ }
1526
+ };
1527
+
1528
+ const env = process.env.NODE_ENV || 'development';
1529
+ const settings = config[env];
1530
+
1531
+ createAgent('environment-aware')
1532
+ .setLLM('openai', {
1533
+ model: settings.model,
1534
+ temperature: 0.7
1535
+ })
1536
+ .setResources({
1537
+ memory: settings.memory
1538
+ });
1539
+ ```
1540
+
1541
+ #### 4. Monitoring and Logging
1542
+ ```javascript
1543
+ // Good: Structured logging
1544
+ createAgent('monitored-agent')
1545
+ .addHandler('output', (data) => {
1546
+ logger.info('Agent output', {
1547
+ agent: 'monitored-agent',
1548
+ timestamp: new Date().toISOString(),
1549
+ data: data.substring(0, 100) // Truncate for logs
1550
+ });
1551
+ })
1552
+ .addHandler('error', (error) => {
1553
+ logger.error('Agent error', {
1554
+ agent: 'monitored-agent',
1555
+ error: error.message,
1556
+ stack: error.stack
1557
+ });
1558
+ })
1559
+ .addHandler('start', () => {
1560
+ logger.info('Agent started', { agent: 'monitored-agent' });
1561
+ });
1562
+ ```
1563
+
1564
+ #### 5. Security Considerations
1565
+ ```javascript
1566
+ // Good: Secure configuration
1567
+ createAgent('secure-agent')
1568
+ .setLLM('openai', {
1569
+ apiKey: process.env.OPENAI_API_KEY, // Never hardcode keys
1570
+ model: 'gpt-3.5-turbo'
1571
+ })
1572
+ .setPrompt(`
1573
+ You are a helpful assistant.
1574
+
1575
+ IMPORTANT SECURITY RULES:
1576
+ - Never reveal API keys or sensitive information
1577
+ - Don't execute system commands
1578
+ - Validate all inputs before processing
1579
+ - Don't access external URLs unless explicitly allowed
1580
+ `)
1581
+ .addHandler('output', (data) => {
1582
+ // Sanitize output before logging
1583
+ const sanitized = sanitizeOutput(data);
1584
+ console.log(sanitized);
1585
+ });
1586
+ ```
1587
+
1588
+ ### 📊 Performance Optimization
1589
+
1590
+ #### 1. Resource Tuning
1591
+ ```bash
1592
+ # Monitor resource usage
1593
+ dank status --watch
1594
+
1595
+ # Check container stats
1596
+ docker stats $(docker ps -f name=dank- -q)
1597
+
1598
+ # Optimize based on usage patterns
1599
+ ```
1600
+
1601
+ #### 2. Parallel Agent Management
1602
+ ```javascript
1603
+ // Good: Balanced agent distribution
1604
+ module.exports = {
1605
+ agents: [
1606
+ // CPU-intensive agents
1607
+ createAgent('analyzer').setResources({ cpu: 2, memory: '1g' }),
1608
+
1609
+ // Memory-intensive agents
1610
+ createAgent('processor').setResources({ cpu: 1, memory: '2g' }),
1611
+
1612
+ // Light agents
1613
+ createAgent('notifier').setResources({ cpu: 0.5, memory: '256m' })
1614
+ ]
1615
+ };
1616
+ ```
1617
+
1618
+ #### 3. Efficient Prompt Design
1619
+ ```javascript
1620
+ // Good: Clear, specific prompts
1621
+ .setPrompt(`
1622
+ You are a customer service agent. Follow these steps:
1623
+
1624
+ 1. Greet the customer politely
1625
+ 2. Understand their issue by asking clarifying questions
1626
+ 3. Provide a solution or escalate if needed
1627
+ 4. Confirm resolution
1628
+
1629
+ Response format: JSON with fields: greeting, questions, solution, status
1630
+ `);
1631
+ ```
1632
+
1633
+ ### 🔄 Development Workflow
1634
+
1635
+ #### 1. Local Development
1636
+ ```bash
1637
+ # 1. Start with development configuration
1638
+ NODE_ENV=development dank run
1639
+
1640
+ # 2. Make changes to dank.config.js
1641
+
1642
+ # 3. Restart agents to apply changes
1643
+ dank stop --all
1644
+ dank run --build # Rebuild if needed
1645
+
1646
+ # 4. Test with reduced resources
1647
+ createAgent('dev-agent').setResources({ memory: '128m', cpu: 0.25 })
1648
+ ```
1649
+
1650
+ #### 2. Testing Agents
1651
+ ```bash
1652
+ # Test individual agents
1653
+ dank run --detached
1654
+ dank logs test-agent --follow
1655
+
1656
+ # Check health endpoints
1657
+ curl http://localhost:3001/health
1658
+
1659
+ # Monitor resource usage
1660
+ docker stats dank-test-agent
1661
+ ```
1662
+
1663
+ #### 3. Production Deployment
1664
+ ```bash
1665
+ # 1. Set production environment
1666
+ export NODE_ENV=production
1667
+
1668
+ # 2. Build optimized images
1669
+ dank build --force
1670
+
1671
+ # 3. Start with image config
1672
+ dank run --detached
1673
+
1674
+ # 4. Monitor and scale as needed
1675
+ dank status --watch
1676
+ ```
1677
+
1678
+ ### Monitoring and Debugging
1679
+
1680
+ ```bash
1681
+ # Watch all agents in real-time
1682
+ dank status --watch
1683
+
1684
+ # Follow logs from specific agent
1685
+ dank logs my-agent --follow
1686
+
1687
+ # View container details
1688
+ docker ps -f name=dank-
1689
+
1690
+ # Check agent health
1691
+ curl http://localhost:3001/health
1692
+ ```
1693
+
1694
+ ## 📦 Installation
1695
+
1696
+ ### Prerequisites
1697
+ - Node.js 16+
1698
+ - Docker Desktop or Docker Engine
1699
+ - npm or yarn
1700
+
1701
+ ### Global Installation
1702
+ ```bash
1703
+ npm install -g dank-ai
1704
+ ```
1705
+
1706
+ ### Local Development
1707
+ ```bash
1708
+ git clone https://github.com/your-org/dank
1709
+ cd dank
1710
+ npm install
1711
+ npm link # Creates global symlink
1712
+ ```
1713
+
1714
+ ## 🤝 Contributing
1715
+
1716
+ 1. Fork the repository
1717
+ 2. Create a feature branch: `git checkout -b feature/amazing-feature`
1718
+ 3. Commit changes: `git commit -m 'Add amazing feature'`
1719
+ 4. Push to branch: `git push origin feature/amazing-feature`
1720
+ 5. Open a Pull Request
92
1721
 
93
- Edit `dank.config.js` to:
1722
+ ## 📄 License
94
1723
 
95
- - Define your agents and their capabilities
96
- - Set up LLM providers and models
97
- - Configure event handlers
98
- - Set Docker and resource limits
99
- - Enable/disable communication features
1724
+ ISC License - see LICENSE file for details.
100
1725
 
101
- ## Documentation
1726
+ ## 🆘 Support
102
1727
 
103
- For more information, visit the [Dank Framework Documentation](https://github.com/your-org/dank).
1728
+ - **Documentation**: [Wiki](https://github.com/your-org/dank/wiki)
1729
+ - **Issues**: [GitHub Issues](https://github.com/your-org/dank/issues)
1730
+ - **Discussions**: [GitHub Discussions](https://github.com/your-org/dank/discussions)
104
1731
 
105
- ## License
1732
+ ---
106
1733
 
107
- ISC
1734
+ **Built with 💯 energy for the AI agent revolution!** 🚀