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 +429 -1393
- package/lib/agent.js +82 -6
- package/lib/cli/init.js +25 -1
- package/lib/cli/production-build.js +3 -1
- package/lib/cli/run.js +3 -1
- package/lib/docker/manager.js +165 -10
- package/lib/index.js +8 -0
- package/lib/plugins/base.js +324 -0
- package/lib/plugins/config.js +171 -0
- package/lib/plugins/events.js +186 -0
- package/lib/plugins/index.js +29 -0
- package/lib/plugins/manager.js +258 -0
- package/lib/plugins/registry.js +268 -0
- package/lib/project.js +15 -8
- package/package.json +1 -1
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
|
|
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
|
|
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
|
|
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** (
|
|
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
|
|
41
|
+
> **🆕 Auto-Docker Installation**: Dank automatically detects, installs, and starts Docker if unavailable. No manual setup required!
|
|
41
42
|
|
|
42
|
-
###
|
|
43
|
-
```bash
|
|
44
|
-
npm install -g dank-ai
|
|
45
|
-
```
|
|
43
|
+
### Installation & Setup
|
|
46
44
|
|
|
47
|
-
### 2. Initialize a new project
|
|
48
45
|
```bash
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
cd my-agent-project
|
|
46
|
+
# 1. Install globally
|
|
47
|
+
npm install -g dank-ai
|
|
52
48
|
|
|
53
|
-
# Initialize
|
|
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
|
-
|
|
67
|
+
<details>
|
|
68
|
+
<summary><b>📁 Project Structure</b></summary>
|
|
69
|
+
|
|
58
70
|
```
|
|
59
|
-
my-
|
|
60
|
-
├── dank.config.js #
|
|
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
|
-
|
|
76
|
+
├── project.yaml # Project state
|
|
77
|
+
└── logs/ # Agent logs
|
|
65
78
|
```
|
|
79
|
+
</details>
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
Create a `.env` file or export environment variables:
|
|
81
|
+
## 📋 CLI Commands
|
|
69
82
|
|
|
83
|
+
### Core Commands
|
|
70
84
|
```bash
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
#
|
|
75
|
-
|
|
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
|
-
|
|
78
|
-
|
|
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
|
-
|
|
82
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
|
98
|
-
.
|
|
99
|
-
.
|
|
100
|
-
|
|
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
|
-
|
|
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
|
-
>
|
|
148
|
+
<details>
|
|
149
|
+
<summary><b>📦 Dynamic Imports (ESM-only packages)</b></summary>
|
|
181
150
|
|
|
182
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
158
|
+
// Multiline .then() is also supported
|
|
159
|
+
const ora = import("ora").then((m) => {
|
|
160
|
+
return m.default;
|
|
161
|
+
});
|
|
223
162
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
-
|
|
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
|
-
>
|
|
321
|
-
|
|
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
|
-
####
|
|
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
|
|
221
|
+
// Main response event
|
|
333
222
|
.addHandler('request_output', (data) => {
|
|
334
|
-
console.log('
|
|
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
|
-
//
|
|
226
|
+
// Modify prompt before LLM processing
|
|
347
227
|
.addHandler('request_output:start', (data) => {
|
|
348
|
-
|
|
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
|
-
|
|
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('
|
|
238
|
+
console.error('Error:', data.error);
|
|
373
239
|
});
|
|
374
240
|
```
|
|
375
241
|
|
|
376
|
-
|
|
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
|
-
|
|
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
|
-
|
|
403
|
-
.
|
|
404
|
-
|
|
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
|
-
|
|
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
|
-
|
|
462
|
-
Traditional system-level events:
|
|
254
|
+
#### System Events
|
|
463
255
|
|
|
464
256
|
```javascript
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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
|
-
####
|
|
263
|
+
#### Advanced Patterns
|
|
488
264
|
|
|
489
|
-
**Wildcard Matching:**
|
|
490
265
|
```javascript
|
|
491
|
-
//
|
|
492
|
-
.addHandler('tool:*', (data) =>
|
|
493
|
-
|
|
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
|
-
//
|
|
498
|
-
.addHandler('request_output
|
|
499
|
-
|
|
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
|
|
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
|
-
|
|
289
|
+
### Production Image Configuration
|
|
580
290
|
|
|
581
291
|
```javascript
|
|
582
|
-
// Complete agent image configuration
|
|
583
292
|
.setAgentImageConfig({
|
|
584
|
-
registry: 'ghcr.io',
|
|
585
|
-
namespace: 'mycompany',
|
|
586
|
-
tag: 'v1.0.0'
|
|
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
|
-
|
|
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
|
-
|
|
694
|
-
dank build:prod --force
|
|
302
|
+
#### Image Naming
|
|
695
303
|
|
|
696
|
-
|
|
697
|
-
|
|
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
|
-
|
|
700
|
-
dank build:prod --tag release-2024.1 --push
|
|
701
|
-
```
|
|
308
|
+
#### Deployment Metadata
|
|
702
309
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
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
|
-
|
|
709
|
-
dank build:prod --push --output-metadata deployment.json
|
|
316
|
+
Perfect for CI/CD pipelines to auto-configure deployment infrastructure.
|
|
710
317
|
|
|
711
|
-
|
|
712
|
-
|
|
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
|
-
"
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
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
|
-
|
|
337
|
+
#### Registry Authentication
|
|
1008
338
|
|
|
1009
|
-
|
|
339
|
+
```bash
|
|
340
|
+
# Docker Hub
|
|
341
|
+
docker login
|
|
342
|
+
dank build:prod --registry docker.io --namespace myusername --push
|
|
1010
343
|
|
|
1011
|
-
|
|
1012
|
-
|
|
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
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1026
|
-
|
|
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
|
-
|
|
1029
|
-
|
|
386
|
+
<details>
|
|
387
|
+
<summary><b>Docker Compose Example</b></summary>
|
|
1030
388
|
|
|
1031
|
-
|
|
1032
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1132
|
-
const { createAgent } = require('dank');
|
|
419
|
+
Dank automatically handles Docker installation and startup:
|
|
1133
420
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
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
|
-
|
|
1151
|
-
|
|
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
|
-
|
|
1154
|
-
|
|
432
|
+
If automatic installation fails, Dank provides clear manual instructions.
|
|
433
|
+
</details>
|
|
1155
434
|
|
|
1156
|
-
|
|
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
|
-
|
|
437
|
+
<details>
|
|
438
|
+
<summary><b>🎯 Common Use Cases</b></summary>
|
|
1220
439
|
|
|
1221
|
-
####
|
|
440
|
+
#### Customer Support Automation
|
|
1222
441
|
```javascript
|
|
1223
442
|
createAgent('support-bot')
|
|
1224
|
-
.setLLM('openai', {
|
|
1225
|
-
|
|
1226
|
-
|
|
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
|
-
####
|
|
449
|
+
#### Content Generation Pipeline
|
|
1253
450
|
```javascript
|
|
1254
|
-
const
|
|
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
|
-
|
|
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', (
|
|
1279
|
-
// Publish optimized content
|
|
1280
|
-
publishContent(optimizedContent);
|
|
1281
|
-
})
|
|
465
|
+
.addHandler('output', (content) => publishContent(content))
|
|
1282
466
|
];
|
|
1283
467
|
```
|
|
1284
468
|
|
|
1285
|
-
####
|
|
469
|
+
#### Data Analysis Workflow
|
|
1286
470
|
```javascript
|
|
1287
471
|
createAgent('data-processor')
|
|
1288
|
-
.setLLM('openai', {
|
|
1289
|
-
|
|
1290
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1368
|
-
const
|
|
1369
|
-
|
|
1370
|
-
|
|
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
|
-
|
|
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
|
-
|
|
520
|
+
<details>
|
|
521
|
+
<summary><b>💡 Best Practices</b></summary>
|
|
1477
522
|
|
|
1478
|
-
####
|
|
523
|
+
#### Resource Management
|
|
1479
524
|
```javascript
|
|
1480
|
-
//
|
|
1481
|
-
createAgent('
|
|
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
|
-
####
|
|
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
|
-
|
|
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
|
-
####
|
|
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
|
-
####
|
|
555
|
+
#### Security
|
|
1567
556
|
```javascript
|
|
1568
|
-
// Good: Secure configuration
|
|
1569
557
|
createAgent('secure-agent')
|
|
1570
|
-
.setLLM('openai', {
|
|
1571
|
-
|
|
1572
|
-
|
|
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
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
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
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
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
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
.
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
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
|
-
|
|
608
|
+
3. **Compile and run:**
|
|
1624
609
|
|
|
1625
|
-
#### 1. Local Development
|
|
1626
610
|
```bash
|
|
1627
|
-
#
|
|
1628
|
-
|
|
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
|
-
|
|
623
|
+
</details>
|
|
1631
624
|
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
dank run --build # Rebuild if needed
|
|
625
|
+
<details>
|
|
626
|
+
<summary><b>🔄 Development Workflow</b></summary>
|
|
1635
627
|
|
|
1636
|
-
|
|
1637
|
-
|
|
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
|
-
####
|
|
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
|
-
####
|
|
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
|
-
|
|
654
|
+
<details>
|
|
655
|
+
<summary><b>Common Issues and Solutions</b></summary>
|
|
1669
656
|
|
|
657
|
+
**1. Docker Connection Issues**
|
|
1670
658
|
```bash
|
|
1671
|
-
#
|
|
1672
|
-
|
|
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
|
-
|
|
1675
|
-
|
|
677
|
+
**4. Container Resource Issues**
|
|
678
|
+
```javascript
|
|
679
|
+
// Increase memory allocation (cloud only)
|
|
680
|
+
createAgent('my-agent').setInstanceType('medium');
|
|
681
|
+
```
|
|
1676
682
|
|
|
1677
|
-
|
|
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
|
-
|
|
1681
|
-
|
|
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
|
-
##
|
|
709
|
+
## 📋 Example Files
|
|
1685
710
|
|
|
1686
|
-
|
|
1687
|
-
-
|
|
1688
|
-
-
|
|
1689
|
-
|
|
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
|
+
---
|