dank-ai 1.0.0
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 +1331 -0
- package/bin/dank +118 -0
- package/docker/Dockerfile +57 -0
- package/docker/entrypoint.js +1227 -0
- package/docker/package.json +19 -0
- package/lib/agent.js +644 -0
- package/lib/cli/build.js +43 -0
- package/lib/cli/clean.js +30 -0
- package/lib/cli/init.js +38 -0
- package/lib/cli/logs.js +122 -0
- package/lib/cli/run.js +176 -0
- package/lib/cli/status.js +125 -0
- package/lib/cli/stop.js +87 -0
- package/lib/config.js +180 -0
- package/lib/constants.js +58 -0
- package/lib/docker/manager.js +968 -0
- package/lib/index.js +26 -0
- package/lib/project.js +280 -0
- package/lib/tools/builtin.js +445 -0
- package/lib/tools/index.js +335 -0
- package/package.json +52 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dank Agent Service - Main Library Export
|
|
3
|
+
*
|
|
4
|
+
* This is the main entry point for the Dank library that users will import
|
|
5
|
+
* to define and configure their AI agents.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { DankAgent } = require('./agent');
|
|
9
|
+
const { DankProject } = require('./project');
|
|
10
|
+
const { AgentConfig } = require('./config');
|
|
11
|
+
const { SUPPORTED_LLMS, DEFAULT_CONFIG } = require('./constants');
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
// Main classes
|
|
15
|
+
DankAgent,
|
|
16
|
+
DankProject,
|
|
17
|
+
AgentConfig,
|
|
18
|
+
|
|
19
|
+
// Constants
|
|
20
|
+
SUPPORTED_LLMS,
|
|
21
|
+
DEFAULT_CONFIG,
|
|
22
|
+
|
|
23
|
+
// Convenience functions
|
|
24
|
+
createAgent: (name, config) => new DankAgent(name, config),
|
|
25
|
+
createProject: (name, options) => new DankProject(name, options)
|
|
26
|
+
};
|
package/lib/project.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DankProject - Project Management Class
|
|
3
|
+
*
|
|
4
|
+
* This class manages a collection of agents and provides
|
|
5
|
+
* project-level configuration and operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs-extra');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const yaml = require('js-yaml');
|
|
11
|
+
const { DankAgent } = require('./agent');
|
|
12
|
+
|
|
13
|
+
class DankProject {
|
|
14
|
+
constructor(name, options = {}) {
|
|
15
|
+
this.name = name;
|
|
16
|
+
this.options = {
|
|
17
|
+
configFile: 'dank.config.js',
|
|
18
|
+
agentsDir: 'agents',
|
|
19
|
+
outputDir: '.dank',
|
|
20
|
+
...options
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
this.agents = new Map();
|
|
24
|
+
this.projectPath = process.cwd();
|
|
25
|
+
this.configPath = path.join(this.projectPath, this.options.configFile);
|
|
26
|
+
this.createdAt = new Date().toISOString();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Add an agent to the project
|
|
31
|
+
*/
|
|
32
|
+
addAgent(agent) {
|
|
33
|
+
if (!(agent instanceof DankAgent)) {
|
|
34
|
+
throw new Error('Agent must be an instance of DankAgent');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (this.agents.has(agent.name)) {
|
|
38
|
+
throw new Error(`Agent with name '${agent.name}' already exists`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.agents.set(agent.name, agent);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Remove an agent from the project
|
|
47
|
+
*/
|
|
48
|
+
removeAgent(name) {
|
|
49
|
+
if (!this.agents.has(name)) {
|
|
50
|
+
throw new Error(`Agent '${name}' not found`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.agents.delete(name);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get an agent by name
|
|
59
|
+
*/
|
|
60
|
+
getAgent(name) {
|
|
61
|
+
return this.agents.get(name);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get all agents
|
|
66
|
+
*/
|
|
67
|
+
getAllAgents() {
|
|
68
|
+
return Array.from(this.agents.values());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Save project configuration to file
|
|
73
|
+
*/
|
|
74
|
+
async save() {
|
|
75
|
+
const config = this.toConfig();
|
|
76
|
+
|
|
77
|
+
// Ensure output directory exists
|
|
78
|
+
await fs.ensureDir(path.join(this.projectPath, this.options.outputDir));
|
|
79
|
+
|
|
80
|
+
// Save as YAML for readability
|
|
81
|
+
const yamlConfig = yaml.dump(config, {
|
|
82
|
+
indent: 2,
|
|
83
|
+
lineWidth: 120,
|
|
84
|
+
noCompatMode: true
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const configFile = path.join(this.projectPath, this.options.outputDir, 'project.yaml');
|
|
88
|
+
await fs.writeFile(configFile, yamlConfig, 'utf8');
|
|
89
|
+
|
|
90
|
+
console.log(`Project configuration saved to: ${configFile}`);
|
|
91
|
+
return configFile;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Load project configuration from file
|
|
96
|
+
*/
|
|
97
|
+
async load() {
|
|
98
|
+
const configFile = path.join(this.projectPath, this.options.outputDir, 'project.yaml');
|
|
99
|
+
|
|
100
|
+
if (!(await fs.pathExists(configFile))) {
|
|
101
|
+
throw new Error(`Project configuration not found: ${configFile}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const yamlContent = await fs.readFile(configFile, 'utf8');
|
|
105
|
+
const config = yaml.load(yamlContent);
|
|
106
|
+
|
|
107
|
+
return this.fromConfig(config);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Initialize a new project structure
|
|
112
|
+
*/
|
|
113
|
+
async init() {
|
|
114
|
+
const projectDir = this.projectPath;
|
|
115
|
+
|
|
116
|
+
// Create directory structure
|
|
117
|
+
await fs.ensureDir(path.join(projectDir, this.options.agentsDir));
|
|
118
|
+
await fs.ensureDir(path.join(projectDir, this.options.outputDir));
|
|
119
|
+
|
|
120
|
+
// Create example config file
|
|
121
|
+
const exampleConfig = this._generateExampleConfig();
|
|
122
|
+
const configPath = path.join(projectDir, this.options.configFile);
|
|
123
|
+
|
|
124
|
+
if (!(await fs.pathExists(configPath))) {
|
|
125
|
+
await fs.writeFile(configPath, exampleConfig, 'utf8');
|
|
126
|
+
console.log(`Created example configuration: ${configPath}`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Create example agent
|
|
130
|
+
const exampleAgent = this._generateExampleAgent();
|
|
131
|
+
const agentPath = path.join(projectDir, this.options.agentsDir, 'example-agent.js');
|
|
132
|
+
|
|
133
|
+
if (!(await fs.pathExists(agentPath))) {
|
|
134
|
+
await fs.writeFile(agentPath, exampleAgent, 'utf8');
|
|
135
|
+
console.log(`Created example agent: ${agentPath}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(`\\nDank project '${this.name}' initialized!`);
|
|
139
|
+
console.log(`\\nNext steps:`);
|
|
140
|
+
console.log(`1. Edit ${this.options.configFile} to configure your agents`);
|
|
141
|
+
console.log(`2. Run 'dank run' to start your agents`);
|
|
142
|
+
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Convert project to configuration object
|
|
148
|
+
*/
|
|
149
|
+
toConfig() {
|
|
150
|
+
return {
|
|
151
|
+
name: this.name,
|
|
152
|
+
version: '1.0.0',
|
|
153
|
+
createdAt: this.createdAt,
|
|
154
|
+
options: this.options,
|
|
155
|
+
agents: Object.fromEntries(
|
|
156
|
+
Array.from(this.agents.entries()).map(([name, agent]) => [
|
|
157
|
+
name,
|
|
158
|
+
agent.toConfig()
|
|
159
|
+
])
|
|
160
|
+
)
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Create project from configuration object
|
|
166
|
+
*/
|
|
167
|
+
fromConfig(config) {
|
|
168
|
+
this.name = config.name;
|
|
169
|
+
this.createdAt = config.createdAt;
|
|
170
|
+
this.options = { ...this.options, ...config.options };
|
|
171
|
+
|
|
172
|
+
// Restore agents
|
|
173
|
+
this.agents.clear();
|
|
174
|
+
if (config.agents) {
|
|
175
|
+
Object.entries(config.agents).forEach(([name, agentConfig]) => {
|
|
176
|
+
const agent = DankAgent.fromConfig(agentConfig);
|
|
177
|
+
this.agents.set(name, agent);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Generate example configuration file
|
|
186
|
+
*/
|
|
187
|
+
_generateExampleConfig() {
|
|
188
|
+
// Detect if we're in development mode (inside the dank repo)
|
|
189
|
+
const isDevelopment = this.projectPath.includes('/dank') &&
|
|
190
|
+
fs.existsSync(path.join(this.projectPath, '../lib/index.js'));
|
|
191
|
+
|
|
192
|
+
const requirePath = isDevelopment ? '../lib/index.js' : 'dank';
|
|
193
|
+
|
|
194
|
+
return `/**
|
|
195
|
+
* Dank Agent Configuration
|
|
196
|
+
*
|
|
197
|
+
* This file defines your AI agents and their configurations.
|
|
198
|
+
* Run 'dank run' to start all defined agents.
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
const { createAgent } = require('${requirePath}');
|
|
202
|
+
|
|
203
|
+
module.exports = {
|
|
204
|
+
// Project configuration
|
|
205
|
+
name: '${this.name}',
|
|
206
|
+
|
|
207
|
+
// Define your agents
|
|
208
|
+
agents: [
|
|
209
|
+
createAgent('example-agent')
|
|
210
|
+
.setLLM('openai', {
|
|
211
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
212
|
+
model: 'gpt-3.5-turbo',
|
|
213
|
+
temperature: 0.7
|
|
214
|
+
})
|
|
215
|
+
.setPrompt('You are a helpful assistant that responds with enthusiasm!')
|
|
216
|
+
.setResources({
|
|
217
|
+
memory: '512m',
|
|
218
|
+
cpu: 1
|
|
219
|
+
})
|
|
220
|
+
.addHandler('output', (data) => {
|
|
221
|
+
console.log('Agent output:', data);
|
|
222
|
+
})
|
|
223
|
+
.addHandler('error', (error) => {
|
|
224
|
+
console.error('Agent error:', error);
|
|
225
|
+
})
|
|
226
|
+
]
|
|
227
|
+
};
|
|
228
|
+
`;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Generate example agent file
|
|
233
|
+
*/
|
|
234
|
+
_generateExampleAgent() {
|
|
235
|
+
return `/**
|
|
236
|
+
* Example Dank Agent
|
|
237
|
+
*
|
|
238
|
+
* This is an example of how to define a Dank agent.
|
|
239
|
+
* You can create multiple agent files and import them in your config.
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
const { createAgent } = require('dank');
|
|
243
|
+
|
|
244
|
+
const exampleAgent = createAgent('example-agent')
|
|
245
|
+
.setLLM('openai', {
|
|
246
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
247
|
+
model: 'gpt-3.5-turbo'
|
|
248
|
+
})
|
|
249
|
+
.setPrompt(\`
|
|
250
|
+
You are a helpful AI assistant with the following capabilities:
|
|
251
|
+
- Answer questions clearly and concisely
|
|
252
|
+
- Provide code examples when appropriate
|
|
253
|
+
- Be friendly and professional
|
|
254
|
+
\`)
|
|
255
|
+
.setResources({
|
|
256
|
+
memory: '512m',
|
|
257
|
+
cpu: 1,
|
|
258
|
+
timeout: 30000
|
|
259
|
+
})
|
|
260
|
+
.addHandlers({
|
|
261
|
+
output: (data) => {
|
|
262
|
+
console.log(\`[\${new Date().toISOString()}] Agent output:\`, data);
|
|
263
|
+
},
|
|
264
|
+
error: (error) => {
|
|
265
|
+
console.error(\`[\${new Date().toISOString()}] Agent error:\`, error);
|
|
266
|
+
},
|
|
267
|
+
start: () => {
|
|
268
|
+
console.log('Agent started successfully');
|
|
269
|
+
},
|
|
270
|
+
stop: () => {
|
|
271
|
+
console.log('Agent stopped');
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
module.exports = exampleAgent;
|
|
276
|
+
`;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = { DankProject };
|