@j-o-r/hello-dave 0.0.9 → 0.1.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.
Files changed (82) hide show
  1. package/README.md +2 -0
  2. package/README.md.bak.1779452127 +240 -0
  3. package/TODO.md +31 -20
  4. package/agents/code_agent.js +6 -6
  5. package/agents/daisy_agent.js +10 -7
  6. package/agents/minimax.js +173 -0
  7. package/agents/spawn_agent.js +33 -10
  8. package/agents/stability.js +173 -0
  9. package/bin/codeDave +1 -1
  10. package/bin/dave.js +1 -1
  11. package/docs/dependencies.md +7 -0
  12. package/docs/music-toolsets.md +137 -0
  13. package/docs/plans/minimax-music-generation.md +80 -0
  14. package/docs/plans/unified-agent-architecture.md +146 -0
  15. package/docs/plans/websocket-streaming-plan.md.bak +317 -0
  16. package/docs/prompt/spawn_agent.md +46 -44
  17. package/docs/prompt/task_clarification_and_documentation.md +35 -0
  18. package/docs/todo-archive-infra-2026-04-21.md +15 -0
  19. package/docs/todo-archive-v0.1.0.md +32 -0
  20. package/lib/API/minimax/ImageToolset.js +169 -0
  21. package/lib/API/minimax/MusicToolset.js +290 -0
  22. package/lib/API/minimax/VideoToolset.js +296 -0
  23. package/lib/API/minimax/image.generation.md +239 -0
  24. package/lib/API/minimax/image.js +219 -0
  25. package/lib/API/minimax/image.to.image.md +257 -0
  26. package/lib/API/minimax/index.js +16 -0
  27. package/lib/API/minimax/music.cover.preprocess.md +206 -0
  28. package/lib/API/minimax/music.generation.md +346 -0
  29. package/lib/API/minimax/music.js +257 -0
  30. package/lib/API/minimax/music.lyrics.generation.md +205 -0
  31. package/lib/API/minimax/video.download.md +133 -0
  32. package/lib/API/minimax/video.first.last.image.md +186 -0
  33. package/lib/API/minimax/video.from.image.md +206 -0
  34. package/lib/API/minimax/video.from.subject.md +164 -0
  35. package/lib/API/minimax/video.generation.md +192 -0
  36. package/lib/API/minimax/video.js +339 -0
  37. package/lib/API/minimax/video.query.md +128 -0
  38. package/lib/API/stability.ai/ImageToolset.js +357 -0
  39. package/lib/API/stability.ai/MusicToolset.js +302 -0
  40. package/lib/API/stability.ai/audio-3.md +205 -0
  41. package/lib/API/stability.ai/audio.js +679 -0
  42. package/lib/API/stability.ai/image.js +911 -0
  43. package/lib/API/stability.ai/image.md +271 -0
  44. package/lib/API/stability.ai/index.js +11 -0
  45. package/lib/API/stability.ai/openapi.json +17118 -0
  46. package/lib/API/x.ai/ImageToolset.js +165 -0
  47. package/lib/API/x.ai/image.editing.md +86 -0
  48. package/lib/API/x.ai/image.js +393 -0
  49. package/lib/API/x.ai/image.md +213 -0
  50. package/lib/API/x.ai/image.to.generation.md +494 -0
  51. package/lib/API/x.ai/image.to.video.md +23 -0
  52. package/lib/API/x.ai/index.js +9 -0
  53. package/lib/AgentManager.js +1 -1
  54. package/lib/CdnToolset.js +191 -0
  55. package/lib/ToolSet.js +19 -1
  56. package/lib/cdn.js +373 -0
  57. package/lib/fafs.js +5 -3
  58. package/lib/genericToolset.js +75 -210
  59. package/lib/index.js +9 -1
  60. package/package.json +2 -2
  61. package/types/API/minimax/ImageToolset.d.ts +3 -0
  62. package/types/API/minimax/MusicToolset.d.ts +3 -0
  63. package/types/API/minimax/VideoToolset.d.ts +3 -0
  64. package/types/API/minimax/image.d.ts +109 -0
  65. package/types/API/minimax/index.d.ts +15 -0
  66. package/types/API/minimax/music.d.ts +46 -0
  67. package/types/API/minimax/video.d.ts +165 -0
  68. package/types/API/stability.ai/ImageToolset.d.ts +3 -0
  69. package/types/API/stability.ai/MusicToolset.d.ts +3 -0
  70. package/types/API/stability.ai/audio.d.ts +193 -0
  71. package/types/API/stability.ai/image.d.ts +274 -0
  72. package/types/API/stability.ai/index.d.ts +11 -0
  73. package/types/API/x.ai/ImageToolset.d.ts +3 -0
  74. package/types/API/x.ai/image.d.ts +82 -0
  75. package/types/API/x.ai/index.d.ts +9 -0
  76. package/types/AgentManager.d.ts +1 -1
  77. package/types/CdnToolset.d.ts +20 -0
  78. package/types/ToolSet.d.ts +8 -0
  79. package/types/cdn.d.ts +141 -0
  80. package/types/index.d.ts +8 -2
  81. package/utils/syntax_check.sh +59 -15
  82. package/docs/multi-agent-clusters.md.bak +0 -229
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Generates one or more images from a text prompt using Grok Imagine.
3
+ *
4
+ * @async
5
+ * @function generateImage
6
+ * @param {string} prompt - Detailed text prompt describing the desired image.
7
+ * @param {Object} [options={}] - Optional generation parameters.
8
+ * @param {string} [options.model='grok-imagine-image-quality'] - Model to use.
9
+ * @param {number} [options.n=1] - Number of images to generate (1–10).
10
+ * @param {string} [options.response_format='url'] - `'url'` or `'b64_json'`.
11
+ * @returns {Promise<Object>} Result containing `local_path`, `url` (or `base64`), and metadata.
12
+ * @throws {Error} On missing prompt or API errors.
13
+ *
14
+ * @example
15
+ * const result = await generateImage("A futuristic city at night");
16
+ * console.log(result.local_path);
17
+ */
18
+ export function generateImage(prompt: string, options?: {
19
+ model?: string | undefined;
20
+ n?: number | undefined;
21
+ response_format?: string | undefined;
22
+ }): Promise<Object>;
23
+ /**
24
+ * Edits one or more images using a natural language prompt.
25
+ * Supports up to 3 reference images for compositing, style transfer, or multi-subject scenes.
26
+ *
27
+ * @async
28
+ * @function editImage
29
+ * @param {string} prompt - Description of the desired edit.
30
+ * @param {string|Buffer|Blob|Array<string|Buffer|Blob>} imageInputs - One or more images (URL, path, base64, Buffer, or Blob).
31
+ * @param {Object} [options={}] - Optional parameters.
32
+ * @param {string} [options.model='grok-imagine-image-quality']
33
+ * @param {number} [options.n=1]
34
+ * @param {string} [options.response_format='url']
35
+ * @returns {Promise<Object>} Result with edited image.
36
+ * @throws {Error} If more than 3 images are provided or on API error.
37
+ *
38
+ * @example
39
+ * // Single image edit
40
+ * const result = await editImage("Make this a pencil sketch", "./photo.png");
41
+ *
42
+ * @example
43
+ * // Multi-image editing (up to 3)
44
+ * const result = await editImage(
45
+ * "Combine these two people into one scene",
46
+ * ["./person1.png", "./person2.png"]
47
+ * );
48
+ */
49
+ export function editImage(prompt: string, imageInputs: string | Buffer | Blob | Array<string | Buffer | Blob>, options?: {
50
+ model?: string | undefined;
51
+ n?: number | undefined;
52
+ response_format?: string | undefined;
53
+ }): Promise<Object>;
54
+ /**
55
+ * Generates a video from a still image and text prompt.
56
+ * This function is fully automatic — it submits the request and polls internally
57
+ * until the video is ready before returning.
58
+ *
59
+ * @async
60
+ * @function generateVideo
61
+ * @param {string} prompt - Description of the desired motion or animation.
62
+ * @param {string|Buffer|Blob} imageInput - Source image (URL, path, base64, Buffer, or Blob).
63
+ * @param {Object} [options={}] - Optional video parameters.
64
+ * @param {number} [options.duration=8] - Video duration in seconds.
65
+ * @param {string} [options.aspect_ratio='16:9'] - Aspect ratio.
66
+ * @param {string} [options.resolution='720p'] - Output resolution.
67
+ * @returns {Promise<Object>} Result containing `local_path` and `url` of the generated video.
68
+ * @throws {Error} On missing inputs or generation failure.
69
+ *
70
+ * @example
71
+ * const result = await generateVideo(
72
+ * "Make the water crash down and slowly pan out",
73
+ * "https://example.com/waterfall.png",
74
+ * { duration: 12 }
75
+ * );
76
+ * console.log(result.local_path);
77
+ */
78
+ export function generateVideo(prompt: string, imageInput: string | Buffer | Blob, options?: {
79
+ duration?: number | undefined;
80
+ aspect_ratio?: string | undefined;
81
+ resolution?: string | undefined;
82
+ }): Promise<Object>;
@@ -0,0 +1,9 @@
1
+ declare namespace _default {
2
+ export let music: any;
3
+ export let musicToolset: any;
4
+ export { image };
5
+ export { imageToolset };
6
+ }
7
+ export default _default;
8
+ import * as image from './image.js';
9
+ import imageToolset from './ImageToolset.js';
@@ -75,7 +75,7 @@ declare class AgentManager {
75
75
  /** @returns {Promise&lt;import('./fafs.js').EnvironmentInfo&gt;} System env info. */
76
76
  environment(): Promise<any> & lt;
77
77
  /**
78
- * Adds a pre-defined generic tool from toolsPool to this agent's ToolSet.
78
+ * Adds a pre-defined generic tool from toolsPool (genericToolset) to this agent's ToolSet.
79
79
  * @param {'execute_bash_script'|'execute_remote_script'|'get_user_env'|'history_search'|'javascript_interpreter'|'memory_recall'|'memory_write'|'open_link'|'read_file'|'send_email'|'syntax_check'|'write_file'} name - Tool name.
80
80
  * @throws {Error} Invalid name, no toolset, or tool missing.
81
81
  * @example mgr.addGenericToolcall('read_file');
@@ -0,0 +1,20 @@
1
+ export default tools;
2
+ /**
3
+ * @module lib/CdnToolset
4
+ * Dedicated ToolSet for CDN / remote public file publishing.
5
+ *
6
+ * Contains only the tools related to publishing files to a remote web server
7
+ * via SSH/SCP (defined by SSH_EP environment variable).
8
+ *
9
+ * This allows clean separation: generic tools + CDN tools + domain-specific toolsets.
10
+ *
11
+ * Usage:
12
+ * import cdnTools from './CdnToolset.js';
13
+ * myToolset.borrow(cdnTools);
14
+ *
15
+ * Or use directly:
16
+ * import cdnTools from './CdnToolset.js';
17
+ * await cdnTools.call('listProjects');
18
+ */
19
+ declare const tools: ToolSet;
20
+ import { ToolSet } from './index.js';
@@ -88,6 +88,14 @@ declare class ToolSet {
88
88
  * @returns {TSToolListItem[]} Array of tool summaries, sorted by name
89
89
  */
90
90
  list(): TSToolListItem[];
91
+ /**
92
+ * Borrows/copies all registered tools (function_calls) from another ToolSet into this one.
93
+ * Overwrites if a tool with the same name already exists in this ToolSet.
94
+ * Uses only public API for compatibility.
95
+ * @param {ToolSet} sourceToolSet - The ToolSet instance to borrow tools from (e.g. musicToolset)
96
+ * @returns {ToolSet} Returns this instance to allow chaining
97
+ */
98
+ borrow(sourceToolSet: ToolSet): ToolSet;
91
99
  /**
92
100
  * Getter for the current tool choice setting.
93
101
  * @returns {string} The tool choice: 'auto', 'none', or 'required'
package/types/cdn.d.ts ADDED
@@ -0,0 +1,141 @@
1
+ declare namespace _default {
2
+ export { getSshConfig };
3
+ export { ensureRemoteDir };
4
+ export { ensureProjectStructure };
5
+ export { listProjects };
6
+ export { deleteProject };
7
+ export { publishFile };
8
+ export { publishToProject };
9
+ }
10
+ export default _default;
11
+ /**
12
+ * Parse and validate the SSH_EP environment variable.
13
+ *
14
+ * Supports both `ssh://user@host:port` and `user@host:port` formats.
15
+ *
16
+ * @returns {{user: string, host: string, port: number, raw: string}}
17
+ * Parsed SSH connection details.
18
+ *
19
+ * @throws {Error} If SSH_EP is missing or has an invalid format.
20
+ *
21
+ * @example
22
+ * // Required environment variable:
23
+ * // export SSH_EP='ssh://jorrit@drive.duin.xyz:4301'
24
+ */
25
+ export function getSshConfig(): {
26
+ user: string;
27
+ host: string;
28
+ port: number;
29
+ raw: string;
30
+ };
31
+ /**
32
+ * Ensure a remote directory exists under `htdocs/`.
33
+ * Creates all parent directories as needed (`mkdir -p`).
34
+ *
35
+ * @param {string} remoteRelativeDir - Relative path under htdocs (e.g. "tmp/cdn-demo-123" or "projects/my-project")
36
+ * @returns {Promise<string>} The full remote directory path (e.g. "htdocs/tmp/cdn-demo-123")
37
+ */
38
+ export function ensureRemoteDir(remoteRelativeDir: string): Promise<string>;
39
+ /**
40
+ * Ensure the remote project directory structure exists.
41
+ * Creates `htdocs/projects/<slug>` (and the `generated` subfolder).
42
+ *
43
+ * @param {string} projectSlug - Project identifier (will be sanitized)
44
+ * @returns {Promise<string>} The remote directory path under htdocs
45
+ */
46
+ export function ensureProjectStructure(projectSlug: string): Promise<string>;
47
+ /**
48
+ * List all existing projects on the remote server.
49
+ *
50
+ * Scans the `htdocs/projects/` directory and returns metadata for each project.
51
+ * Useful when starting without prior context about what has already been published.
52
+ *
53
+ * @returns {Promise<Array<{slug: string, url: string, fileCount: number, created?: string}>>}
54
+ * Array of project objects.
55
+ *
56
+ * @throws {Error} If the SSH connection or directory listing fails.
57
+ *
58
+ * @example
59
+ * const projects = await cdn.listProjects();
60
+ * console.log(projects[0].url); // https://drive.duin.xyz/projects/my-project/
61
+ */
62
+ export function listProjects(): Promise<Array<{
63
+ slug: string;
64
+ url: string;
65
+ fileCount: number;
66
+ created?: string;
67
+ }>>;
68
+ /**
69
+ * Delete an entire project folder from the remote server.
70
+ *
71
+ * Permanently removes `htdocs/projects/<slug>` and all its contents.
72
+ * Use with caution — this operation cannot be undone.
73
+ *
74
+ * @param {string} projectSlug - Project identifier (will be sanitized to kebab-case)
75
+ * @returns {Promise<{deleted: boolean, project: string}>}
76
+ *
77
+ * @example
78
+ * await cdn.deleteProject('my-old-project');
79
+ */
80
+ export function deleteProject(projectSlug: string): Promise<{
81
+ deleted: boolean;
82
+ project: string;
83
+ }>;
84
+ /**
85
+ * Publish a single local file to an arbitrary location on the public CDN.
86
+ *
87
+ * Automatically creates any missing parent directories.
88
+ * Returns a direct public HTTPS URL.
89
+ *
90
+ * @param {string} localPath - Absolute or relative path to the local file
91
+ * @param {string} remoteRelativePath - Target path under htdocs (e.g. "tmp/audio-123.mp3" or "projects/my-project/reference.wav")
92
+ *
93
+ * @returns {Promise<{public_url: string, remote_path: string}>}
94
+ *
95
+ * @example
96
+ * const result = await cdn.publishFile(
97
+ * '/tmp/generated.mp3',
98
+ * 'tmp/quick-reference.mp3'
99
+ * );
100
+ * console.log(result.public_url);
101
+ */
102
+ export function publishFile(localPath: string, remoteRelativePath: string): Promise<{
103
+ public_url: string;
104
+ remote_path: string;
105
+ }>;
106
+ /**
107
+ * Publish one or more local files into an organized project folder on the public CDN.
108
+ *
109
+ * Supports both single file (string) and multiple files (array).
110
+ * Automatically creates the project directory and generates `meta.json`.
111
+ * Optional `description.md` and `plan.md` files can be created.
112
+ *
113
+ * @param {string|string[]} localPaths - Single path or array of local file paths
114
+ * @param {string} projectSlug - Project identifier (sanitized to kebab-case)
115
+ * @param {Object} [options]
116
+ * @param {string} [options.description] - Human-readable project description
117
+ * @param {string} [options.plan] - Planning notes or step-by-step evolution
118
+ * @param {string} [options.filename] - Custom filename (only used when uploading a single file)
119
+ *
120
+ * @returns {Promise<{public_urls: string[], project_folder: string, meta: object}>}
121
+ *
122
+ * @example
123
+ * // Multiple files
124
+ * const result = await cdn.publishToProject(
125
+ * ['audio.mp3', 'cover.jpg'],
126
+ * 'my-project',
127
+ * { description: 'Music cover project' }
128
+ * );
129
+ *
130
+ * // Single file with custom name
131
+ * await cdn.publishToProject('/tmp/file.mp3', 'my-project', { filename: 'final.mp3' });
132
+ */
133
+ export function publishToProject(localPaths: string | string[], projectSlug: string, options?: {
134
+ description?: string | undefined;
135
+ plan?: string | undefined;
136
+ filename?: string | undefined;
137
+ }): Promise<{
138
+ public_urls: string[];
139
+ project_folder: string;
140
+ meta: object;
141
+ }>;
package/types/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { default as CdnToolset } from "./CdnToolset.js";
1
2
  import AgentManager from './AgentManager.js';
2
3
  import AgentServer from './AgentServer.js';
3
4
  import AgentClient from './AgentClient.js';
@@ -5,14 +6,17 @@ import Prompt from './Prompt.js';
5
6
  import ToolSet from './ToolSet.js';
6
7
  import Session from './Session.js';
7
8
  export namespace API {
8
- namespace text {
9
+ export namespace text {
9
10
  export { gpt };
10
11
  export { xai };
11
12
  export { claude };
12
13
  }
13
- namespace search {
14
+ export namespace search {
14
15
  export { brave };
15
16
  }
17
+ export { minimax };
18
+ export { stability };
19
+ export { xai };
16
20
  }
17
21
  import Cli from './Cli.js';
18
22
  import { env } from './fafs.js';
@@ -23,4 +27,6 @@ import { request as gpt } from './API/openai.com/reponses/text.js';
23
27
  import { request as xai } from './API/x.ai/responses.js';
24
28
  import { request as claude } from './API/anthropic.com/text.js';
25
29
  import { request as brave } from './API/brave.com/search.js';
30
+ import minimax from './API/minimax/index.js';
31
+ import stability from './API/stability.ai/index.js';
26
32
  export { AgentManager, AgentServer, AgentClient, Prompt, ToolSet, Session, Cli, env, GLOBAL, wsCli, wsIO };
@@ -1,20 +1,20 @@
1
1
  #!/bin/bash
2
2
  # utils/syntax_check.sh - Multi-language syntax validation
3
- # Usage: ./utils/syntax_check.sh <file> [--fix|--verbose]
4
- # Detects lang from ext/shebang, runs checker. Returns 0=OK, 1=error.
5
- # Integrates with write_file tool retries.
3
+ # Usage: ./utils/syntax_check.sh <file>
4
+ # Detects lang from ext/shebang, runs checker.
5
+ # Captures stdout+stderr from each syntax tool and echoes it back to STDOUT.
6
+ # Returns 0=OK, 1=error. Integrates with write_file lib/genericToolset.js tool.
6
7
 
7
8
  set -euo pipefail
8
9
 
9
10
  FILE="${1?Error: Provide file path}"
10
- VERBOSE="${2:-}"
11
- FIX="${VERBOSE:0:4}==--fix"
11
+ MODE="${2:-}"
12
12
 
13
13
  [ ! -f "$FILE" ] && { echo "❌ File not found: $FILE"; exit 1; }
14
14
 
15
15
  # Detect language
16
16
  EXT="${FILE##*.}"
17
- SHEBANG=$(head -n1 "$FILE" 2>/dev/null | cut -d' ' -f1)
17
+ SHEBANG=$(head -n1 "$FILE" 2>/dev/null | cut -d' ' -f1 || true)
18
18
 
19
19
  detect_lang() {
20
20
  case "$SHEBANG" in
@@ -35,26 +35,70 @@ detect_lang() {
35
35
  LANG=$(detect_lang)
36
36
  echo "🔍 Validating $FILE (lang: $LANG)"
37
37
 
38
+ # Helper to run checker, capture all output (stdout+stderr), echo it, then print status
39
+ run_check() {
40
+ local cmd="$1"
41
+ local label="$2"
42
+ local ok_msg="✅ ${label} OK"
43
+ local err_msg="❌ ${label} syntax error"
44
+
45
+ echo "→ Running: $cmd"
46
+ if output=$(eval "$cmd" 2>&1); then
47
+ if [ -n "$output" ]; then
48
+ echo "$output"
49
+ fi
50
+ echo "$ok_msg"
51
+ return 0
52
+ else
53
+ if [ -n "$output" ]; then
54
+ echo "$output"
55
+ else
56
+ echo "(No output from checker - exited with error)"
57
+ fi
58
+ echo "$err_msg"
59
+ return 1
60
+ fi
61
+ }
62
+
38
63
  case "$LANG" in
39
64
  js)
40
- node --check "$FILE" && echo "JS OK" || { echo "❌ JS syntax error"; exit 1; }
65
+ run_check "node --check \"$FILE\"" "JS" || exit 1
41
66
  ;;
42
67
  py)
43
- python3 -m py_compile "$FILE" && echo "Python OK" || { echo "❌ Python syntax error"; exit 1; }
68
+ run_check "python3 -m py_compile \"$FILE\"" "Python" || exit 1
44
69
  ;;
45
70
  bash|sh)
46
- bash -n "$FILE" && echo "Bash OK" || { echo "❌ Bash syntax error"; exit 1; }
47
- # Optional: shellcheck if installed
48
- if command -v shellcheck >/dev/null; then
49
- shellcheck "$FILE" || echo "⚠️ Shellcheck warnings"
71
+ run_check "shellcheck \"$FILE\"" "Bash" || exit 1
72
+
73
+ # Optional: shellcheck (warnings only, does not fail build)
74
+ if command -v shellcheck >/dev/null 2>&1; then
75
+ echo "→ Running: shellcheck \"$FILE\""
76
+ if shell_output=$(shellcheck "$FILE" 2>&1); then
77
+ if [ -n "$shell_output" ]; then
78
+ echo "$shell_output"
79
+ fi
80
+ echo "✅ Shellcheck passed"
81
+ else
82
+ echo "$shell_output"
83
+ echo "⚠️ Shellcheck found issues (warnings only)"
84
+ fi
50
85
  fi
51
86
  ;;
52
87
  json)
53
- node -e "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'))" "$FILE" && echo "✅ JSON OK" || { echo "❌ JSON invalid"; exit 1; }
88
+ run_check "node -e '
89
+ try {
90
+ JSON.parse(require(\"fs\").readFileSync(process.argv[1], \"utf8\"));
91
+ console.log(\"JSON is valid\");
92
+ } catch (e) {
93
+ console.error(e.message);
94
+ process.exit(1);
95
+ }
96
+ ' \"$FILE\"" "JSON" || exit 1
54
97
  ;;
55
98
  unknown)
56
- echo "⚠️ Unknown lang for $EXT / shebang: $SHEBANG"
57
- exit 0 # Non-fatal
99
+ echo "⚠️ Unknown language for extension .$EXT / shebang: $SHEBANG"
100
+ echo "✅ Skipping syntax check"
101
+ exit 0
58
102
  ;;
59
103
  esac
60
104
 
@@ -1,229 +0,0 @@
1
- # Multi-Agent Clusters in Dave: v0.0.9
2
-
3
- Welcome to the exciting world of **Multi-Agent Clusters** in the Dave framework! 🚀 If you&apos;re ready to scale your AI agents into powerful, collaborative clusters, you&apos;ve come to the right place. This guide walks you through setting up CodeServer with PM2, spawning agents, launching in server mode, connecting clients, querying sessions, managing with PM2, testing, and more. By the end, you&apos;ll have a robust cluster humming along, enabling self-aware, interconnected agents. Let&apos;s dive in step-by-step!
4
-
5
- ## CodeServer PM2 Setup
6
-
7
- CodeServer is the backbone of your multi-agent cluster, providing a WebSocket-based server for agent communication. It integrates seamlessly with PM2 for process management, ensuring high availability and easy scaling.
8
-
9
- ### Prerequisites
10
- - Node.js (v18+ recommended)
11
- - PM2 installed globally: `npm install -g pm2`
12
- - Dave project cloned and dependencies installed: `npm install`
13
-
14
- ### Step-by-Step Setup
15
- 1. **Choose Your Launch Method**:
16
- - Use the binary script: `./bin/codeDave` (convenient for quick starts).
17
- - Or the shell script: `./agents/codeserver.sh` (for more customization).
18
-
19
- 2. **Default Configuration**:
20
- - **Port**: 9000 (change with `--port 8080` if needed).
21
- - **Secret**: &quot;123&quot; (for secure WebSocket connections; override with `--secret your_secret`).
22
-
23
- 3. **Launch CodeServer with PM2**:
24
- Run the following to start CodeServer as a PM2-managed process:
25
- ```
26
- pm2 start ./bin/codeDave --name &quot;hello-dave_code_9000&quot; -- --serve --port 9000 --secret 123
27
- ```
28
- - `--serve`: Enables server mode (detailed below).
29
- - This creates a process named `hello-dave_code_9000` for easy identification.
30
-
31
- 4. **Verify Setup**:
32
- - Check PM2 status: `pm2 list` (look for `hello-dave_code_9000` in &quot;online&quot; status).
33
- - Test connection: Use a WebSocket client to connect to `ws://127.0.0.1:9000/ws` with secret &quot;123&quot;.
34
-
35
- ## Creating Agents via spawn_agent
36
-
37
- Spawning agents is where the magic happens! Use the `spawn_agent` function to dynamically create and integrate new agents into your cluster.
38
-
39
- ### Reference to spawn_agent Blueprint
40
- For a deep dive into `spawn_agent`, check the [spawn_agent blueprint](../blueprints/spawn-agent.md) (or implement based on the core Dave agent manager patterns in [agent-manager.md](./agent-manager.md)).
41
-
42
- ### Step-by-Step Agent Creation
43
- 1. **Import and Initialize**:
44
- In your Node.js script:
45
- ```javascript
46
- const { spawn_agent } = require(&apos;./agents/spawn&apos;); // Adjust path as needed
47
- ```
48
-
49
- 2. **Spawn an Agent**:
50
- ```javascript
51
- const newAgent = spawn_agent({
52
- name: &quot;weatherPredictor&quot;,
53
- prompt: &quot;You are a weather prediction agent. Use tools to fetch data.&quot;,
54
- tools: [&apos;web_search&apos;, &apos;weather_api&apos;],
55
- cluster: &quot;ws://127.0.0.1:9000/ws&quot; // Attach to your CodeServer
56
- });
57
- ```
58
- - This generates the agent and attaches it to the cluster for collaborative querying.
59
-
60
- 3. **Integration with Cluster**:
61
- - Agents auto-register with CodeServer upon spawn.
62
- - Use `newAgent.connect({ secret: &quot;123&quot; })` to ensure secure attachment.
63
-
64
- ## Launching Server Mode (--serve)
65
-
66
- Server mode turns CodeServer into a persistent hub for multi-agent interactions.
67
-
68
- 1. **Command**:
69
- ```
70
- ./bin/codeDave --serve --port 9000 --secret 123
71
- ```
72
-
73
- 2. **What Happens**:
74
- - Listens on WebSocket endpoint `/ws`.
75
- - Handles agent registrations and session management.
76
- - Supports multiple concurrent clients.
77
-
78
- 3. **PM2 Integration**:
79
- As shown in setup, wrap it in PM2 for daemonization and auto-restart.
80
-
81
- ## Attaching Clients (--connect)
82
-
83
- Clients (like other Dave instances or tools) connect to the cluster for tool calls and session sharing.
84
-
85
- 1. **Basic Connection**:
86
- ```
87
- ./bin/dave.js --connect ws://127.0.0.1:9000/ws --secret 123
88
- ```
89
- - This attaches the client as a tool-calling endpoint.
90
- - Use in scripts for agent-to-agent communication.
91
-
92
- 2. **Advanced Usage**:
93
- - Pipe inputs: `echo &quot;query&quot; | ./bin/dave.js --connect ...`
94
- - Handle toolcalls: Clients receive and execute tools on behalf of the cluster.
95
-
96
- ## Querying via bin/dave.js --connect
97
-
98
- For one-shot queries or building sessions, use `bin/dave.js` with connection flags.
99
-
100
- ### One-Shot Example
101
- Predict weather with a quick query:
102
- ```
103
- echo &quot;predict weather in NYC&quot; | ./bin/dave.js --connect ws://127.0.0.1:9000/ws --secret 123
104
- ```
105
- - Builds a temporary session, routes to relevant agents (e.g., weatherPredictor), and returns results.
106
-
107
- ### Session Building
108
- For persistent sessions:
109
- ```
110
- ./bin/dave.js --connect ws://127.0.0.1:9000/ws --secret 123 --session my_weather_session
111
- ```
112
- - Follow with queries to maintain state across interactions.
113
-
114
- ## PM2 Start/Stop/Reload
115
-
116
- PM2 makes cluster management a breeze!
117
-
118
- 1. **List Processes**:
119
- ```
120
- pm2 list
121
- ```
122
- - Shows status of `hello-dave_code_9000` and other agents.
123
-
124
- 2. **Start/Stop**:
125
- ```
126
- pm2 start hello-dave_code_9000 # Start
127
- pm2 stop hello-dave_code_9000 # Stop
128
- pm2 restart hello-dave_code_9000 # Restart
129
- ```
130
-
131
- 3. **Reload (Zero-Downtime)**:
132
- ```
133
- pm2 reload hello-dave_code_9000
134
- ```
135
- - Ideal for updates without interrupting sessions.
136
-
137
- 4. **Logs and Monitoring**:
138
- ```
139
- pm2 logs hello-dave_code_9000
140
- pm2 monit
141
- ```
142
-
143
- ## Testing One-Shots and Sessions
144
-
145
- Ensure your cluster is rock-solid with these tests.
146
-
147
- ### One-Shot Testing
148
- 1. Spawn a test agent.
149
- 2. Run: `echo &quot;test query&quot; | ./bin/dave.js --connect ...`
150
- 3. Verify output matches expected (e.g., no errors, relevant response).
151
-
152
- ### Session Testing
153
- 1. Start a session: `./bin/dave.js --connect ... --session test`
154
- 2. Send multiple queries: `echo &quot;first&quot; | ...` then `echo &quot;follow-up&quot; | ...`
155
- 3. Check session persistence (e.g., context retained).
156
-
157
- ### End-to-End Test Script
158
- ```bash
159
- #!/bin/bash
160
- # test_cluster.sh
161
- pm2 start ./bin/codeDave --name &quot;test_code&quot; -- --serve --port 9000 --secret 123
162
- sleep 2
163
- echo &quot;Hello cluster!&quot; | ./bin/dave.js --connect ws://127.0.0.1:9000/ws --secret 123
164
- pm2 stop test_code
165
- ```
166
-
167
- ## Self-Awareness: Detecting PM2/CodeServer in Prompts
168
-
169
- Make your agents smarter by embedding cluster awareness!
170
-
171
- - **In Agent Prompts**:
172
- Include detection logic: &quot;If running under PM2/CodeServer (detect via env vars like PM2_PROCESS_ID or connection to ws://localhost:9000), coordinate with cluster agents.&quot;
173
-
174
- - **Implementation**:
175
- Agents auto-detect via:
176
- ```javascript
177
- if (process.env.PM2_PROCESS_ID || connection.url.includes(&apos;9000&apos;)) {
178
- // Cluster mode: Share context
179
- }
180
- ```
181
- This enables self-aware routing, e.g., &quot;Delegate weather query to weatherPredictor in cluster.&quot;
182
-
183
- ## Mermaid Diagram: Cluster Architecture
184
-
185
- Visualize your setup!
186
-
187
- ```mermaid
188
- graph TD
189
- A[PM2 Manager] --> B[CodeServer<br/>Port 9000 /ws]
190
- B --> C[Agent 1<br/>spawn_agent()]
191
- B --> D[Agent 2<br/>e.g., WeatherPredictor]
192
- E[Client / bin/dave.js] -->|connect| B
193
- E -->|one-shot| F[Session Builder]
194
- G[Tools: web_search, etc.] <-->|toolcalls| C
195
- G <-->|toolcalls| D
196
- style B fill:#f9f,stroke:#333,stroke-width:2px
197
- ```
198
-
199
- - **Nodes**: PM2 oversees CodeServer, which hubs agents and clients.
200
- - **Flows**: Connections for spawning, querying, and tool execution.
201
-
202
- ## Examples
203
-
204
- ### Full Cluster Spawn and Query
205
- 1. Start CodeServer: `pm2 start ./bin/codeDave --name code_9000 -- --serve --port 9000 --secret 123`
206
- 2. Spawn Agent (in Node script):
207
- ```javascript
208
- const agent = spawn_agent({ name: &quot;queryMaster&quot;, cluster: &quot;ws://127.0.0.1:9000/ws&quot; });
209
- ```
210
- 3. Query: `echo &quot;What&apos;s the plan?&quot; | ./bin/dave.js --connect ws://127.0.0.1:9000/ws --secret 123`
211
-
212
- ### Multi-Agent Collaboration
213
- - Spawn multiple: weather, news, summary agents.
214
- - Query: &quot;Summarize today&apos;s news and weather&quot; → Routes to respective agents via cluster.
215
-
216
- ## Troubleshooting
217
-
218
- - **Connection Refused**: Ensure CodeServer is running (`pm2 list`) and port 9000 is free (`lsof -i :9000`).
219
- - **Secret Mismatch**: Double-check `--secret` flags match.
220
- - **PM2 Crashes**: View logs (`pm2 logs`)—common issues: missing deps or port conflicts. Restart: `pm2 restart all`.
221
- - **Agent Not Attaching**: Verify `spawn_agent` cluster URL and secret. Test WebSocket manually.
222
- - **Session Loss**: Check PM2 memory limits (`pm2 desc code_9000`); increase if needed.
223
- - **One-Shot Fails**: Ensure input is piped correctly; debug with `--verbose`.
224
-
225
- If issues persist, reference [project-overview.md](./project-overview.md) or spawn a debug agent!
226
-
227
- ---
228
-
229
- *Ready for v0.0.9 deployment! Cluster up and conquer those multi-agent challenges. 🎉 Questions? Ping the Dave community.*