dank-ai 1.0.1 โ 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build-context-api-agent/Dockerfile +3 -0
- package/.build-context-basic-agent/Dockerfile +3 -0
- package/.build-context-prompt-only-agent/Dockerfile +3 -0
- package/.build-context-webhook-agent/Dockerfile +3 -0
- package/.env.example +22 -0
- package/README.md +66 -1290
- package/agents/example-agent.js +41 -0
- package/dank.config.js +210 -0
- package/docker/package-lock.json +2899 -0
- package/docker/package.json +7 -6
- package/example/README.md +176 -0
- package/example/dank.config.js +301 -0
- package/lib/agent.js +14 -19
- package/lib/cli/init.js +52 -7
- package/lib/project.js +16 -4
- package/package.json +20 -41
package/docker/package.json
CHANGED
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
"description": "Runtime dependencies for Dank agents",
|
|
5
5
|
"private": true,
|
|
6
6
|
"dependencies": {
|
|
7
|
+
"@anthropic-ai/sdk": "^0.6.0",
|
|
7
8
|
"axios": "^1.5.0",
|
|
8
|
-
"
|
|
9
|
-
"winston": "^3.10.0",
|
|
9
|
+
"cohere-ai": "^7.0.0",
|
|
10
10
|
"dotenv": "^16.3.1",
|
|
11
|
+
"express": "^4.18.2",
|
|
12
|
+
"express-rate-limit": "^6.8.1",
|
|
11
13
|
"lodash": "^4.17.21",
|
|
12
|
-
"uuid": "^9.0.0",
|
|
13
14
|
"moment": "^2.29.4",
|
|
14
15
|
"openai": "^4.0.0",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"uuid": "^9.0.0",
|
|
17
|
+
"winston": "^3.10.0",
|
|
18
|
+
"ws": "^8.18.3"
|
|
18
19
|
}
|
|
19
20
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# ๐งช Dank Agent HTTP Endpoints Test
|
|
2
|
+
|
|
3
|
+
This directory contains a test configuration with HTTP-enabled agents and their endpoints.
|
|
4
|
+
|
|
5
|
+
## ๐ Quick Start
|
|
6
|
+
|
|
7
|
+
1. **Start the agents:**
|
|
8
|
+
```bash
|
|
9
|
+
cd test
|
|
10
|
+
dank run
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
2. **Test the endpoints:**
|
|
14
|
+
```bash
|
|
15
|
+
# Install axios for testing (if not already installed)
|
|
16
|
+
npm install axios
|
|
17
|
+
|
|
18
|
+
# Run endpoint tests
|
|
19
|
+
node test-endpoints.js
|
|
20
|
+
|
|
21
|
+
# Or run graceful tests (handles errors better)
|
|
22
|
+
node test-endpoints.js graceful
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## ๐ค Agents & Endpoints
|
|
26
|
+
|
|
27
|
+
### API Agent (Port 3000)
|
|
28
|
+
A full-featured API agent with various endpoints:
|
|
29
|
+
|
|
30
|
+
**Endpoints:**
|
|
31
|
+
- `GET /` - Welcome message and endpoint list
|
|
32
|
+
- `GET /hello?name=YourName` - Simple greeting
|
|
33
|
+
- `POST /chat` - Chat with the AI agent
|
|
34
|
+
- `POST /analyze` - Analyze text content
|
|
35
|
+
- `GET /status` - Agent status and metrics
|
|
36
|
+
- `GET /metrics` - Performance metrics
|
|
37
|
+
|
|
38
|
+
**Example Usage:**
|
|
39
|
+
```bash
|
|
40
|
+
# Simple greeting
|
|
41
|
+
curl "http://localhost:3000/hello?name=Developer"
|
|
42
|
+
|
|
43
|
+
# Chat with agent
|
|
44
|
+
curl -X POST "http://localhost:3000/chat" \
|
|
45
|
+
-H "Content-Type: application/json" \
|
|
46
|
+
-d '{"message": "Hello, how can you help me?"}'
|
|
47
|
+
|
|
48
|
+
# Analyze text with sentiment
|
|
49
|
+
curl -X POST "http://localhost:3000/analyze" \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{"text": "This is amazing software!", "analysisType": "sentiment"}'
|
|
52
|
+
|
|
53
|
+
# Get agent status
|
|
54
|
+
curl "http://localhost:3000/status"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Webhook Agent (Port 3001)
|
|
58
|
+
Specialized agent for handling webhooks from external services:
|
|
59
|
+
|
|
60
|
+
**Endpoints:**
|
|
61
|
+
- `GET /webhook/test` - Test endpoint status
|
|
62
|
+
- `POST /webhook/github` - GitHub webhook handler
|
|
63
|
+
- `POST /webhook/slack` - Slack webhook handler
|
|
64
|
+
- `POST /webhook/generic` - Generic webhook handler
|
|
65
|
+
|
|
66
|
+
**Example Usage:**
|
|
67
|
+
```bash
|
|
68
|
+
# Test webhook status
|
|
69
|
+
curl "http://localhost:3001/webhook/test"
|
|
70
|
+
|
|
71
|
+
# Simulate GitHub webhook
|
|
72
|
+
curl -X POST "http://localhost:3001/webhook/github" \
|
|
73
|
+
-H "X-GitHub-Event: push" \
|
|
74
|
+
-H "Content-Type: application/json" \
|
|
75
|
+
-d '{"repository": {"full_name": "user/repo"}}'
|
|
76
|
+
|
|
77
|
+
# Simulate Slack webhook
|
|
78
|
+
curl -X POST "http://localhost:3001/webhook/slack" \
|
|
79
|
+
-H "Content-Type: application/json" \
|
|
80
|
+
-d '{"text": "Hello!", "user_name": "testuser", "channel_name": "#general"}'
|
|
81
|
+
|
|
82
|
+
# Generic webhook with custom source
|
|
83
|
+
curl -X POST "http://localhost:3001/webhook/generic" \
|
|
84
|
+
-H "X-Webhook-Source: my-service" \
|
|
85
|
+
-H "Content-Type: application/json" \
|
|
86
|
+
-d '{"event": "user_signup", "data": {"email": "test@example.com"}}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## ๐ง Features Demonstrated
|
|
90
|
+
|
|
91
|
+
### API Agent Features:
|
|
92
|
+
- โ
**CORS enabled** - Cross-origin requests allowed
|
|
93
|
+
- โ
**Rate limiting** - 100 requests per 15 minutes per IP
|
|
94
|
+
- โ
**Input validation** - Proper error handling for missing data
|
|
95
|
+
- โ
**JSON responses** - Consistent API response format
|
|
96
|
+
- โ
**Error handling** - Graceful error responses
|
|
97
|
+
- โ
**Metrics & monitoring** - Status and performance endpoints
|
|
98
|
+
|
|
99
|
+
### Webhook Agent Features:
|
|
100
|
+
- โ
**Multiple webhook types** - GitHub, Slack, generic webhooks
|
|
101
|
+
- โ
**Header processing** - Reads webhook-specific headers
|
|
102
|
+
- โ
**Event logging** - Logs incoming webhook events
|
|
103
|
+
- โ
**Flexible responses** - Different response formats per webhook type
|
|
104
|
+
|
|
105
|
+
### Security & Performance:
|
|
106
|
+
- โ
**Port isolation** - Different ports for different services
|
|
107
|
+
- โ
**Resource limits** - CPU and memory constraints
|
|
108
|
+
- โ
**Request logging** - All requests are logged
|
|
109
|
+
- โ
**Graceful error handling** - No crashes on bad requests
|
|
110
|
+
|
|
111
|
+
## ๐งช Testing Scenarios
|
|
112
|
+
|
|
113
|
+
The test script (`test-endpoints.js`) covers:
|
|
114
|
+
|
|
115
|
+
1. **Basic functionality** - All endpoints return expected responses
|
|
116
|
+
2. **Error handling** - Invalid requests return proper error messages
|
|
117
|
+
3. **Data processing** - POST endpoints process JSON payloads correctly
|
|
118
|
+
4. **Headers** - Webhook endpoints read custom headers
|
|
119
|
+
5. **Response formats** - All responses follow consistent JSON structure
|
|
120
|
+
|
|
121
|
+
## ๐ Expected Responses
|
|
122
|
+
|
|
123
|
+
### Successful API Response Format:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"message": "Response message",
|
|
127
|
+
"agent": "agent-name",
|
|
128
|
+
"timestamp": "2024-01-01T12:00:00.000Z",
|
|
129
|
+
"data": { /* response data */ }
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Error Response Format:
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"error": "Error description",
|
|
137
|
+
"message": "Detailed error message",
|
|
138
|
+
"timestamp": "2024-01-01T12:00:00.000Z"
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## ๐ Monitoring
|
|
143
|
+
|
|
144
|
+
While agents are running, you can monitor them:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Check agent status
|
|
148
|
+
dank status
|
|
149
|
+
|
|
150
|
+
# View agent logs
|
|
151
|
+
dank logs api-agent --follow
|
|
152
|
+
dank logs webhook-agent --follow
|
|
153
|
+
|
|
154
|
+
# Check container stats
|
|
155
|
+
docker stats $(docker ps -f name=dank- -q)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## ๐จ Troubleshooting
|
|
159
|
+
|
|
160
|
+
**Connection refused errors:**
|
|
161
|
+
- Make sure agents are running with `dank run`
|
|
162
|
+
- Check if ports 3000 and 3001 are available
|
|
163
|
+
- Verify Docker containers are running: `docker ps`
|
|
164
|
+
|
|
165
|
+
**Rate limit errors:**
|
|
166
|
+
- Wait 15 minutes for rate limit to reset
|
|
167
|
+
- Or restart the agents to reset counters
|
|
168
|
+
|
|
169
|
+
**JSON parsing errors:**
|
|
170
|
+
- Ensure Content-Type header is set to `application/json`
|
|
171
|
+
- Verify JSON payload is properly formatted
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
๐ฅ **Ready to test your HTTP-enabled Dank agents!** ๐
|
|
176
|
+
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dank Agent Configuration - Auto-Detection Features
|
|
3
|
+
*
|
|
4
|
+
* This file demonstrates the new auto-detection capabilities:
|
|
5
|
+
* - Event handlers are auto-enabled only when .addHandler() is used
|
|
6
|
+
* - Direct prompting is auto-enabled only when .setPrompt() + .setLLM() are set
|
|
7
|
+
* - HTTP API is auto-enabled only when routes (.get(), .post(), etc.) are added
|
|
8
|
+
*
|
|
9
|
+
* No more explicit .enableHttpApi() or .disableEventHandlers() calls needed!
|
|
10
|
+
* Run 'dank run' to start all defined agents.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: This file uses the local development version (../lib/index.js).
|
|
13
|
+
* For production use, copy example/dank.config.template.js to your project
|
|
14
|
+
* and install dank via npm, then update the require statement.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { createAgent } = require("dank");
|
|
18
|
+
module.exports = {
|
|
19
|
+
// Project configuration
|
|
20
|
+
name: "test-project",
|
|
21
|
+
|
|
22
|
+
// Define your agents
|
|
23
|
+
agents: [
|
|
24
|
+
// 1. DIRECT PROMPTING ONLY - Auto-enabled because it has setPrompt() + setLLM() + handlers
|
|
25
|
+
createAgent("prompt-only-agent")
|
|
26
|
+
.setLLM("openai", {
|
|
27
|
+
apiKey:
|
|
28
|
+
"x",
|
|
29
|
+
model: "gpt-3.5-turbo",
|
|
30
|
+
temperature: 0.7,
|
|
31
|
+
})
|
|
32
|
+
//add in a pre-prompt pipeline that handler that can be used to modify and moderate requests to the prompt before it is sent to the LLM, and handler for when the llm responds with response but before it is sent to the client
|
|
33
|
+
.setPrompt("You are a helpful assistant that responds to direct prompts.") // โ
Auto-enables direct prompting
|
|
34
|
+
.setBaseImage("nodejs-22") //latest is nodejs-20
|
|
35
|
+
.setPromptingServer({
|
|
36
|
+
protocol: "http",
|
|
37
|
+
port: 3000,
|
|
38
|
+
authentication: false,
|
|
39
|
+
maxConnections: 50,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// HTTP API auto-disabled (no routes added)
|
|
43
|
+
// Event handlers auto-enabled (handlers added below)
|
|
44
|
+
.setResources({
|
|
45
|
+
memory: "512m",
|
|
46
|
+
cpu: 1,
|
|
47
|
+
})
|
|
48
|
+
// Adding handlers auto-enables event handling โ
|
|
49
|
+
.addHandler("request_output", (data) => {
|
|
50
|
+
console.log("[Prompt-Only Agent] LLM Response:", {
|
|
51
|
+
originalPrompt: data.prompt.substring(0, 50) + "...",
|
|
52
|
+
finalPrompt: data.finalPrompt
|
|
53
|
+
? data.finalPrompt.substring(0, 50) + "..."
|
|
54
|
+
: "N/A",
|
|
55
|
+
promptModified: data.promptModified,
|
|
56
|
+
response: data.response.substring(0, 100) + "...",
|
|
57
|
+
processingTime: data.processingTime + "ms",
|
|
58
|
+
model: data.model,
|
|
59
|
+
});
|
|
60
|
+
})
|
|
61
|
+
.addHandler("request_output:start", (data) => {
|
|
62
|
+
console.log(
|
|
63
|
+
"[Prompt-Only Agent] Processing prompt:",
|
|
64
|
+
data.conversationId
|
|
65
|
+
);
|
|
66
|
+
console.log("[Prompt-Only Agent] Original prompt:", data.prompt);
|
|
67
|
+
|
|
68
|
+
// Example: Add context to the prompt
|
|
69
|
+
const enhancedPrompt = `Context: You are a helpful assistant. Please be concise and friendly.
|
|
70
|
+
|
|
71
|
+
User Question: ${data.prompt}`;
|
|
72
|
+
|
|
73
|
+
console.log("[Prompt-Only Agent] Enhanced prompt:", enhancedPrompt);
|
|
74
|
+
|
|
75
|
+
// Return modified data - this will replace the prompt sent to the LLM
|
|
76
|
+
return {
|
|
77
|
+
prompt: enhancedPrompt,
|
|
78
|
+
};
|
|
79
|
+
})
|
|
80
|
+
.addHandler("request_output:end", (data) => {
|
|
81
|
+
console.log(
|
|
82
|
+
"[Prompt-Only Agent] Completed in:",
|
|
83
|
+
data.processingTime + "ms"
|
|
84
|
+
);
|
|
85
|
+
console.log(
|
|
86
|
+
"[Prompt-Only Agent] Original response:",
|
|
87
|
+
data.response.substring(0, 50) + "..."
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Example: Add a simple footer to the response
|
|
91
|
+
const enhancedResponse = `${data.response}\n\n[Enhanced by Dank Framework]`;
|
|
92
|
+
|
|
93
|
+
console.log(
|
|
94
|
+
"[Prompt-Only Agent] Enhanced response:",
|
|
95
|
+
enhancedResponse.substring(0, 100) + "..."
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Return modified data - this will replace the response sent to the caller
|
|
99
|
+
return {
|
|
100
|
+
response: "dank response:" + enhancedResponse,
|
|
101
|
+
};
|
|
102
|
+
})
|
|
103
|
+
.addHandler("error", (error) => {
|
|
104
|
+
console.error("[Prompt-Only Agent] Error:", error);
|
|
105
|
+
}),
|
|
106
|
+
|
|
107
|
+
/*
|
|
108
|
+
// 2. HTTP API ONLY - Auto-enabled because it has routes, auto-disabled direct prompting (no setPrompt)
|
|
109
|
+
createAgent('api-only-agent')
|
|
110
|
+
.setLLM('openai', {
|
|
111
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
112
|
+
model: 'gpt-4',
|
|
113
|
+
temperature: 0.5
|
|
114
|
+
})
|
|
115
|
+
// โ No setPrompt() = Direct prompting auto-disabled
|
|
116
|
+
.setBaseImage('nodejs-20')
|
|
117
|
+
// โ No more .disableDirectPrompting() or .enableHttpApi() needed!
|
|
118
|
+
// Direct prompting auto-disabled (no setPrompt())
|
|
119
|
+
// HTTP API auto-enabled (routes added below)
|
|
120
|
+
// Event handlers auto-enabled (handlers added below)
|
|
121
|
+
.enableHttp({
|
|
122
|
+
port: 3001,
|
|
123
|
+
cors: true,
|
|
124
|
+
rateLimit: {
|
|
125
|
+
windowMs: 15 * 60 * 1000,
|
|
126
|
+
max: 100
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
// Adding routes auto-enables HTTP API โ
|
|
130
|
+
.get('/chat', (req, res) => {
|
|
131
|
+
res.json({
|
|
132
|
+
message: 'Hello from API-only agent!',
|
|
133
|
+
query: req.query,
|
|
134
|
+
timestamp: new Date().toISOString()
|
|
135
|
+
});
|
|
136
|
+
})
|
|
137
|
+
.post('/process', (req, res) => {
|
|
138
|
+
res.json({
|
|
139
|
+
processed: true,
|
|
140
|
+
input: req.body,
|
|
141
|
+
agent: 'api-only-agent',
|
|
142
|
+
timestamp: new Date().toISOString()
|
|
143
|
+
});
|
|
144
|
+
})
|
|
145
|
+
.setResources({
|
|
146
|
+
memory: '1g',
|
|
147
|
+
cpu: 2
|
|
148
|
+
})
|
|
149
|
+
// Adding handlers auto-enables event handling โ
|
|
150
|
+
.addHandler('tool:http-server:*', (data) => {
|
|
151
|
+
console.log('[API-Only Agent] HTTP Activity:', {
|
|
152
|
+
type: data.type,
|
|
153
|
+
method: data.method,
|
|
154
|
+
path: data.path,
|
|
155
|
+
statusCode: data.statusCode
|
|
156
|
+
});
|
|
157
|
+
})
|
|
158
|
+
.addHandler('tool:http-server:call', (data) => {
|
|
159
|
+
console.log('[API-Only Agent] Incoming Request:', {
|
|
160
|
+
method: data.method,
|
|
161
|
+
path: data.path,
|
|
162
|
+
hasBody: !!data.body
|
|
163
|
+
});
|
|
164
|
+
})
|
|
165
|
+
.addHandler('tool:http-server:response:post', (data) => {
|
|
166
|
+
console.log('[API-Only Agent] POST Response:', {
|
|
167
|
+
path: data.path,
|
|
168
|
+
statusCode: data.statusCode,
|
|
169
|
+
processingTime: data.processingTime + 'ms'
|
|
170
|
+
});
|
|
171
|
+
}),
|
|
172
|
+
// 3. MINIMAL AGENT - Auto-disables everything (no setPrompt, no routes, no handlers)
|
|
173
|
+
createAgent('minimal-agent')
|
|
174
|
+
.setLLM('anthropic', {
|
|
175
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
176
|
+
model: 'claude-3-sonnet-20240229',
|
|
177
|
+
temperature: 0.3
|
|
178
|
+
})
|
|
179
|
+
// โ No setPrompt() = Direct prompting auto-disabled
|
|
180
|
+
// โ No routes = HTTP API auto-disabled
|
|
181
|
+
// โ No handlers = Event handling auto-disabled
|
|
182
|
+
.setBaseImage('python-311')
|
|
183
|
+
// โ No more explicit disable calls needed!
|
|
184
|
+
// All features auto-disabled based on usage
|
|
185
|
+
.setResources({
|
|
186
|
+
memory: '1g',
|
|
187
|
+
cpu: 1
|
|
188
|
+
}),
|
|
189
|
+
// This agent only has basic LLM functionality available
|
|
190
|
+
|
|
191
|
+
// 4. EVENT HANDLERS ONLY - Auto-enabled because it has handlers, auto-disabled others
|
|
192
|
+
/*
|
|
193
|
+
createAgent('event-only-agent')
|
|
194
|
+
.setLLM('anthropic', {
|
|
195
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
196
|
+
model: 'claude-3-sonnet-20240229',
|
|
197
|
+
temperature: 0.3
|
|
198
|
+
})
|
|
199
|
+
// โ No setPrompt() = Direct prompting auto-disabled
|
|
200
|
+
// โ No routes = HTTP API auto-disabled
|
|
201
|
+
// โ
Has handlers = Event handling auto-enabled
|
|
202
|
+
.setBaseImage('python-311')
|
|
203
|
+
.setResources({
|
|
204
|
+
memory: '1g',
|
|
205
|
+
cpu: 1
|
|
206
|
+
})
|
|
207
|
+
// Adding handlers auto-enables event handling โ
|
|
208
|
+
.addHandler('output', (data) => {
|
|
209
|
+
console.log('[Event-Only Agent] Processing output:', data);
|
|
210
|
+
})
|
|
211
|
+
.addHandler('error', (error) => {
|
|
212
|
+
console.error('[Event-Only Agent] Handling error:', error);
|
|
213
|
+
})
|
|
214
|
+
.addHandler('custom', (data) => {
|
|
215
|
+
console.log('[Event-Only Agent] Custom event:', data);
|
|
216
|
+
}),
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
// 5. FULL-FEATURED AGENT - Auto-enables all features based on usage
|
|
220
|
+
/*
|
|
221
|
+
createAgent('full-featured-agent')
|
|
222
|
+
.setLLM('openai', {
|
|
223
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
224
|
+
model: 'gpt-4',
|
|
225
|
+
temperature: 0.6
|
|
226
|
+
})
|
|
227
|
+
.setPrompt('You are a versatile agent supporting all communication methods.') // โ
Auto-enables direct prompting
|
|
228
|
+
.setBaseImage('latest')
|
|
229
|
+
.setPromptingServer({
|
|
230
|
+
protocol: 'websocket',
|
|
231
|
+
port: 3003,
|
|
232
|
+
authentication: true,
|
|
233
|
+
maxConnections: 100
|
|
234
|
+
})
|
|
235
|
+
.enableHttp({
|
|
236
|
+
port: 8080,
|
|
237
|
+
cors: true
|
|
238
|
+
})
|
|
239
|
+
// โ No more .enableHttpApi() or .enableEventHandlers() needed!
|
|
240
|
+
// Direct prompting auto-enabled (has setPrompt() + setLLM())
|
|
241
|
+
// HTTP API auto-enabled (routes added below)
|
|
242
|
+
// Event handlers auto-enabled (handlers added below)
|
|
243
|
+
|
|
244
|
+
// Adding routes auto-enables HTTP API โ
|
|
245
|
+
.get('/status', (req, res) => {
|
|
246
|
+
res.json({
|
|
247
|
+
agent: 'full-featured-agent',
|
|
248
|
+
features: {
|
|
249
|
+
directPrompting: 'auto-enabled (has prompt + LLM)',
|
|
250
|
+
httpApi: 'auto-enabled (has routes)',
|
|
251
|
+
eventHandlers: 'auto-enabled (has handlers)'
|
|
252
|
+
},
|
|
253
|
+
timestamp: new Date().toISOString()
|
|
254
|
+
});
|
|
255
|
+
})
|
|
256
|
+
.post('/chat', (req, res) => {
|
|
257
|
+
res.json({
|
|
258
|
+
response: `I received: ${req.body.message}`,
|
|
259
|
+
via: 'HTTP API',
|
|
260
|
+
timestamp: new Date().toISOString()
|
|
261
|
+
});
|
|
262
|
+
})
|
|
263
|
+
.setResources({
|
|
264
|
+
memory: '2g',
|
|
265
|
+
cpu: 3
|
|
266
|
+
})
|
|
267
|
+
// Adding handlers auto-enables event handling โ
|
|
268
|
+
.addHandler('output', (data) => {
|
|
269
|
+
console.log('[Full-Featured Agent] Output:', data);
|
|
270
|
+
})
|
|
271
|
+
.addHandler('error', (error) => {
|
|
272
|
+
console.error('[Full-Featured Agent] Error:', error);
|
|
273
|
+
})
|
|
274
|
+
.addHandler('heartbeat', () => {
|
|
275
|
+
console.log('[Full-Featured Agent] Heartbeat - All systems operational');
|
|
276
|
+
})
|
|
277
|
+
// Event patterns for all communication methods
|
|
278
|
+
.addHandler('request_output', (data) => {
|
|
279
|
+
console.log('[Full-Featured Agent] Direct Prompt Response:', {
|
|
280
|
+
conversationId: data.conversationId,
|
|
281
|
+
responseLength: data.response.length,
|
|
282
|
+
processingTime: data.processingTime + 'ms'
|
|
283
|
+
});
|
|
284
|
+
})
|
|
285
|
+
.addHandler('tool:http-server:call:post', (data) => {
|
|
286
|
+
console.log('[Full-Featured Agent] HTTP POST Call:', {
|
|
287
|
+
path: data.path,
|
|
288
|
+
bodySize: JSON.stringify(data.body).length
|
|
289
|
+
});
|
|
290
|
+
})
|
|
291
|
+
.addHandler('tool:http-server:response', (data) => {
|
|
292
|
+
console.log('[Full-Featured Agent] HTTP Response:', {
|
|
293
|
+
method: data.method,
|
|
294
|
+
path: data.path,
|
|
295
|
+
status: data.statusCode,
|
|
296
|
+
time: data.processingTime + 'ms'
|
|
297
|
+
});
|
|
298
|
+
})
|
|
299
|
+
*/
|
|
300
|
+
],
|
|
301
|
+
};
|
package/lib/agent.js
CHANGED
|
@@ -110,39 +110,34 @@ class DankAgent {
|
|
|
110
110
|
return this;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/**
|
|
114
|
-
* Set the main port that the agent will expose
|
|
115
|
-
*/
|
|
116
|
-
setPort(port) {
|
|
117
|
-
if (typeof port !== 'number' || port < 1000 || port > 65535) {
|
|
118
|
-
throw new Error('Port must be a number between 1000 and 65535');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
this.config.docker = { ...this.config.docker, port };
|
|
122
|
-
return this;
|
|
123
|
-
}
|
|
124
113
|
|
|
125
114
|
/**
|
|
126
|
-
*
|
|
115
|
+
* Configure prompting server settings
|
|
127
116
|
*/
|
|
128
|
-
|
|
117
|
+
setPromptingServer(options = {}) {
|
|
129
118
|
const schema = Joi.object({
|
|
130
|
-
protocol: Joi.string().valid('websocket', 'tcp', 'http').default('
|
|
119
|
+
protocol: Joi.string().valid('websocket', 'tcp', 'http').default('http'),
|
|
120
|
+
port: Joi.number().min(1000).max(65535).default(3000),
|
|
131
121
|
authentication: Joi.boolean().default(false),
|
|
132
|
-
maxConnections: Joi.number().min(1).max(1000).default(
|
|
122
|
+
maxConnections: Joi.number().min(1).max(1000).default(50),
|
|
133
123
|
timeout: Joi.number().min(1000).default(30000)
|
|
134
124
|
});
|
|
135
125
|
|
|
136
126
|
const { error, value } = schema.validate(options);
|
|
137
127
|
if (error) {
|
|
138
|
-
throw new Error(`Invalid
|
|
128
|
+
throw new Error(`Invalid prompting server configuration: ${error.message}`);
|
|
139
129
|
}
|
|
140
130
|
|
|
131
|
+
// Set the port in docker config
|
|
132
|
+
this.config.docker = { ...this.config.docker, port: value.port };
|
|
133
|
+
|
|
134
|
+
// Set the communication config (excluding port)
|
|
135
|
+
const { port, ...communicationConfig } = value;
|
|
141
136
|
this.config.communication = {
|
|
142
137
|
...this.config.communication,
|
|
143
138
|
directPrompting: {
|
|
144
139
|
enabled: true,
|
|
145
|
-
...
|
|
140
|
+
...communicationConfig
|
|
146
141
|
}
|
|
147
142
|
};
|
|
148
143
|
|
|
@@ -568,9 +563,9 @@ class DankAgent {
|
|
|
568
563
|
communication: Joi.object({
|
|
569
564
|
directPrompting: Joi.object({
|
|
570
565
|
enabled: Joi.boolean().default(false),
|
|
571
|
-
protocol: Joi.string().valid('websocket', 'tcp', 'http').default('
|
|
566
|
+
protocol: Joi.string().valid('websocket', 'tcp', 'http').default('http'),
|
|
572
567
|
authentication: Joi.boolean().default(false),
|
|
573
|
-
maxConnections: Joi.number().min(1).max(1000).default(
|
|
568
|
+
maxConnections: Joi.number().min(1).max(1000).default(50),
|
|
574
569
|
timeout: Joi.number().min(1000).default(30000)
|
|
575
570
|
}).default({ enabled: false }),
|
|
576
571
|
httpApi: Joi.object({
|
package/lib/cli/init.js
CHANGED
|
@@ -8,9 +8,54 @@ const chalk = require('chalk');
|
|
|
8
8
|
const { DankProject } = require('../project');
|
|
9
9
|
|
|
10
10
|
async function initCommand(projectName, options) {
|
|
11
|
-
|
|
11
|
+
let name = projectName;
|
|
12
|
+
let npmProjectName = projectName;
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
// If no project name provided, prompt for both directory name and npm project name
|
|
15
|
+
if (!name) {
|
|
16
|
+
const inquirer = await import('inquirer');
|
|
17
|
+
const answers = await inquirer.default.prompt([
|
|
18
|
+
{
|
|
19
|
+
type: 'input',
|
|
20
|
+
name: 'projectName',
|
|
21
|
+
message: 'What should the project directory be named?',
|
|
22
|
+
default: path.basename(process.cwd()),
|
|
23
|
+
validate: (input) => {
|
|
24
|
+
if (!input.trim()) {
|
|
25
|
+
return 'Project name is required';
|
|
26
|
+
}
|
|
27
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
|
|
28
|
+
return 'Project name can only contain letters, numbers, hyphens, and underscores';
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'input',
|
|
35
|
+
name: 'npmProjectName',
|
|
36
|
+
message: 'What should the npm package name be?',
|
|
37
|
+
default: (answers) => answers.projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-'),
|
|
38
|
+
validate: (input) => {
|
|
39
|
+
if (!input.trim()) {
|
|
40
|
+
return 'NPM project name is required';
|
|
41
|
+
}
|
|
42
|
+
if (!/^[a-z0-9-]+$/.test(input)) {
|
|
43
|
+
return 'NPM project name can only contain lowercase letters, numbers, and hyphens';
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
name = answers.projectName;
|
|
51
|
+
npmProjectName = answers.npmProjectName;
|
|
52
|
+
} else {
|
|
53
|
+
// If project name provided, use it for both directory and npm name
|
|
54
|
+
npmProjectName = name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log(chalk.yellow(`๐ Initializing Dank project: ${name}`));
|
|
58
|
+
console.log(chalk.cyan(`๐ฆ NPM package name: ${npmProjectName}\n`));
|
|
14
59
|
|
|
15
60
|
try {
|
|
16
61
|
// Create project instance
|
|
@@ -23,7 +68,7 @@ async function initCommand(projectName, options) {
|
|
|
23
68
|
await project.init();
|
|
24
69
|
|
|
25
70
|
// Create package.json
|
|
26
|
-
await createPackageJson(
|
|
71
|
+
await createPackageJson(npmProjectName, project.projectPath);
|
|
27
72
|
|
|
28
73
|
// Create .env.example file
|
|
29
74
|
await createEnvExample(project.projectPath);
|
|
@@ -51,11 +96,11 @@ async function initCommand(projectName, options) {
|
|
|
51
96
|
/**
|
|
52
97
|
* Create package.json for the new project
|
|
53
98
|
*/
|
|
54
|
-
async function createPackageJson(
|
|
99
|
+
async function createPackageJson(npmProjectName, projectPath) {
|
|
55
100
|
const packageJson = {
|
|
56
|
-
name:
|
|
101
|
+
name: npmProjectName,
|
|
57
102
|
version: '1.0.0',
|
|
58
|
-
description: `Dank AI agents for ${
|
|
103
|
+
description: `Dank AI agents for ${npmProjectName}`,
|
|
59
104
|
main: 'dank.config.js',
|
|
60
105
|
scripts: {
|
|
61
106
|
start: 'dank run',
|
|
@@ -67,7 +112,7 @@ async function createPackageJson(projectName, projectPath) {
|
|
|
67
112
|
clean: 'dank clean'
|
|
68
113
|
},
|
|
69
114
|
dependencies: {
|
|
70
|
-
'dank': '^1.0.0'
|
|
115
|
+
'dank-ai': '^1.0.0'
|
|
71
116
|
},
|
|
72
117
|
keywords: ['dank', 'ai', 'agents', 'automation', 'llm'],
|
|
73
118
|
author: '',
|