@j-o-r/hello-dave 0.0.3 → 0.0.4

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 (119) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +216 -56
  3. package/README.md.bak +481 -0
  4. package/README.md.bak.1774780058 +338 -0
  5. package/README.md.bak2 +455 -0
  6. package/docs.bak.1774780058/agent-manager.md +167 -0
  7. package/docs.bak.1774780058/agent-manager.md.bak +137 -0
  8. package/docs.bak.1774780058/agent-manager.md.bak2 +157 -0
  9. package/docs.bak.1774780058/codeserver-pattern.md +191 -0
  10. package/docs.bak.1774780058/path-resolution-best-practices.md +104 -0
  11. package/docs.bak.1774780058/project-overview.md +67 -0
  12. package/docs.bak.1774780058/project-overview.md.bak +67 -0
  13. package/docs.bak.1774780058/prompt-class.md +141 -0
  14. package/docs.bak.1774780058/prompt-class.md.bak +142 -0
  15. package/docs.bak.1774780058/tools-syntax-validation.md +121 -0
  16. package/docs.bak.1774780058/tools-syntax-validation.md.bak2 +125 -0
  17. package/docs.bak.1774780058/tools-syntax-validation.md.bak3 +125 -0
  18. package/docs.bak.1774780058/tools-syntax-validation.md.bak4 +106 -0
  19. package/docs.bak.1774780058/tools-syntax-validation.md.bak_path +106 -0
  20. package/docs.bak.1774780058/toolset.md +164 -0
  21. package/docs.bak.1774780058/toolset.md.bak +94 -0
  22. package/docs.bak.1774780058/toolset.md.bak3 +161 -0
  23. package/docs.bak.1774780058/toolset.md.bak4 +161 -0
  24. package/docs.bak.1774780058/toolset.md.bak5 +161 -0
  25. package/docs.bak.1774780058/toolset.md.bak6 +163 -0
  26. package/docs.bak.1774780058/toolset.md.bak_path +163 -0
  27. package/docs.bak.1774780058/toolset.md.bak_syntax +161 -0
  28. package/docs.bak.1774780058/xai-responses.md +111 -0
  29. package/docs.bak.1774780058/xai-responses.md.bak +107 -0
  30. package/docs.bak.1774780058/xai-responses.md.bak2 +107 -0
  31. package/docs.bak.1774780058/xai_collections.md +106 -0
  32. package/examples/ask_agent.js +137 -0
  33. package/examples/code_agent.js +149 -0
  34. package/examples/coderev_agent.js +136 -0
  35. package/examples/codeserver.sh +47 -0
  36. package/examples/daisy_agent.js +170 -0
  37. package/examples/docs_agent.js +148 -0
  38. package/examples/gpt_agent.js +125 -0
  39. package/examples/grok_agent.js +132 -0
  40. package/examples/grok_agent.js.bak +98 -0
  41. package/examples/grok_agent.js.bak.2 +99 -0
  42. package/examples/grok_agent.js.bak.3 +1 -0
  43. package/examples/grok_agent.js.bak.4 +124 -0
  44. package/examples/grok_agent.js.bak.5 +1 -0
  45. package/examples/grok_agent.js.bak.6 +1 -0
  46. package/examples/memory_agent.js +152 -0
  47. package/examples/npm_agent.js +202 -0
  48. package/examples/npm_agent.js.bak.3 +2 -0
  49. package/examples/npm_agent.js.bak.4 +205 -0
  50. package/examples/npm_agent.js.bak.5 +1 -0
  51. package/examples/npm_agent.js.bak.6 +1 -0
  52. package/examples/prompt_agent.js +133 -0
  53. package/examples/readme_agent.js +148 -0
  54. package/examples/spawn_agent.js +293 -0
  55. package/examples/test_agent.js +187 -0
  56. package/examples/todo_agent.js +175 -0
  57. package/{examples/codeDave.js → examples.bak.1774780058/code_agent.js} +40 -6
  58. package/{examples/CodeServer → examples.bak.1774780058/codeserver.sh} +9 -5
  59. package/examples.bak.1774780058/memory_agent.js +112 -0
  60. package/{examples/spawndave.js → examples.bak.1774780058/spawn_agent.js} +29 -6
  61. package/examples.bak.1774780058/test_agent.js +162 -0
  62. package/{examples/todoDave.js → examples.bak.1774780058/todo_agent.js} +8 -2
  63. package/lib/API/x.ai/responses.js +7 -9
  64. package/lib/AgentManager.js +3 -2
  65. package/lib/AgentServer.js +23 -19
  66. package/lib/genericToolset.js +159 -26
  67. package/lib/genericToolset.js.bak_syntax +402 -0
  68. package/lib/wsCli.js +0 -1
  69. package/package.json +4 -5
  70. package/scenarios.bak.1774780058/data/eval_node_message.json +9 -0
  71. package/scenarios.bak.1774780058/data/hist_oa.json +66 -0
  72. package/scenarios.bak.1774780058/data/o3_response1.json +96 -0
  73. package/scenarios.bak.1774780058/data/oa_reasoning_parse.json +112 -0
  74. package/scenarios.bak.1774780058/data/tool_oa.json +96 -0
  75. package/scenarios.bak.1774780058/data/tool_xai.json +59 -0
  76. package/scenarios.bak.1774780058/data/tool_xai2.json +40 -0
  77. package/scenarios.bak.1774780058/data/xai-response-1.json +59 -0
  78. package/scenarios.bak.1774780058/data/xai-response-2.json +10 -0
  79. package/scenarios.bak.1774780058/data/xai_reasoning_tools_resp.json +59 -0
  80. package/scenarios.bak.1774780058/data/xai_search_response.json +58 -0
  81. package/scenarios.bak.1774780058/environment.js +10 -0
  82. package/scenarios.bak.1774780058/example.js +17 -0
  83. package/scenarios.bak.1774780058/genericToolset.test.js +182 -0
  84. package/scenarios.bak.1774780058/grok.js +113 -0
  85. package/scenarios.bak.1774780058/memory-tools.js +51 -0
  86. package/scenarios.bak.1774780058/openai-o3.js +137 -0
  87. package/scenarios.bak.1774780058/openai-prompt.js +155 -0
  88. package/scenarios.bak.1774780058/openai-session.js +148 -0
  89. package/scenarios.bak.1774780058/openai.js +102 -0
  90. package/scenarios.bak.1774780058/prompt.js +118 -0
  91. package/scenarios.bak.1774780058/promptFishbowl.js +76 -0
  92. package/scenarios.bak.1774780058/search.brave.com.js +25 -0
  93. package/scenarios.bak.1774780058/sh.js +15 -0
  94. package/scenarios.bak.1774780058/test-wsio.js +26 -0
  95. package/scenarios.bak.1774780058/testToolset.js +42 -0
  96. package/scenarios.bak.1774780058/toolset.js +16 -0
  97. package/scenarios.bak.1774780058/toolset.test.js +141 -0
  98. package/scenarios.bak.1774780058/write_file_syntax.test.js +145 -0
  99. package/scenarios.bak.1774780058/write_file_validation/README.md +30 -0
  100. package/scenarios.bak.1774780058/write_file_validation/bad.js +3 -0
  101. package/scenarios.bak.1774780058/write_file_validation/good.js +4 -0
  102. package/scenarios.bak.1774780058/write_file_validation/test.sh +43 -0
  103. package/scenarios.bak.1774780058/wsClient.js +69 -0
  104. package/scenarios.bak.1774780058/xai_responses.integration.test.js +57 -0
  105. package/scenarios.bak.1774780058/xai_responses.test.js +154 -0
  106. package/scenarios.bak.1774780058/xaicoll.js +50 -0
  107. package/scenarios.bak.1774780058/xaifiles.js +48 -0
  108. package/types/AgentManager.d.ts +4 -3
  109. package/utils/syntax_check.sh +61 -0
  110. package/utils/test.sh +46 -0
  111. /package/{examples/askDave.js → examples.bak.1774780058/ask_agent.js} +0 -0
  112. /package/{examples/coderev.js → examples.bak.1774780058/coderev_agent.js} +0 -0
  113. /package/{examples/daisy.js → examples.bak.1774780058/daisy_agent.js} +0 -0
  114. /package/{examples/docsDave.js → examples.bak.1774780058/docs_agent.js} +0 -0
  115. /package/{examples/gpt.js → examples.bak.1774780058/gpt_agent.js} +0 -0
  116. /package/{examples/grok.js → examples.bak.1774780058/grok_agent.js} +0 -0
  117. /package/{examples/npmDave.js → examples.bak.1774780058/npm_agent.js} +0 -0
  118. /package/{examples/promptDave.js → examples.bak.1774780058/prompt_agent.js} +0 -0
  119. /package/{examples/readmeDave.js → examples.bak.1774780058/readme_agent.js} +0 -0
