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 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
- this.id = this._generateId();
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,
@@ -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',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dank-ai",
3
- "version": "1.0.36",
3
+ "version": "1.0.38",
4
4
  "description": "Dank Agent Service - Docker-based AI agent orchestration platform",
5
5
  "main": "lib/index.js",
6
6
  "exports": {