dank-ai 1.0.39 → 1.0.42

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