@@ -77,9 +77,44 @@ const sys = (await agent.environment()).system;
77
77
  const prompt = `
78
78
  You are a coding assistant specializing in Bash and JavaScript (ESM/ESNext), with support for other languages. Assist by executing, reading, creating, querying, explaining, or helping with code. Use tools like 'execute_bash_script' for code execution and for writing and reading files, stay in the current working folder. Provide clear, step-by-step responses, examples, and ensure safety compliance.
79
79
  ---env
80
- ${sys}
80
+ \${sys}
81
81
  ---
82
- `.trim();
82
+
83
+ **MANDATORY MEMORY PROTOCOL (For EVERY query/task - NO EXCEPTIONS):**
84
+
85
+ Connected clients (todo_agent, readme_agent, npm_agent, docs_agent, **memory_agent**) are available as tools. **ALWAYS** use **memory_agent** FIRST and LAST:
86
+
87
+ 1. **RECALL PHASE (Step 1 of EVERY response)**:
88
+ - Call \`memory_agent "Recall relevant memories: tasks, errors, prefs for [keywords from user query]. List recent if empty."\`
89
+ - Incorporate recalled info (e.g., avoid known errors, resume tasks, apply prefs like temp=0.2).
90
+
91
+ 2. **CORE ACTION**:
92
+ - Perform coding assistance (tools: execute_bash_script, javascript_interpreter, read_file/write_file, web_search, etc.).
93
+ - Delegate to specialists if relevant:
94
+ - todo_agent: Tasks/TODO.md
95
+ - readme_agent: README.md
96
+ - npm_agent: NPM modules/package.json
97
+ - docs_agent: Documentation
98
+ - memory_agent: Persistent storage
99
+
100
+ 3. **WRITE PHASE (Step 3 of EVERY response)**:
101
+ - Call \`memory_agent "Store updates: [new tasks/errors/prefs/decisions from this interaction]. E.g., 'Task: [next step]', 'Error: [issue]', 'Pref: [setting]'"\`
102
+ - This ensures persistence across sessions/agents, prevents loops/token burn.
103
+
104
+ **EXAMPLE FLOW**:
105
+ User: "Fix bug in main.js"
106
+ - 1. memory_agent "Recall: tasks errors code bugs main.js"
107
+ - 2. read_file main.js → analyze/fix → write_file
108
+ - 3. memory_agent "Write: Task completed: fixed main.js bug. New task: add tests."
109
+
110
+ **PRIORITIES**:
111
+ - Safety: CWD-only, no escapes, validate before write.
112
+ - Efficiency: Use memories to skip repeats (e.g., "Known error: git conflict → skip").
113
+ - Step-by-step: Clear responses with code blocks.
114
+ - Current date: March 27, 2026.
115
+
116
+ FOLLOW MEMORY PROTOCOL RIGIDLY - it's how multi-agent coordination works!
117
+ `.trim();
83
118
  agent.setup({
84
119
  prompt,
85
120
  api,
@@ -97,9 +132,6 @@ if (toolset) {
97
132
  agent.addGenericToolcall('write_file');
98
133
 
99
134
  const addTools = (args['tools']) ? args['tools'].split(',') : [''];
100
- // if (addTools.includes('javascript')) {
101
- // agent.addGenericToolcall('javascript_interpreter');
102
- // }
103
135
  if (addTools.includes('ssh')) {
104
136
  agent.addGenericToolcall('execute_remote_script');
105
137
  }
@@ -107,9 +139,11 @@ if (toolset) {
107
139
  const cliIntro = `
108
140
  ${name} ${options.model}
109
141
  - context: ${contextWindow}
142
+ - **Memory Protocol ACTIVE**: Auto-recalls/writes via memory_agent for every query!
110
143
  `.trim();
111
144
  const description = `
112
- Handles execution, reading, creation, querying, explaining and code help, with safety and folder restrictions.
145
+ Main CodeServer hub: Coding expert + delegates to todo/readme/npm/docs/memory agents.
146
+ ALWAYS uses memory_agent for persistent tasks/errors/prefs.
113
147
  `.trim();
114
148
 
115
149
  await agent.start(serve, connect, cliIntro, "code_agent", description);
@@ -30,14 +30,18 @@ pm2 delete "${FOLDER}_todo_agent_${PORT}" 2>/dev/null || true
30
30
  pm2 delete "${FOLDER}_readme_agent_${PORT}" 2>/dev/null || true
31
31
  pm2 delete "${FOLDER}_npm_agent_${PORT}" 2>/dev/null || true
32
32
  pm2 delete "${FOLDER}_docs_agent_${PORT}" 2>/dev/null || true
33
+ pm2 delete "${FOLDER}_test_agent_${PORT}" 2>/dev/null || true
34
+ pm2 delete "${FOLDER}_memory_agent_${PORT}" 2>/dev/null || true
33
35
 
34
36
  # Spawn main Agent / server (absolute paths to scripts)
35
- pm2 start "${SCRIPT_DIR}/codeDave.js" --name "${FOLDER}_code_agent_${PORT}" -- --serve "${PORT}" --tools javascript --secret "${SECRET}"
37
+ pm2 start "${SCRIPT_DIR}/code_agent.js" --name "${FOLDER}_code_agent_${PORT}" -- --serve "${PORT}" --tools javascript --secret "${SECRET}"
36
38
  # Attach clients
37
- pm2 start "${SCRIPT_DIR}/todoDave.js" --name "${FOLDER}_todo_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
38
- pm2 start "${SCRIPT_DIR}/readmeDave.js" --name "${FOLDER}_readme_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
39
- pm2 start "${SCRIPT_DIR}/npmDave.js" --name "${FOLDER}_npm_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
40
- pm2 start "${SCRIPT_DIR}/docsDave.js" --name "${FOLDER}_docs_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
39
+ pm2 start "${SCRIPT_DIR}/todo_agent.js" --name "${FOLDER}_todo_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
40
+ pm2 start "${SCRIPT_DIR}/readme_agent.js" --name "${FOLDER}_readme_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
41
+ pm2 start "${SCRIPT_DIR}/npm_agent.js" --name "${FOLDER}_npm_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
42
+ pm2 start "${SCRIPT_DIR}/docs_agent.js" --name "${FOLDER}_docs_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
43
+ pm2 start "${SCRIPT_DIR}/test_agent.js" --name "${FOLDER}_test_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
44
+ pm2 start "${SCRIPT_DIR}/memory_agent.js" --name "${FOLDER}_memory_agent_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
41
45
 
42
46
  echo "CodeServer processes spawned with prefix '${FOLDER}_' and suffix _${PORT}. Check with: pm2 list | grep '${FOLDER}_${PORT}'"
43
47
  echo "dave --connect ws://127.0.0.1:${PORT}/ws --secret '$SECRET'"
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ import { AgentManager } from '@j-o-r/hello-dave';
3
+ import { parseArgs } from '@j-o-r/sh';
4
+
5
+ const name = 'memory_dave';
6
+ const api = 'xai';
7
+ let secret = '';
8
+
9
+ const args = parseArgs();
10
+ const help = args['help'] || false;
11
+ const connect = args['connect'] ? args['connect'] : undefined;
12
+ const serve = args['serve'] ? parseInt(args['serve']) : undefined;
13
+
14
+ /** @type {import('lib/API/x.ai/responses.js').XAIOptions} */
15
+ const options = { tools: [] };
16
+ options.tools.push({ type: 'web_search' });
17
+
18
+ if (args['secret']) {
19
+ secret = args['secret'];
20
+ }
21
+ if (args['model'] || true) {
22
+ options.model = args['model'] || 'grok-4-fast-reasoning';
23
+ }
24
+ if (args['temperature']) {
25
+ options.temperature = parseFloat(args['temperature']);
26
+ }
27
+ if (args['tokens']) {
28
+ options.max_output_tokens = parseInt(args['tokens']);
29
+ }
30
+ if (args['top_p']) {
31
+ options.top_p = parseFloat(args['top_p']);
32
+ }
33
+ options.reasoning = { effort: 'medium', summary: 'auto' };
34
+
35
+ const toolsetMode = 'auto';
36
+ const contextWindow = args['context'] ? parseInt(args['context']) : 250000;
37
+
38
+ function printHelp() {
39
+ console.log(`
40
+ '${name} --help' You are looking at it.
41
+
42
+ Project Memory manager for CodeServer multi-agent setup. Stores/retrieves shared memories in .cache/memory.ndjson (tasks/errors/prefs).
43
+
44
+ OPTIONS: --model ... --temp ... --secret ...
45
+ SERVER: --serve PORT | --connect ws://host:PORT/ws
46
+ `);
47
+ process.exit();
48
+ }
49
+
50
+ if (help) printHelp();
51
+
52
+ const tool_call_description = `
53
+ CodeServer Memory Agent. Manages shared agent memory (.cache/memory.ndjson) for tasks, errors, user prefs across all agents (code/todo/readme/npm/docs).
54
+ Use before/after actions: Recall relevant memories, write updates to avoid loops/repetition.
55
+ Categories: tasks (pending work), errors (failures to avoid), prefs (user settings).
56
+ `.trim();
57
+
58
+ const tool_call_name = 'memory_agent';
59
+
60
+ const prompt = `
61
+ You are MemoryDave, the dedicated memory manager for CodeServer multi-agent setup (code/todo/readme/npm/docs agents).
62
+
63
+ **CORE TOOLS (from lib/genericToolset.js)**:
64
+ - \`memory_recall [query]\`: Retrieve stored memories (tasks/errors/prefs). ALWAYS recall before acting (e.g., "tasks", "errors", "" for recent).
65
+ - \`memory_write {category: "tasks|errors|prefs", content: "details"}\`: Persist info to avoid repetition/loops/token burn.
66
+
67
+ **SHARED STORAGE**: .cache/memory.ndjson in project CWD (all agents share).
68
+
69
+ **ALWAYS**:
70
+ 1. **RECALL FIRST**: \`memory_recall "<user_query|category|''>"\` to check prior state/tasks/errors/prefs.
71
+ 2. **ACT**: Analyze + decide (write if new info, delegate via server if needed).
72
+ 3. **WRITE IF CHANGED**: Use \`memory_write\` for decisions/tasks/errors/prefs (e.g., "Pending: review npm deps", "Error: loop in git", "Pref: low temp for code").
73
+ 4. Respond: Summarize memories used/updated + action taken.
74
+
75
+ **USER QUERIES**:
76
+ - "Recall tasks" → List + suggest next.
77
+ - "Store task: Fix auth bug" → Write + confirm.
78
+ - "Clear old errors" → Recall + write cleaned.
79
+ - Coordinate: "Check if code agent has pending tasks" → Recall + advise.
80
+
81
+ Use other tools (bash/read_file) only if needed for context. Focus on memory coordination to boost multi-agent efficiency.
82
+
83
+ Current date: March 27, 2026.
84
+ `.trim();
85
+
86
+ const agent = new AgentManager({ name, secret });
87
+ agent.setup({
88
+ prompt,
89
+ api,
90
+ options,
91
+ toolsetMode,
92
+ contextWindow
93
+ });
94
+
95
+ // Ensure memory tools are available (auto + explicit for emphasis)
96
+ const toolset = agent.getToolset();
97
+ if (toolset) {
98
+ // Core memory tools (already in 'auto', but explicit)
99
+ agent.addGenericToolcall('memory_recall');
100
+ agent.addGenericToolcall('memory_write');
101
+ // Helpers for inspection
102
+ agent.addGenericToolcall('execute_bash_script');
103
+ agent.addGenericToolcall('read_file');
104
+ }
105
+
106
+ const cliIntro = `
107
+ 🤖 ${name} (${options.model}) ready! Shared CodeServer memory manager (.cache/memory.ndjson).
108
+ - context: ${contextWindow} tokens
109
+ - Recall: "tasks" | Write: "store task: XYZ"
110
+ `.trim();
111
+
112
+ await agent.start(serve, connect, cliIntro, tool_call_name, tool_call_description);
@@ -2,7 +2,7 @@
2
2
  import { AgentManager } from '@j-o-r/hello-dave';
3
3
  import { parseArgs } from '@j-o-r/sh';
4
4
 
5
- const name = 'spawndave';
5
+ const name = 'spawn_agent';
6
6
  const api = 'xai';
7
7
  let secret = '';
8
8
 
@@ -44,9 +44,9 @@ Guides you to create custom @j-o-r/hello-dave CLI agents (bin/<name>.js) w/ full
44
44
  PORTABLE: Runs in ANY project (auto-installs deps, no local docs needed). Docs: https://codeberg.org/duin/hello-dave (agent-manager.md, codeserver-pattern.md).
45
45
 
46
46
  USAGE:
47
- npx @j-o-r/hello-dave spawndave # Interactive creation
48
- npx @j-o-r/hello-dave spawndave --name myagent "Desc" # Semi-auto
49
- echo "Create CodeServer launcher" | npx @j-o-r/hello-dave spawndave # Multi-agent
47
+ npx @j-o-r/hello-dave spawn_agent # Interactive creation
48
+ npx @j-o-r/hello-dave spawn_agent --name myagent "Desc" # Semi-auto
49
+ echo "Create CodeServer launcher" | npx @j-o-r/hello-dave spawn_agent # Multi-agent
50
50
 
51
51
  OPTIONS: --model [...] --temp [...] --secret [...]
52
52
 
@@ -86,6 +86,29 @@ const promptParts = [
86
86
  '',
87
87
  '**PORTABILITY**: Auto-install deps: `@j-o-r/hello-dave @j-o-r/sh`. Absolute imports. NO local file refs (docs/examples).',
88
88
  '',
89
+ '**MANDATORY MEMORY PROTOCOL (For EVERY query/task - NO EXCEPTIONS):**',
90
+ 'Connected clients (todo_agent, readme_agent, npm_agent, docs_agent, **memory_agent**) are available as tools. **ALWAYS** use **memory_agent** FIRST and LAST:',
91
+ '1. **RECALL PHASE (Step 1 of EVERY response)**:',
92
+ ' - Call `memory_agent "Recall relevant memories: tasks, errors, prefs for [keywords from user query]. List recent if empty."`',
93
+ ' - Incorporate recalled info (e.g., avoid known errors, resume tasks, apply prefs like temp=0.2).',
94
+ '2. **CORE ACTION**:',
95
+ ' - Perform coding assistance (tools: execute_bash_script, javascript_interpreter, read_file/write_file, web_search, etc.).',
96
+ ' - Delegate to specialists if relevant:',
97
+ ' - todo_agent: Tasks/TODO.md',
98
+ ' - readme_agent: README.md',
99
+ ' - npm_agent: NPM modules/package.json',
100
+ ' - docs_agent: Documentation',
101
+ ' - memory_agent: Persistent storage',
102
+ '3. **WRITE PHASE (Step 3 of EVERY response)**:',
103
+ ' - Call `memory_agent "Store updates: [new tasks/errors/prefs/decisions from this interaction]. E.g., \'Task: [next step]\', \'Error: [issue]\', \'Pref: [setting]\'"`',
104
+ ' - This ensures persistence across sessions/agents, prevents loops/token burn.',
105
+ '',
106
+ '**PRIORITIES**:',
107
+ '- Safety: CWD-only, no escapes, validate before write.',
108
+ '- Efficiency: Use memories to skip repeats (e.g., "Known error: git conflict → skip").',
109
+ '- Step-by-step: Clear responses with code blocks.',
110
+ 'FOLLOW MEMORY PROTOCOL RIGIDLY - it\'s how multi-agent coordination works!',
111
+ '',
89
112
  '**INITIAL INSPECT** (execute_bash_script):',
90
113
  '1. `npm ls @j-o-r/hello-dave @j-o-r/sh 2>/dev/null || echo MISSING` → If MISSING: `npm i @j-o-r/hello-dave @j-o-r/sh --save-exact`.',
91
114
  '2. `mkdir -p bin examples`.',
@@ -234,7 +257,7 @@ Examples:
234
257
  - "Create code-review agent: name=coderev, desc=Git diff analyzer, tools=read_file execute_bash_script web_search"
235
258
  - "Generate CodeServer launcher for coderev + tododave + npmdave"`.trim();
236
259
 
237
- const toolName = 'spawn_dave';
260
+ const toolName = 'spawn_agent';
238
261
  const toolDescription = `Portable creator for CLI/WS agents (bin/<name>.js) + PM2 multi-agent launchers. Validates/tests/deploys. No local docs needed (uses repo: https://codeberg.org/duin/hello-dave).`.trim();
239
262
 
240
- await agent.start(serve, connect, cliIntro, toolName, toolDescription);
263
+ await agent.start(serve, connect, cliIntro, toolName, toolDescription);
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+ import { AgentManager } from '@j-o-r/hello-dave';
3
+ import { parseArgs } from '@j-o-r/sh';
4
+
5
+ const name = 'test_dave';
6
+ const api = 'xai';
7
+ let secret = '';
8
+
9
+ const args = parseArgs();
10
+ const help = args['help'] || false;
11
+ const connect = args['connect'] ? args['connect'] : undefined;
12
+ const serve = args['serve'] ? parseInt(args['serve']) : undefined;
13
+
14
+ /** @type {import('lib/API/x.ai/responses.js').XAIOptions} */
15
+ const options = {
16
+ tools: []
17
+ };
18
+ options.tools.push({
19
+ type: 'web_search'
20
+ });
21
+ if (args['secret']) {
22
+ secret = args['secret'];
23
+ }
24
+ if (args['model'] || true) {
25
+ options.model = args['model'] || 'grok-4-1-fast-reasoning';
26
+ }
27
+ options.temperature = 0.2;
28
+ if (args['tokens']) {
29
+ options.max_output_tokens = parseInt(args['tokens']);
30
+ }
31
+ if (args['top_p']) {
32
+ options.top_p = parseFloat(args['top_p']);
33
+ }
34
+ const reasoning = args['reasoning'] ? args['reasoning'] : 'medium';
35
+ if (reasoning) {
36
+ options.reasoning = {
37
+ effort: reasoning,
38
+ summary: 'auto'
39
+ };
40
+ }
41
+ const toolsetMode = 'auto';
42
+ const contextWindow = args['context'] ? parseInt(args['context']) : 2565000;
43
+
44
+ function printHelp() {
45
+ console.log(`
46
+ '${name} --help' You are looking at it.
47
+
48
+ OPTIONS:
49
+ --tokens [number]: max generated tokens
50
+ --context [number]: truncate message history to context-window size (default ${contextWindow})
51
+ --temperature [float]: -2 / +2
52
+ --model [string]: model name
53
+ --top_p [float]: number > 0, 0.1 means no top_p
54
+ --reasoning [low|medium|high]
55
+ --tools [javascript,bash,nushell,ssh] comma separated list
56
+
57
+ SERVER TOOLS:
58
+ --serve [number]: create an Agent server on port ws://127.0.0.1:[serve]/ws
59
+ --connect [url]: connect to a Server Agent e.g. ws://127.0.0.1:8080/ws (https://my.domain/ws)
60
+ --secret [string]: limit access to websocket server with a secret
61
+ `);
62
+ process.exit();
63
+ }
64
+
65
+ if (help) {
66
+ printHelp();
67
+ }
68
+
69
+ const agent = new AgentManager({ name, secret });
70
+ const sys = (await agent.environment()).system;
71
+
72
+ const prompt = `You are TestDave, the specialized testing agent for CodeServer projects. Your sole responsibility is to create, manage, and execute tests using the lightweight 'Test' class from '@j-o-r/sh' (already installed).
73
+
74
+ **CORE MISSION**:
75
+ - Write executable test scripts in ./scenarios/ folder with the extension *.test.js (e.g., scenarios/toolset.test.js).
76
+ - Tests must use: \`import { Test, assert, jsType } from '@j-o-r/sh';\`
77
+ - Structure: shebang \`#!/usr/bin/env node\`, fluent Test API (\`const t = new Test(); t.add('desc', () => { assert... }); await t.run();\`), exit(1) on errors.
78
+ - After write_file to scenarios/MODULE.test.js, ensure executable: \`chmod +x scenarios/MODULE.test.js\`
79
+ - Leverage project utilities: test existing files (examples/*.js, toolset.js, agents, SH commands, etc.) using read_file, execute_bash_script (ls/cat), npm_module_inspector.
80
+
81
+ **WHAT TO TEST** (discover dynamically):
82
+ 1. Project scripts: e.g., parseArgs, AgentManager flows, toolsets.
83
+ 2. Utilities: SH commands, async hooks, promise tracking.
84
+ 3. Agents: codeDave, npmDave, memoryDave integrations.
85
+ 4. Existing: genericToolset.test.js patterns, sh.js, etc.
86
+ - Query: "Write test for toolset.js" → read_file toolset.js → generate scenarios/toolset.test.js.
87
+
88
+ **Test Example** (from @j-o-r/sh docs):
89
+ \`\`\`
90
+ #!/usr/bin/env node
91
+ import { Test, assert, jsType } from '@j-o-r/sh';
92
+
93
+ const t = new Test();
94
+ t.add('Basic assert', () => assert.strictEqual(1 + 1, 2));
95
+ t.add('Type check', () => assert.strictEqual(jsType([]), 'Array'));
96
+ t.add('Async test', async () => {
97
+ const p = Promise.resolve('ok');
98
+ assert.strictEqual(await p, 'ok');
99
+ });
100
+ const report = await t.run();
101
+ process.exit(report.errors > 0 ? 1 : 0);
102
+ \`\`\`
103
+
104
+ **WORKFLOW** (per user request, e.g., "test parseArgs"):
105
+ 1. Recall memories (tasks/errors for testing).
106
+ 2. Inspect target: read_file, execute_bash_script \`ls lib/\`, npm_module_inspector.
107
+ 3. Generate test: Plan tests (coverage: happy path, errors, async), write to scenarios/{target}.test.js (e.g., scenarios/parseArgs.test.js).
108
+ 4. Validate: execute_bash_script \`node scenarios/{target}.test.js\` or \`./scenarios/{target}.test.js\`.
109
+ 5. Report results, store outcomes.
110
+
111
+ **MANDATORY MEMORY PROTOCOL** (ALWAYS FIRST/LAST):
112
+ 1. RECALL: memory_agent "Recall relevant memories: tasks, errors, prefs for [test target, e.g., toolset.js]."
113
+ 2. CORE: Write/Run tests in scenarios/*.test.js.
114
+ 3. WRITE: memory_agent "Store updates: Task: [next test], Error: [test fail], Pref: [coverage style]."
115
+
116
+ **PRIORITIES**:
117
+ - Safety: CWD-only, validate syntax before write (write_file auto-checks).
118
+ - Coverage: assertions (strictEqual, ok, throws), types (jsType), async (promises).
119
+ - Executable: shebang + chmod +x scenarios/*.test.js.
120
+ - Reuse: Import project utils (e.g., import {parseArgs} from './toolset.js').
121
+ - Current date: March 27, 2026.
122
+
123
+ FOLLOW RIGIDLY: Memory first/last, scenarios/*.test.js only, Test class exclusively.
124
+ `.trim();
125
+
126
+ agent.setup({
127
+ prompt,
128
+ api,
129
+ options,
130
+ toolsetMode,
131
+ contextWindow
132
+ });
133
+
134
+ const toolset = agent.getToolset();
135
+ if (toolset) {
136
+ agent.addGenericToolcall('history_search');
137
+ agent.addGenericToolcall('memory_recall');
138
+ agent.addGenericToolcall('memory_write');
139
+ agent.addGenericToolcall('javascript_interpreter');
140
+ agent.addGenericToolcall('execute_bash_script');
141
+ agent.addGenericToolcall('read_file');
142
+ agent.addGenericToolcall('write_file');
143
+ const addTools = args['tools'] ? args['tools'].split(',') : [''];
144
+ if (addTools.includes('ssh')) {
145
+ agent.addGenericToolcall('execute_remote_script');
146
+ }
147
+ }
148
+
149
+ const cliIntro = `
150
+ ${name} ${options.model}
151
+ - context: ${contextWindow}
152
+ - **Test Agent ACTIVE**: Writes/runs @j-o-r/sh Test scripts in ./scenarios/*.test.js (auto-executable).
153
+ - Example: "Write test for lib/MyClass.js"
154
+ - **Memory Protocol ACTIVE**
155
+ `.trim();
156
+
157
+ const description = `
158
+ TestDave: Generates executable tests (Test class) for project files/utils/agents in ./scenarios/*.test.js.
159
+ Uses memories, delegates to code/npm/etc. agents.
160
+ `.trim();
161
+
162
+ await agent.start(serve, connect, cliIntro, 'test_agent', description);
@@ -1,12 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { AgentManager } from '@j-o-r/hello-dave';
3
- import { parseArgs, readIn } from '@j-o-r/sh';
3
+ import { parseArgs } from '@j-o-r/sh';
4
4
 
5
5
  const name = 'todo_dave';
6
6
  const api = 'xai';
7
7
  let secret = '';
8
8
 
9
- const input = ''; // await readIn() /* not compabtible with `pm2` */;
10
9
  const args = parseArgs();
11
10
  const help = args['help'] || false;
12
11
  const connect = args['connect'] ? args['connect'] : undefined;
@@ -88,6 +87,13 @@ You are an expert TODO manager for this project. TODO.md stores tasks in Markdow
88
87
  ## Done
89
88
  - [x] Completed task
90
89
 
90
+ **CRITICAL: STRICT NO-CODING RULE** - Stick to TODO management ONLY. NEVER:
91
+ - Use coding tools (e.g., javascript_interpreter, write_file, read_file, syntax_check).
92
+ - Generate, execute, or edit code.
93
+ - Misuse bash for anything beyond safe TODO.md ops (e.g., cat TODO.md, echo > TODO.md).
94
+ If asked to code, decline: "For coding, use other agents. I'll handle TODOs only."
95
+ Delegate complex tasks via suggestions; use memory_agent if available for persistence.
96
+
91
97
  ALWAYS:
92
98
 
93
99
  1. Inspect the current TODO.md file if it exists (use \`cat TODO.md\` or similar).
@@ -160,7 +160,7 @@ const API_URL = 'https://api.x.ai/v1/responses';
160
160
  */
161
161
  const getHeaders = () => {
162
162
  if (!process.env['XAIKEY']) {
163
- throw new Error('Missing XAIKEY! export XAIKEY=<XAIKEY>')
163
+ throw new Error('Missing XAIKEY! export XAIKEY=[XAIKEY]')
164
164
  }
165
165
  const KEY = process.env['XAIKEY'];
166
166
  return {
@@ -301,7 +301,7 @@ function getBody(prompt, toolset, options) {
301
301
  // From the messages I only want assistant and user
302
302
  /** @type {XAIOptions} */
303
303
  // @ts-ignore
304
- const body = { ...defaultSettings, ...options };
304
+ const body = { ...defaultSettings, ...(options || {}) };
305
305
  // const body = options ? mergeOptions(DEFAULT_OPTIONS, options) : DEFAULT_OPTIONS;
306
306
  body.instructions = prompt.hasSystemprompt ? prompt.system_prompt : '';
307
307
  // the last messages should be a role tool or user else the model cannot handle the request
@@ -447,14 +447,14 @@ async function parseResponse(duration, prompt, res, toolset) {
447
447
  * @param {number} [counter] - leave empty this counts the number of requests when doing recursive request calls
448
448
  * @return {Promise<import('../../Session.js').Message>}
449
449
  */
450
- async function request(prompt, toolset = null, options, counter = 0) {
450
+ async function request(prompt, toolset = null, options = {}, counter = 0) {
451
451
  // Max number of recurusive calls
452
452
  const counterMax = GLOBAL.max_recursive_requests;
453
453
  const start = new Date().getTime();
454
- if (counter === 0) {
454
+ // if (counter === 0) {
455
455
  // Fresh request
456
456
  delete options.previous_response_id
457
- }
457
+ // }
458
458
  // Generate the request
459
459
  const { url, headers, body } = generateRequest(prompt, toolset, options);
460
460
  prompt.emit(prompt.EVENTS.http_request, {url, counter, body});
@@ -480,11 +480,9 @@ async function request(prompt, toolset = null, options, counter = 0) {
480
480
  // need to do another roundtrip to include the funtion_responses
481
481
  // And add the previousId for toolsets to work
482
482
  if (!options) {
483
- // @ts-ignore
484
- // options = {previous_response_id: previousId}
485
- } else {
486
- // options.previous_response_id = previousId
483
+ options = {};
487
484
  }
485
+ options.previous_response_id = previousId;
488
486
  await sleep('2s');
489
487
  return request(prompt, toolset, options, counter)
490
488
  } else {
@@ -151,8 +151,9 @@ class AgentManager {
151
151
  return env();
152
152
  }
153
153
  /**
154
- * Add (copy) a pre-defined toolcall to the function_calls
155
- * @param {'read_file'|'write_file'|'get_user_env'|'execute_bash_script'|'send_email'|'open_link'|'execute_remote_script'|'history_search'|'javascript_interpreter'} name - name /^[a-z_0-9]{2,}$/ e.g. 'execute_bash_script'
154
+ * Adds a pre-defined generic tool from lib/genericToolset.js to this agent's ToolSet.
155
+ * @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 - Valid generic tool name (validated /^[a-z_0-9]{2,}$/).
156
+ * @throws {Error} If toolset not initialized or tool not found in pool.
156
157
  */
157
158
  addGenericToolcall(name) {
158
159
  const validNameRegex = /^[a-z_0-9]{2,}$/;
@@ -131,7 +131,7 @@ class AgentServer {
131
131
  #debug = false;
132
132
  #port = 8000;
133
133
  #name = '';
134
- #secret = ''; // access secret
134
+ #secret = ''; // access secret
135
135
  #description = '';
136
136
  /** @type {Prompt} */
137
137
  #prompt
@@ -163,19 +163,19 @@ class AgentServer {
163
163
  this.#prompt = options.prompt;
164
164
  this.#debug = options.debug;
165
165
  // LOG EVENTS
166
- const events = Object.keys(this.#prompt.EVENTS);
167
- events.forEach((evt) => {
168
- this.#prompt.on(evt, (_msg) => {
169
- // log events
170
- console.log(`** ${this.#name} e:${evt}**`);
171
- if (evt === 'tool_request') {
172
- console.log(`tool execute: ${this.#name} ${_msg.name} ${_msg.call_id}`);
173
- } else if (evt === 'tool_error') {
174
- console.log(`tool error:`);
175
- console.log(JSON.stringify(_msg, null, ' '));
176
- }
177
- });
178
- });
166
+ const events = Object.keys(this.#prompt.EVENTS);
167
+ events.forEach((evt) => {
168
+ this.#prompt.on(evt, (_msg) => {
169
+ // log events
170
+ console.log(`** ${this.#name} e:${evt}**`);
171
+ if (evt === 'tool_request') {
172
+ console.log(`tool execute: ${this.#name} ${_msg.name} ${_msg.call_id}`);
173
+ } else if (evt === 'tool_error') {
174
+ console.log(`tool error:`);
175
+ console.log(JSON.stringify(_msg, null, ' '));
176
+ }
177
+ });
178
+ });
179
179
  // start
180
180
  (async () => {
181
181
  await this._start();
@@ -302,18 +302,22 @@ class AgentServer {
302
302
  const selected = msg.content;
303
303
  const messages = [];
304
304
  const list = this.#session.set(selected);
305
- list.forEach((msg) => {
305
+ this.#prompt.messages = list;
306
+ let i = 0;
307
+ const length = list.length;
308
+ for (; i < length; i++) {
309
+ const msg = list[i];
306
310
  if (!msg.sticky) {
307
311
  if (['user', 'assistant', 'reasoning', 'log'].includes(msg.role)) {
308
- if (msg.role === 'assistant' && msg.content[0].type === 'function_request') {
309
-
310
- } else {
312
+ if (msg.content[0].type !== 'function_request') {
311
313
  const content = this.#prompt.contentToString(msg.content);
312
314
  messages.push({ role: msg.role, content });
313
315
  }
314
316
  }
315
317
  }
316
- });
318
+ };
319
+ // Resume execution
320
+ await this.#prompt.triggerRequest();
317
321
  ws.sendToConnection(conn.id, JSON.stringify({
318
322
  action: 'server_sessionloaded',
319
323
  id,