dank-ai 1.0.36 → 1.0.38
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/lib/agent.js +82 -7
- package/lib/cli/init.js +16 -0
- package/lib/cli/production-build.js +10 -0
- package/lib/config.js +9 -0
- package/lib/docker/manager.js +11 -0
- package/lib/project.js +20 -0
- package/package.json +1 -1
package/lib/agent.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const Joi = require('joi');
|
|
9
|
+
const { validate: validateUUID } = require('uuid');
|
|
9
10
|
const { DEFAULT_CONFIG, SUPPORTED_LLMS, DOCKER_CONFIG, INSTANCE_TYPES } = require('./constants');
|
|
10
11
|
const { ToolRegistry, ToolExecutor } = require('./tools');
|
|
11
12
|
const builtinTools = require('./tools/builtin');
|
|
@@ -15,7 +16,8 @@ class DankAgent {
|
|
|
15
16
|
this.name = name;
|
|
16
17
|
this.config = this._validateConfig(config);
|
|
17
18
|
this.handlers = new Map();
|
|
18
|
-
|
|
19
|
+
// id is optional during construction - must be set via setId() before use
|
|
20
|
+
this.id = this.config.id || null;
|
|
19
21
|
this.status = 'defined'; // defined, building, running, stopped, error
|
|
20
22
|
this.containerId = null;
|
|
21
23
|
this.createdAt = new Date().toISOString();
|
|
@@ -51,6 +53,33 @@ class DankAgent {
|
|
|
51
53
|
return this;
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Set the unique ID for this agent (required, must be UUIDv4)
|
|
58
|
+
* @param {string} id - UUIDv4 string that must be unique and never used before
|
|
59
|
+
*/
|
|
60
|
+
setId(id) {
|
|
61
|
+
if (!id || typeof id !== 'string') {
|
|
62
|
+
throw new Error('Agent ID must be a non-empty string');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const trimmedId = id.trim();
|
|
66
|
+
|
|
67
|
+
// Validate UUIDv4 format
|
|
68
|
+
if (!validateUUID(trimmedId)) {
|
|
69
|
+
throw new Error(`Agent ID must be a valid UUIDv4. Received: ${trimmedId}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check if it's actually v4 (UUIDv4 has '4' in the version position)
|
|
73
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
74
|
+
if (!uuidRegex.test(trimmedId)) {
|
|
75
|
+
throw new Error(`Agent ID must be a valid UUIDv4. Received: ${trimmedId}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.config.id = trimmedId;
|
|
79
|
+
this.id = trimmedId;
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
54
83
|
/**
|
|
55
84
|
* Set the system prompt for the agent
|
|
56
85
|
*/
|
|
@@ -535,11 +564,39 @@ class DankAgent {
|
|
|
535
564
|
return this;
|
|
536
565
|
}
|
|
537
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Validate that agent ID is set (required for all operations)
|
|
569
|
+
* @private
|
|
570
|
+
*/
|
|
571
|
+
_validateId() {
|
|
572
|
+
if (!this.id || !this.config.id) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
`Agent ID is required for agent "${this.name}". ` +
|
|
575
|
+
`Use .setId(uuidv4) to set a unique UUIDv4 identifier. ` +
|
|
576
|
+
`Example: createAgent('${this.name}').setId(require('uuid').v4())`
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Validate UUIDv4 format
|
|
581
|
+
const trimmedId = this.id.trim();
|
|
582
|
+
if (!validateUUID(trimmedId)) {
|
|
583
|
+
throw new Error(`Agent ID must be a valid UUIDv4 for agent "${this.name}". Received: ${trimmedId}`);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
587
|
+
if (!uuidRegex.test(trimmedId)) {
|
|
588
|
+
throw new Error(`Agent ID must be a valid UUIDv4 for agent "${this.name}". Received: ${trimmedId}`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
538
592
|
/**
|
|
539
593
|
* Finalize agent configuration by auto-detecting features
|
|
540
594
|
* This should be called before the agent is deployed
|
|
541
595
|
*/
|
|
542
596
|
finalize() {
|
|
597
|
+
// Validate that ID is set before finalization (REQUIRED)
|
|
598
|
+
this._validateId();
|
|
599
|
+
|
|
543
600
|
this._autoDetectFeatures();
|
|
544
601
|
return this;
|
|
545
602
|
}
|
|
@@ -578,6 +635,9 @@ class DankAgent {
|
|
|
578
635
|
* Get the complete agent configuration for serialization
|
|
579
636
|
*/
|
|
580
637
|
toConfig() {
|
|
638
|
+
// Validate ID before serialization
|
|
639
|
+
this._validateId();
|
|
640
|
+
|
|
581
641
|
return {
|
|
582
642
|
name: this.name,
|
|
583
643
|
id: this.id,
|
|
@@ -611,7 +671,28 @@ class DankAgent {
|
|
|
611
671
|
* Validate agent configuration
|
|
612
672
|
*/
|
|
613
673
|
_validateConfig(config) {
|
|
674
|
+
// ID is optional during construction - will be validated when setId() is called
|
|
675
|
+
// or when the agent is finalized/used
|
|
676
|
+
if (config.id) {
|
|
677
|
+
if (typeof config.id !== 'string') {
|
|
678
|
+
throw new Error('Agent ID must be a string');
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
const trimmedId = config.id.trim();
|
|
682
|
+
if (!validateUUID(trimmedId)) {
|
|
683
|
+
throw new Error(`Agent ID must be a valid UUIDv4. Received: ${trimmedId}`);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// Check if it's actually v4 (UUIDv4 has '4' in the version position)
|
|
687
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
688
|
+
if (!uuidRegex.test(trimmedId)) {
|
|
689
|
+
throw new Error(`Agent ID must be a valid UUIDv4. Received: ${trimmedId}`);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
614
693
|
const schema = Joi.object({
|
|
694
|
+
id: Joi.string().optional(), // Optional during construction, required via setId()
|
|
695
|
+
|
|
615
696
|
llm: Joi.object({
|
|
616
697
|
provider: Joi.string().valid(...SUPPORTED_LLMS).required(),
|
|
617
698
|
apiKey: Joi.string().allow('').default(''),
|
|
@@ -686,12 +767,6 @@ class DankAgent {
|
|
|
686
767
|
return value;
|
|
687
768
|
}
|
|
688
769
|
|
|
689
|
-
/**
|
|
690
|
-
* Generate a unique ID
|
|
691
|
-
*/
|
|
692
|
-
_generateId() {
|
|
693
|
-
return `agent_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
694
|
-
}
|
|
695
770
|
|
|
696
771
|
/**
|
|
697
772
|
* Serialize handlers for storage (functions can't be serialized)
|
package/lib/cli/init.js
CHANGED
|
@@ -93,6 +93,11 @@ async function initCommand(projectName, options) {
|
|
|
93
93
|
console.log(chalk.gray(' 2. Run "npm install" to install dependencies'));
|
|
94
94
|
console.log(chalk.gray(' 3. Edit dank.config.js to configure your agents'));
|
|
95
95
|
console.log(chalk.gray(' 4. Run "dank run" to start your agents'));
|
|
96
|
+
console.log(chalk.yellow('\n📝 Note about Agent IDs:'));
|
|
97
|
+
console.log(chalk.gray(' - Unique UUIDv4 IDs have been generated for each agent'));
|
|
98
|
+
console.log(chalk.gray(' - These IDs are stored in dank.config.js as AGENT_IDS constants'));
|
|
99
|
+
console.log(chalk.gray(' - Once agents register with Dank Cloud, these IDs become locked to your account'));
|
|
100
|
+
console.log(chalk.gray(' - You can generate new UUIDs if needed: require(\'uuid\').v4()'));
|
|
96
101
|
console.log(chalk.gray('\nFor more information, visit: https://github.com/your-org/dank'));
|
|
97
102
|
|
|
98
103
|
process.exit(0);
|
|
@@ -334,6 +339,16 @@ Handle agent lifecycle and errors:
|
|
|
334
339
|
})
|
|
335
340
|
\`\`\`
|
|
336
341
|
|
|
342
|
+
## Agent IDs (UUIDv4)
|
|
343
|
+
|
|
344
|
+
Each agent in your project has a unique UUIDv4 identifier that is automatically generated when you initialize your project. These IDs are stored in \`dank.config.js\` as constants in the \`AGENT_IDS\` object.
|
|
345
|
+
|
|
346
|
+
**Important Notes:**
|
|
347
|
+
- Agent IDs are generated automatically during project initialization
|
|
348
|
+
- These IDs uniquely identify your agents across deployments
|
|
349
|
+
- Once agents register with Dank Cloud services, these IDs become locked to your account
|
|
350
|
+
- You can generate new UUIDs if needed: \`require('uuid').v4()\`
|
|
351
|
+
|
|
337
352
|
## Configuration
|
|
338
353
|
|
|
339
354
|
Edit \`dank.config.js\` to:
|
|
@@ -343,6 +358,7 @@ Edit \`dank.config.js\` to:
|
|
|
343
358
|
- Configure event handlers
|
|
344
359
|
- Set Docker and resource limits
|
|
345
360
|
- Enable/disable communication features
|
|
361
|
+
- Manage agent IDs (UUIDv4 identifiers)
|
|
346
362
|
|
|
347
363
|
## Documentation
|
|
348
364
|
|
|
@@ -12,6 +12,15 @@ const analytics = require('../analytics');
|
|
|
12
12
|
* Extract deployment metadata from an agent configuration
|
|
13
13
|
*/
|
|
14
14
|
function extractAgentMetadata(agent, buildOptions, imageName) {
|
|
15
|
+
// Validate that agent ID is set (required)
|
|
16
|
+
if (!agent.id || !agent.config?.id) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Agent ID is required for agent "${agent.name}". ` +
|
|
19
|
+
`Use .setId(uuidv4) to set a unique UUIDv4 identifier. ` +
|
|
20
|
+
`Example: createAgent('${agent.name}').setId(require('uuid').v4())`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
const config = agent.config || {};
|
|
16
25
|
const dockerConfig = config.docker || {};
|
|
17
26
|
const communication = config.communication || {};
|
|
@@ -91,6 +100,7 @@ function extractAgentMetadata(agent, buildOptions, imageName) {
|
|
|
91
100
|
};
|
|
92
101
|
|
|
93
102
|
return {
|
|
103
|
+
id: agent.id, // Agent UUIDv4 identifier from setId()
|
|
94
104
|
name: agent.name,
|
|
95
105
|
imageName: imageName,
|
|
96
106
|
baseImage: {
|
package/lib/config.js
CHANGED
|
@@ -120,6 +120,15 @@ class AgentConfig {
|
|
|
120
120
|
* Generate environment variables for agent container
|
|
121
121
|
*/
|
|
122
122
|
static generateContainerEnv(agent) {
|
|
123
|
+
// Validate that agent ID is set (required)
|
|
124
|
+
if (!agent.id || !agent.config?.id) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
`Agent ID is required for agent "${agent.name}". ` +
|
|
127
|
+
`Use .setId(uuidv4) to set a unique UUIDv4 identifier. ` +
|
|
128
|
+
`Example: createAgent('${agent.name}').setId(require('uuid').v4())`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
123
132
|
const env = {
|
|
124
133
|
AGENT_NAME: agent.name,
|
|
125
134
|
AGENT_ID: agent.id,
|
package/lib/docker/manager.js
CHANGED
|
@@ -1399,9 +1399,20 @@ class DockerManager {
|
|
|
1399
1399
|
});
|
|
1400
1400
|
|
|
1401
1401
|
// Finalize agent configuration (auto-detect features)
|
|
1402
|
+
// This will validate that agent.id is set (required)
|
|
1402
1403
|
agent.finalize();
|
|
1403
1404
|
|
|
1404
1405
|
const imageName = `dank-agent-${agent.name.toLowerCase()}`;
|
|
1406
|
+
|
|
1407
|
+
// Ensure agent.id is set (should be validated by finalize(), but double-check for safety)
|
|
1408
|
+
if (!agent.id) {
|
|
1409
|
+
throw new Error(
|
|
1410
|
+
`Agent ID is required for agent "${agent.name}". ` +
|
|
1411
|
+
`Use .setId(uuidv4) to set a unique UUIDv4 identifier. ` +
|
|
1412
|
+
`Example: createAgent('${agent.name}').setId(require('uuid').v4())`
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1405
1416
|
const containerName = `dank-${agent.name.toLowerCase()}-${agent.id
|
|
1406
1417
|
.split("_")
|
|
1407
1418
|
.pop()}`;
|
package/lib/project.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const fs = require('fs-extra');
|
|
8
8
|
const path = require('path');
|
|
9
|
+
const { v4: uuidv4 } = require('uuid');
|
|
9
10
|
|
|
10
11
|
class DankProject {
|
|
11
12
|
constructor(name, options = {}) {
|
|
@@ -56,15 +57,33 @@ class DankProject {
|
|
|
56
57
|
|
|
57
58
|
const requirePath = isDevelopment ? '../lib/index.js' : 'dank-ai';
|
|
58
59
|
|
|
60
|
+
// Generate UUIDv4 IDs for each agent in the template
|
|
61
|
+
const promptAgentId = uuidv4();
|
|
62
|
+
|
|
59
63
|
return `/**
|
|
60
64
|
* Dank Agent Configuration
|
|
61
65
|
*
|
|
62
66
|
* This file defines your AI agents and their configurations.
|
|
63
67
|
* Run 'dank run' to start all defined agents.
|
|
68
|
+
*
|
|
69
|
+
* IMPORTANT: Agent IDs (UUIDv4)
|
|
70
|
+
* ==============================
|
|
71
|
+
* Each agent has a unique UUIDv4 identifier that is generated when you initialize
|
|
72
|
+
* your project. These IDs are used to identify and track your agents.
|
|
73
|
+
*
|
|
74
|
+
* - You can generate new UUIDv4s if needed (use: require('uuid').v4())
|
|
75
|
+
* - Once agents register with Dank Cloud services using these IDs, they become
|
|
76
|
+
* locked in and owned by your account
|
|
64
77
|
*/
|
|
65
78
|
|
|
66
79
|
const { createAgent } = require('${requirePath}');
|
|
67
80
|
|
|
81
|
+
// Agent IDs - Generated UUIDv4 identifiers for each agent
|
|
82
|
+
// These IDs are used to uniquely identify your agents across deployments
|
|
83
|
+
const AGENT_IDS = {
|
|
84
|
+
PROMPT_AGENT: '${promptAgentId}'
|
|
85
|
+
};
|
|
86
|
+
|
|
68
87
|
module.exports = {
|
|
69
88
|
// Project configuration
|
|
70
89
|
name: '${this.name}',
|
|
@@ -74,6 +93,7 @@ module.exports = {
|
|
|
74
93
|
agents: [
|
|
75
94
|
// Example 1: Direct Prompting Agent with Event Handlers
|
|
76
95
|
createAgent('prompt-agent')
|
|
96
|
+
.setId(AGENT_IDS.PROMPT_AGENT) // Required: Unique UUIDv4 identifier
|
|
77
97
|
.setLLM('openai', {
|
|
78
98
|
apiKey: process.env.OPENAI_API_KEY,
|
|
79
99
|
model: 'gpt-3.5-turbo',
|