@j-o-r/hello-dave 0.0.5 → 0.0.7

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 (127) hide show
  1. package/CHANGELOG.md +13 -26
  2. package/README.md +161 -522
  3. package/README.md.bak +144 -449
  4. package/{examples → agents}/ask_agent.js +5 -5
  5. package/{examples → agents}/codeserver.sh +14 -14
  6. package/{examples → agents}/daisy_agent.js +5 -5
  7. package/{examples → agents}/docs_agent.js +5 -5
  8. package/{examples → agents}/gpt_agent.js +5 -5
  9. package/{examples → agents}/grok_agent.js +5 -5
  10. package/agents/memory_agent.js +263 -0
  11. package/{examples → agents}/npm_agent.js +5 -5
  12. package/{examples → agents}/prompt_agent.js +5 -5
  13. package/agents/spawn_agent.js +137 -0
  14. package/{examples → agents}/test_agent.js +6 -8
  15. package/{examples → agents}/todo_agent.js +5 -5
  16. package/bin/codeDave +58 -0
  17. package/bin/dave.js +114 -96
  18. package/lib/AgentClient.js +111 -67
  19. package/lib/AgentManager.js +111 -80
  20. package/lib/AgentServer.js +144 -104
  21. package/lib/Cli.js +126 -93
  22. package/lib/Prompt.js +38 -5
  23. package/lib/Session.js +102 -79
  24. package/lib/ToolSet.js +79 -60
  25. package/lib/fafs.js +54 -19
  26. package/lib/genericToolset.js +109 -213
  27. package/lib/wsCli.js +50 -19
  28. package/lib/wsIO.js +11 -17
  29. package/package.json +2 -2
  30. package/types/AgentClient.d.ts +69 -35
  31. package/types/AgentManager.d.ts +50 -56
  32. package/types/AgentServer.d.ts +63 -16
  33. package/types/Cli.d.ts +56 -10
  34. package/types/Prompt.d.ts +36 -4
  35. package/types/Session.d.ts +23 -9
  36. package/types/ToolSet.d.ts +49 -32
  37. package/types/fafs.d.ts +68 -25
  38. package/types/wsCli.d.ts +14 -0
  39. package/types/wsIO.d.ts +9 -5
  40. package/utils/search_sessions.sh +100 -53
  41. package/README.md.backup +0 -269
  42. package/README.md.bak.1774780058 +0 -338
  43. package/README.md.bak2 +0 -531
  44. package/bin/spawn_agent.js +0 -293
  45. package/docs.bak.1774780058/agent-manager.md +0 -167
  46. package/docs.bak.1774780058/agent-manager.md.bak +0 -137
  47. package/docs.bak.1774780058/agent-manager.md.bak2 +0 -157
  48. package/docs.bak.1774780058/codeserver-pattern.md +0 -191
  49. package/docs.bak.1774780058/path-resolution-best-practices.md +0 -104
  50. package/docs.bak.1774780058/project-overview.md +0 -67
  51. package/docs.bak.1774780058/project-overview.md.bak +0 -67
  52. package/docs.bak.1774780058/prompt-class.md +0 -141
  53. package/docs.bak.1774780058/prompt-class.md.bak +0 -142
  54. package/docs.bak.1774780058/tools-syntax-validation.md +0 -121
  55. package/docs.bak.1774780058/tools-syntax-validation.md.bak2 +0 -125
  56. package/docs.bak.1774780058/tools-syntax-validation.md.bak3 +0 -125
  57. package/docs.bak.1774780058/tools-syntax-validation.md.bak4 +0 -106
  58. package/docs.bak.1774780058/tools-syntax-validation.md.bak_path +0 -106
  59. package/docs.bak.1774780058/toolset.md +0 -164
  60. package/docs.bak.1774780058/toolset.md.bak +0 -94
  61. package/docs.bak.1774780058/toolset.md.bak3 +0 -161
  62. package/docs.bak.1774780058/toolset.md.bak4 +0 -161
  63. package/docs.bak.1774780058/toolset.md.bak5 +0 -161
  64. package/docs.bak.1774780058/toolset.md.bak6 +0 -163
  65. package/docs.bak.1774780058/toolset.md.bak_path +0 -163
  66. package/docs.bak.1774780058/toolset.md.bak_syntax +0 -161
  67. package/docs.bak.1774780058/xai-responses.md +0 -111
  68. package/docs.bak.1774780058/xai-responses.md.bak +0 -107
  69. package/docs.bak.1774780058/xai-responses.md.bak2 +0 -107
  70. package/docs.bak.1774780058/xai_collections.md +0 -106
  71. package/examples/memory_agent.js +0 -152
  72. package/examples.bak.1774780058/ask_agent.js +0 -114
  73. package/examples.bak.1774780058/code_agent.js +0 -149
  74. package/examples.bak.1774780058/coderev_agent.js +0 -72
  75. package/examples.bak.1774780058/codeserver.sh +0 -47
  76. package/examples.bak.1774780058/daisy_agent.js +0 -177
  77. package/examples.bak.1774780058/docs_agent.js +0 -119
  78. package/examples.bak.1774780058/gpt_agent.js +0 -109
  79. package/examples.bak.1774780058/grok_agent.js +0 -98
  80. package/examples.bak.1774780058/memory_agent.js +0 -112
  81. package/examples.bak.1774780058/npm_agent.js +0 -175
  82. package/examples.bak.1774780058/prompt_agent.js +0 -112
  83. package/examples.bak.1774780058/readme_agent.js +0 -144
  84. package/examples.bak.1774780058/spawn_agent.js +0 -263
  85. package/examples.bak.1774780058/test_agent.js +0 -162
  86. package/examples.bak.1774780058/todo_agent.js +0 -138
  87. package/lib/genericToolset.js.bak_syntax +0 -402
  88. package/scenarios.bak.1774780058/data/eval_node_message.json +0 -9
  89. package/scenarios.bak.1774780058/data/hist_oa.json +0 -66
  90. package/scenarios.bak.1774780058/data/o3_response1.json +0 -96
  91. package/scenarios.bak.1774780058/data/oa_reasoning_parse.json +0 -112
  92. package/scenarios.bak.1774780058/data/tool_oa.json +0 -96
  93. package/scenarios.bak.1774780058/data/tool_xai.json +0 -59
  94. package/scenarios.bak.1774780058/data/tool_xai2.json +0 -40
  95. package/scenarios.bak.1774780058/data/xai-response-1.json +0 -59
  96. package/scenarios.bak.1774780058/data/xai-response-2.json +0 -10
  97. package/scenarios.bak.1774780058/data/xai_reasoning_tools_resp.json +0 -59
  98. package/scenarios.bak.1774780058/data/xai_search_response.json +0 -58
  99. package/scenarios.bak.1774780058/environment.js +0 -10
  100. package/scenarios.bak.1774780058/example.js +0 -17
  101. package/scenarios.bak.1774780058/genericToolset.test.js +0 -182
  102. package/scenarios.bak.1774780058/grok.js +0 -113
  103. package/scenarios.bak.1774780058/memory-tools.js +0 -51
  104. package/scenarios.bak.1774780058/openai-o3.js +0 -137
  105. package/scenarios.bak.1774780058/openai-prompt.js +0 -155
  106. package/scenarios.bak.1774780058/openai-session.js +0 -148
  107. package/scenarios.bak.1774780058/openai.js +0 -102
  108. package/scenarios.bak.1774780058/prompt.js +0 -118
  109. package/scenarios.bak.1774780058/promptFishbowl.js +0 -76
  110. package/scenarios.bak.1774780058/search.brave.com.js +0 -25
  111. package/scenarios.bak.1774780058/sh.js +0 -15
  112. package/scenarios.bak.1774780058/test-wsio.js +0 -26
  113. package/scenarios.bak.1774780058/testToolset.js +0 -42
  114. package/scenarios.bak.1774780058/toolset.js +0 -16
  115. package/scenarios.bak.1774780058/toolset.test.js +0 -141
  116. package/scenarios.bak.1774780058/write_file_syntax.test.js +0 -145
  117. package/scenarios.bak.1774780058/write_file_validation/README.md +0 -30
  118. package/scenarios.bak.1774780058/write_file_validation/bad.js +0 -3
  119. package/scenarios.bak.1774780058/write_file_validation/good.js +0 -4
  120. package/scenarios.bak.1774780058/write_file_validation/test.sh +0 -43
  121. package/scenarios.bak.1774780058/wsClient.js +0 -69
  122. package/scenarios.bak.1774780058/xai_responses.integration.test.js +0 -57
  123. package/scenarios.bak.1774780058/xai_responses.test.js +0 -154
  124. package/scenarios.bak.1774780058/xaicoll.js +0 -50
  125. package/scenarios.bak.1774780058/xaifiles.js +0 -48
  126. /package/{examples → agents}/code_agent.js +0 -0
  127. /package/{examples → agents}/readme_agent.js +0 -0
@@ -56,19 +56,19 @@ function printHelp() {
56
56
  ## USAGE MODES:
57
57
 
58
58
  ### 1. Direct Call (One-Shot, Positional ONLY):
59
- ./examples/${name}.js "Your query here" [--options]
59
+ ./agents/${name}.js "Your query here" [--options]
60
60
 
61
61
  ### 2. Interactive CLI (no positional arg):
62
- ./examples/${name}.js [--options]
62
+ ./agents/${name}.js [--options]
63
63
 
64
64
  ### 3. WS Server (no positional arg):
65
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
65
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
66
66
 
67
67
  ### 4. WS Client (no positional arg):
68
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
68
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
69
69
 
70
70
  ### 5. Hybrid (Server + Client, no positional arg):
71
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
71
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
72
72
 
73
73
  ## SERVER OPTIONS EXPLAINED:
74
74
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'search_agent'). Runs indefinitely until Ctrl+C.
@@ -25,23 +25,23 @@ FOLDER=$(basename "$PROJECT_DIR")
25
25
  echo "Starting CodeServer on port ${PORT} in folder '${FOLDER}' (SCRIPT_DIR: ${SCRIPT_DIR}) with SECRET '${SECRET}'..."
26
26
 
27
27
  # Delete existing processes with folder_port suffix
28
- pm2 delete "${FOLDER}_code_agent_${PORT}" 2>/dev/null || true
29
- pm2 delete "${FOLDER}_todo_agent_${PORT}" 2>/dev/null || true
30
- pm2 delete "${FOLDER}_readme_agent_${PORT}" 2>/dev/null || true
31
- pm2 delete "${FOLDER}_npm_agent_${PORT}" 2>/dev/null || true
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
28
+ pm2 delete "${FOLDER}_code_${PORT}" 2>/dev/null || true
29
+ pm2 delete "${FOLDER}_todo_${PORT}" 2>/dev/null || true
30
+ pm2 delete "${FOLDER}_readme_${PORT}" 2>/dev/null || true
31
+ pm2 delete "${FOLDER}_npm_${PORT}" 2>/dev/null || true
32
+ pm2 delete "${FOLDER}_docs_${PORT}" 2>/dev/null || true
33
+ pm2 delete "${FOLDER}_test_${PORT}" 2>/dev/null || true
34
+ pm2 delete "${FOLDER}_memory__${PORT}" 2>/dev/null || true
35
35
 
36
36
  # Spawn main Agent / server (absolute paths to scripts)
37
- pm2 start "${SCRIPT_DIR}/code_agent.js" --name "${FOLDER}_code_agent_${PORT}" -- --serve "${PORT}" --tools javascript --secret "${SECRET}"
37
+ pm2 start "${SCRIPT_DIR}/code_agent.js" --name "${FOLDER}_code_${PORT}" -- --serve "${PORT}" --tools javascript --secret "${SECRET}"
38
38
  # Attach clients
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}"
39
+ pm2 start "${SCRIPT_DIR}/todo_agent.js" --name "${FOLDER}_todo_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
40
+ pm2 start "${SCRIPT_DIR}/readme_agent.js" --name "${FOLDER}_readme_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
41
+ pm2 start "${SCRIPT_DIR}/npm_agent.js" --name "${FOLDER}_npm_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
42
+ pm2 start "${SCRIPT_DIR}/docs_agent.js" --name "${FOLDER}_docs_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
43
+ pm2 start "${SCRIPT_DIR}/test_agent.js" --name "${FOLDER}_test_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
44
+ pm2 start "${SCRIPT_DIR}/memory_agent.js" --name "${FOLDER}_memory_${PORT}" -- --connect "ws://127.0.0.1:${PORT}/ws" --secret "${SECRET}"
45
45
 
46
46
  echo "CodeServer processes spawned with prefix '${FOLDER}_' and suffix _${PORT}. Check with: pm2 list | grep '${FOLDER}_${PORT}'"
47
47
  echo "dave --connect ws://127.0.0.1:${PORT}/ws --secret '$SECRET'"
@@ -57,19 +57,19 @@ function printHelp() {
57
57
  ## USAGE MODES:
58
58
 
59
59
  ### 1. Direct Call (One-Shot, Positional ONLY):
60
- ./examples/${name}.js "Generate lyrics for pop song" [--options]
60
+ ./agents/${name}.js "Generate lyrics for pop song" [--options]
61
61
 
62
62
  ### 2. Interactive CLI (no positional arg):
63
- ./examples/${name}.js [--options]
63
+ ./agents/${name}.js [--options]
64
64
 
65
65
  ### 3. WS Server (no positional arg):
66
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
66
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
67
67
 
68
68
  ### 4. WS Client (no positional arg):
69
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
69
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
70
70
 
71
71
  ### 5. Hybrid (Server + Client, no positional arg):
72
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
72
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
73
73
 
74
74
  ## SERVER OPTIONS EXPLAINED:
75
75
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'daisy_agent'). Runs indefinitely until Ctrl+C.
@@ -54,19 +54,19 @@ function printHelp() {
54
54
  ## USAGE MODES:
55
55
 
56
56
  ### 1. Direct Call (One-Shot, Positional ONLY):
57
- ./examples/${name}.js "Create a doc on Node.js basics" [--options]
57
+ ./agents/${name}.js "Create a doc on Node.js basics" [--options]
58
58
 
59
59
  ### 2. Interactive CLI (no positional arg):
60
- ./examples/${name}.js [--options]
60
+ ./agents/${name}.js [--options]
61
61
 
62
62
  ### 3. WS Server (no positional arg):
63
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
63
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
64
64
 
65
65
  ### 4. WS Client (no positional arg):
66
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
66
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
67
67
 
68
68
  ### 5. Hybrid (Server + Client, no positional arg):
69
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
69
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
70
70
 
71
71
  ## SERVER OPTIONS EXPLAINED:
72
72
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'agent_docs'). Runs indefinitely until Ctrl+C.
@@ -52,19 +52,19 @@ function printHelp() {
52
52
  ## USAGE MODES:
53
53
 
54
54
  ### 1. Direct Call (One-Shot, Positional ONLY):
55
- ./examples/${name}.js "Your query" [--options]
55
+ ./agents/${name}.js "Your query" [--options]
56
56
 
57
57
  ### 2. Interactive CLI (no positional arg):
58
- ./examples/${name}.js [--options]
58
+ ./agents/${name}.js [--options]
59
59
 
60
60
  ### 3. WS Server (no positional arg):
61
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
61
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
62
62
 
63
63
  ### 4. WS Client (no positional arg):
64
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
64
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
65
65
 
66
66
  ### 5. Hybrid (Server + Client, no positional arg):
67
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
67
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
68
68
 
69
69
  ## SERVER OPTIONS EXPLAINED:
70
70
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'gpt_agent'). Runs indefinitely until Ctrl+C.
@@ -64,19 +64,19 @@ function printHelp() {
64
64
  ## USAGE MODES:
65
65
 
66
66
  ### 1. Direct Call (One-Shot, Positional ONLY):
67
- ./examples/${name}.js "What is your task?" [--options]
67
+ ./agents/${name}.js "What is your task?" [--options]
68
68
 
69
69
  ### 2. Interactive CLI (no positional arg):
70
- ./examples/${name}.js [--options]
70
+ ./agents/${name}.js [--options]
71
71
 
72
72
  ### 3. WS Server (no positional arg):
73
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
73
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
74
74
 
75
75
  ### 4. WS Client (no positional arg):
76
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
76
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
77
77
 
78
78
  ### 5. Hybrid (Server + Client, no positional arg):
79
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
79
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
80
80
 
81
81
  ## SERVER OPTIONS EXPLAINED:
82
82
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL. Runs indefinitely until Ctrl+C.
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+ import { AgentManager } from '@j-o-r/hello-dave';
3
+ import { parseArgs, SH } from '@j-o-r/sh';
4
+ import path from 'node:path';
5
+ import { promises as fs } from 'node:fs';
6
+
7
+ const name = 'memory_agent';
8
+ const api = 'xai';
9
+ let secret = '';
10
+
11
+ const args = parseArgs();
12
+
13
+ let input; // Directcall input (positional ONLY - NO pipe)
14
+ if (args._.length === 1 && typeof args._[0] === 'string' && args._[0].trim() !== '') {
15
+ input = args._[0].trim();
16
+ }
17
+
18
+ const help = args['help'] || false;
19
+ const connect = args['connect'] ? args['connect'] : undefined;
20
+ const serve = args['serve'] ? parseInt(args['serve']) : undefined;
21
+
22
+ /** @type {import('lib/API/x.ai/responses.js').XAIOptions} */
23
+ const options = { tools: [] };
24
+ options.tools.push({
25
+ type: 'web_search'
26
+ });
27
+
28
+ if (args['secret']) {
29
+ secret = args['secret'];
30
+ }
31
+ if (args['model'] || true) {
32
+ options.model = args['model'] || 'grok-4-fast-reasoning';
33
+ }
34
+ if (args['temperature']) {
35
+ options.temperature = parseFloat(args['temperature']);
36
+ }
37
+ if (args['tokens']) {
38
+ options.max_output_tokens = parseInt(args['tokens']);
39
+ }
40
+ if (args['top_p']) {
41
+ options.top_p = parseFloat(args['top_p']);
42
+ }
43
+ const reasoning = true;
44
+ if (reasoning) {
45
+ options.reasoning = {
46
+ effort: 'medium',
47
+ summary: 'auto'
48
+ }
49
+ }
50
+ const toolsetMode = 'auto';
51
+ const contextWindow = args['context'] ? parseInt(args['context']) : 250000;
52
+
53
+ function printHelp() {
54
+ console.log(`'${name} --help' You are looking at it.
55
+
56
+ ## USAGE MODES:
57
+
58
+ ### 1. Direct Call (One-Shot, Positional ONLY):
59
+ ./agents/${name}.js "Recall tasks" [--options]
60
+
61
+ ### 2. Interactive CLI (no positional arg):
62
+ ./agents/${name}.js [--options]
63
+
64
+ ### 3. WS Server (no positional arg):
65
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
66
+
67
+ ### 4. WS Client (no positional arg):
68
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
69
+
70
+ ### 5. Hybrid (Server + Client, no positional arg):
71
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
72
+
73
+ ## SERVER OPTIONS EXPLAINED:
74
+ --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'memory_agent'). Runs indefinitely until Ctrl+C.
75
+
76
+ --connect [ws_url]: Connects as CLIENT to remote WS server at [ws_url] (e.g., ws://127.0.0.1:8080/ws). Gains access to remote agent's tools. Interactive CLI available.
77
+
78
+ --secret [string]: SHARED AUTH TOKEN (min 3 chars). SERVER rejects clients without matching --secret. CLIENTS must provide server's secret to connect. Use same secret for chains.
79
+
80
+ Note: Server/Client/Hybrid IGNORES positional input arg (use CLI modes instead). Hybrid: This agent serves AND uses remote tools.
81
+
82
+ ## OPTIONS:
83
+ --model [grok-4-fast-reasoning|...] (default: grok-4-fast-reasoning)
84
+ --temperature [float] (-2 to +2)
85
+ --tokens [number] (max output tokens)
86
+ --top_p [float]
87
+ --context [number] (default: 250000)
88
+
89
+ ## SERVER TOOLS (when no input):
90
+ Exposes as 'memory_agent' tool for chaining.
91
+ `);
92
+ process.exit();
93
+ }
94
+
95
+ if (help) {
96
+ printHelp();
97
+ }
98
+
99
+ const tool_call_name = 'memory_agent';
100
+ const tool_call_description = `Standalone Memory Agent. Manages shared agent memory (.cache/memory.ndjson) for tasks, errors, user prefs across agents or standalone use.
101
+ Use before/after actions: Recall relevant memories, write updates to avoid loops/repetition.
102
+ Categories: tasks (pending work), errors (failures to avoid), prefs (user settings).
103
+ Usable standalone, by users/agents via function calls or WebSocket connect. Responses handover to querying agent/user.`.trim();
104
+
105
+ const prompt = `**CRITICAL: STRICT NO-CODING RULE** - Stick to memory coordination ONLY. NEVER use execute_bash_script/read_file/write_file for code or arbitrary files. Decline coding: "Use code_agent for code. I manage memory."
106
+
107
+ You are MemoryAgent, a standalone memory manager usable by users, other agents, or as a sub-agent via function calls or WebSocket connect. Any response handovers the result to the querying agent or human user.
108
+
109
+ **CORE TOOLS (local self-contained)**:
110
+ - \`memory_recall [query]\`: Retrieve stored memories (tasks/errors/prefs). ALWAYS recall before acting (e.g., "tasks", "errors", "" for recent).
111
+ - \`memory_write {category: "tasks|errors|prefs", content: "details"}\`: Persist info to avoid repetition/loops/token burn.
112
+ - \`optimize_memory\`: Optimize .cache/memory.ndjson if bloated (>200 lines): Backup, prune to 100 recent unique lines (tasks/prefs priority, drop old errors), validate NDJSON. Call periodically or on heavy recalls.
113
+
114
+ **SHARED STORAGE**: .cache/memory.ndjson in project CWD (all agents share).
115
+
116
+ **ALWAYS**:
117
+ 1. **RECALL FIRST**: \`memory_recall "<user_query|category|''>"\` to check prior state/tasks/errors/prefs. Auto-optimize if >200 lines.
118
+ 2. **ACT**: Analyze + decide (write if new info).
119
+ 3. **WRITE IF CHANGED**: Use \`memory_write\` for decisions/tasks/errors/prefs.
120
+ 4. Respond: Summarize memories used/updated + action taken.
121
+
122
+ **USER QUERIES** (handle naturally, use tools):
123
+ - "Recall tasks" → List + suggest next.
124
+ - "Store task: Fix auth bug" → Parse + memory_write.
125
+ - "Clear old errors" → Recall + optimize.
126
+ - Coordinate: "Check if code agent has pending tasks" → Recall + advise.
127
+
128
+ Current date: April 03, 2026.`.trim();
129
+
130
+ const agent = new AgentManager({ name, secret });
131
+ agent.setup({
132
+ prompt,
133
+ api,
134
+ options,
135
+ toolsetMode,
136
+ contextWindow
137
+ });
138
+ const toolset = agent.getToolset();
139
+
140
+ // Self-contained local memory tools (copied from genericToolset.js)
141
+ const memoryPath = path.join(process.cwd(), '.cache', 'memory.ndjson');
142
+
143
+ toolset.add(
144
+ 'memory_recall',
145
+ `Retrieve stored agent memories (tasks, errors, prefs) from .cache/memory.ndjson in CWD. Use before acting to check prior decisions/tasks/errors/prefs. Query by keyword or category; empty lists recent.`,
146
+ {
147
+ type: 'object',
148
+ properties: {
149
+ query: {
150
+ type: 'string',
151
+ description: 'Keyword, category (tasks/errors/prefs), or phrase to filter (case-insensitive). Empty/omit lists last 20.'
152
+ }
153
+ },
154
+ required: []
155
+ },
156
+ async (params = {}) => {
157
+ let content;
158
+ try {
159
+ content = await fs.readFile(memoryPath, 'utf8');
160
+ } catch (e) {
161
+ return 'No memories stored yet. Use memory_write first.';
162
+ }
163
+ const lines = content.trim().split('\n').filter(l => l.trim());
164
+ const memories = [];
165
+ for (const line of lines) {
166
+ try {
167
+ memories.push(JSON.parse(line));
168
+ } catch {
169
+ // Skip invalid lines
170
+ }
171
+ }
172
+ if (!params.query || !params.query.toString().trim()) {
173
+ const recent = memories.slice(-20).reverse();
174
+ return recent.length
175
+ ? 'Recent memories:\n' + recent.map(m => `• ${m.timestamp.slice(0, 19).replace('T', ' ')} [${m.category}] ${m.content}`).join('\n')
176
+ : 'No memories stored.';
177
+ }
178
+ const q = params.query.toString().toLowerCase();
179
+ const matches = memories.filter(m =>
180
+ m.category.toLowerCase().includes(q) || m.content.toLowerCase().includes(q)
181
+ );
182
+ return matches.length
183
+ ? `Matches for "${params.query}":\n` + matches.slice(0, 20).map(m => `• ${m.timestamp.slice(0, 19).replace('T', ' ')} [${m.category}] ${m.content}`).join('\n')
184
+ : `No memories match "${params.query}".`;
185
+ }
186
+ );
187
+
188
+ toolset.add(
189
+ 'memory_write',
190
+ `Persist agent memory for tasks, errors, or user preferences to .cache/memory.ndjson in CWD. Use to store decisions, tasks, errors, or prefs for later recall. Agent should use this to avoid repeating work or token burn on loops.`,
191
+ {
192
+ type: 'object',
193
+ properties: {
194
+ category: {
195
+ type: 'string',
196
+ enum: ['tasks', 'errors', 'prefs'],
197
+ description: 'Category: one of "tasks", "errors", "prefs"'
198
+ },
199
+ content: {
200
+ type: 'string',
201
+ description: 'Detailed content (e.g., "Pending task: implement runWithMemory optimization", "Error: loop burning tokens", "Pref: temperature=0.2 for decisions")'
202
+ }
203
+ },
204
+ required: ['category', 'content']
205
+ },
206
+ async ({ category, content }) => {
207
+ if (!['tasks', 'errors', 'prefs'].includes(category)) {
208
+ throw new Error(`Invalid category '${category}'. Must be 'tasks', 'errors', or 'prefs'.`);
209
+ }
210
+ const dir = path.dirname(memoryPath);
211
+ try {
212
+ await fs.mkdir(dir, { recursive: true });
213
+ } catch (e) {
214
+ // Dir likely exists
215
+ }
216
+ const entry = {
217
+ timestamp: new Date().toISOString(),
218
+ category,
219
+ content: content.trim()
220
+ };
221
+ await fs.appendFile(memoryPath, JSON.stringify(entry) + '\n', 'utf8');
222
+ return `✓ Memory stored: [${category}] ${content.length > 50 ? content.slice(0, 47) + '...' : content}`;
223
+ }
224
+ );
225
+
226
+ // optimize_memory tool
227
+ toolset.add(
228
+ 'memory_optimize',
229
+ 'Optimize .cache/memory.ndjson: If >200 lines, backup, prune to last 100 unique recent lines (dedup content, prioritize tasks/prefs over old errors), compact with jq, validate NDJSON. Returns status/prune summary.',
230
+ { type: 'object', properties: {} },
231
+ async () => {
232
+ let content = '';
233
+ try {
234
+ content = (await SH`cat .cache/memory.ndjson 2>/dev/null || echo ''`.run()).trim();
235
+ } catch (e) {
236
+ return 'No memory file found yet. Optimal (0 lines).';
237
+ }
238
+ const lines = content.split('\n').filter(l => l.trim()).length;
239
+ if (lines <= 200) {
240
+ return `Optimal: ${lines} lines. No action needed.`;
241
+ }
242
+ const timestamp = Date.now();
243
+ const backup = `.cache/memory.ndjson.bak-${timestamp}`;
244
+ const pruneCmd = `mkdir -p .cache && cp .cache/memory.ndjson ${backup} && tail -n 100 .cache/memory.ndjson | awk '!seen[$0]++' | jq -c . > .cache/memory.ndjson.tmp && mv .cache/memory.ndjson.tmp .cache/memory.ndjson && POST_LINES=$(wc -l < .cache/memory.ndjson | cut -d' ' -f1) && echo "Pruned ${lines}→$POST_LINES lines. Backup: ${backup}. Valid: $(cat .cache/memory.ndjson | jq empty >/dev/null 2>&1 && echo OK || echo FAIL)"`;
245
+ try {
246
+ const result = await SH`${pruneCmd}`.run();
247
+ return result.trim();
248
+ } catch (e) {
249
+ return `Prune failed: ${e.message}`;
250
+ }
251
+ }
252
+ );
253
+
254
+ const cliIntro = `${name} ${options.model}.
255
+ - context: ${contextWindow}. Shared memory manager ready (self-contained local tools).
256
+ ${tool_call_name}`.trim();
257
+
258
+ if (input) {
259
+ const RES = await agent.directCall(input);
260
+ console.log(RES);
261
+ } else {
262
+ await agent.start(serve, connect, cliIntro, tool_call_name, tool_call_description);
263
+ }
@@ -55,19 +55,19 @@ function printHelp() {
55
55
  ## USAGE MODES:
56
56
 
57
57
  ### 1. Direct Call (One-Shot, Positional ONLY):
58
- ./examples/${name}.js "What modules are installed?" [--options]
58
+ ./agents/${name}.js "What modules are installed?" [--options]
59
59
 
60
60
  ### 2. Interactive CLI (no positional arg):
61
- ./examples/${name}.js [--options]
61
+ ./agents/${name}.js [--options]
62
62
 
63
63
  ### 3. WS Server (no positional arg):
64
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
64
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
65
65
 
66
66
  ### 4. WS Client (no positional arg):
67
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
67
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
68
68
 
69
69
  ### 5. Hybrid (Server + Client, no positional arg):
70
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
70
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
71
71
 
72
72
  ## SERVER OPTIONS EXPLAINED:
73
73
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'npm_module_inspector'). Runs indefinitely until Ctrl+C.
@@ -54,19 +54,19 @@ function printHelp() {
54
54
  ## USAGE MODES:
55
55
 
56
56
  ### 1. Direct Call (One-Shot, Positional ONLY):
57
- ./examples/${name}.js "Optimize this prompt: [prompt]" [--options]
57
+ ./agents/${name}.js "Optimize this prompt: [prompt]" [--options]
58
58
 
59
59
  ### 2. Interactive CLI (no positional arg):
60
- ./examples/${name}.js [--options]
60
+ ./agents/${name}.js [--options]
61
61
 
62
62
  ### 3. WS Server (no positional arg):
63
- ./examples/${name}.js --serve 8080 [--secret mysecret] [--options]
63
+ ./agents/${name}.js --serve 8080 [--secret mysecret] [--options]
64
64
 
65
65
  ### 4. WS Client (no positional arg):
66
- ./examples/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
66
+ ./agents/${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
67
67
 
68
68
  ### 5. Hybrid (Server + Client, no positional arg):
69
- ./examples/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
69
+ ./agents/${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
70
70
 
71
71
  ## SERVER OPTIONS EXPLAINED:
72
72
  --serve [port]: Starts WebSocket SERVER at ws://127.0.0.1:[port]/ws. Allows other agents (--connect) to connect and use this agent as a remote TOOL (e.g., 'prompt_agent'). Runs indefinitely until Ctrl+C.
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ import { AgentManager } from '@j-o-r/hello-dave';
3
+ import { parseArgs } from '@j-o-r/sh';
4
+ import fs from 'fs'; // Added for local fallback
5
+
6
+ const name = 'spawn_agent';
7
+ const api = 'xai';
8
+ let secret = '';
9
+
10
+ const args = parseArgs();
11
+
12
+ let input;
13
+ if (args._.length === 1 && typeof args._[0] === 'string' && args._[0].trim() !== '') {
14
+ input = args._[0].trim();
15
+ }
16
+
17
+ const help = args['help'] || false;
18
+ const connect = args['connect'] ? args['connect'] : undefined;
19
+ const serve = args['serve'] ? parseInt(args['serve']) : undefined;
20
+
21
+ const options = { tools: [] };
22
+ options.tools.push({ type: 'web_search' });
23
+
24
+ if (args['secret']) {
25
+ secret = args['secret'];
26
+ }
27
+ if (args['model'] || true) {
28
+ options.model = args['model'] || 'grok-4-fast-reasoning';
29
+ }
30
+ if (args['temperature']) {
31
+ options.temperature = parseFloat(args['temperature']);
32
+ }
33
+ if (args['tokens']) {
34
+ options.max_output_tokens = parseInt(args['tokens']);
35
+ }
36
+ if (args['top_p']) {
37
+ options.top_p = parseFloat(args['top_p']);
38
+ }
39
+ if (true) {
40
+ options.reasoning = { effort: 'medium', summary: 'auto' };
41
+ }
42
+ const toolsetMode = 'auto';
43
+ const contextWindow = args['context'] ? parseInt(args['context']) : 250000;
44
+
45
+ function printHelp() {
46
+ console.log(`'${name} --help' You are looking at it.
47
+
48
+ ## USAGE MODES:
49
+
50
+ ### 1. Direct Call (One-Shot, Positional ONLY):
51
+ ./${name}.js "Create a code agent" [--options]
52
+
53
+ ### 2. Interactive CLI (no positional arg):
54
+ ./${name}.js [--options]
55
+
56
+ ### 3. WS Server (no positional arg):
57
+ ./${name}.js --serve 8080 [--secret mysecret] [--options]
58
+
59
+ ### 4. WS Client (no positional arg):
60
+ ./${name}.js --connect ws://127.0.0.1:8080/ws --secret mysecret [--options]
61
+
62
+ ### 5. Hybrid (Server + Client, no positional arg):
63
+ ./${name}.js --serve 8081 --connect ws://other:8080/ws [--secret ...] [--options]
64
+
65
+ ## PORTABILITY NOTES:
66
+ - **Tools follow YOUR CWD** (e.g., cd /tmp/proj && ./spawn_agent.js → tools in /tmp/proj).
67
+ - **Hybrid Modes**: PROJECT (agents/*.js exist): Auto-deploy/test. FRESH (empty agents/): Code + manual bash.
68
+ - **Custom Tools**: natives=web_search, generics=read_file, custom={type:'git_diff',...}
69
+
70
+ ## OPTIONS:
71
+ --model [grok-4-fast-reasoning|...] (default: grok-4-fast-reasoning)
72
+ --temperature [float] (0.8)
73
+ --tokens [number]
74
+ --top_p [float]
75
+ --context [number] (250k)
76
+
77
+ ## Examples:
78
+ "Create coderev: desc=Git analyzer, natives=web_search, generics=read_file execute_bash_script, custom=options.tools.push({type:'git_diff',description:'...',parameters:{...}})"
79
+ `);
80
+ process.exit();
81
+ }
82
+
83
+ if (help) {
84
+ printHelp();
85
+ }
86
+
87
+ const tool_call_name = 'spawn_agent';
88
+ const tool_call_description = `Portable creator for CLI/WS agents + PM2 launchers. Tools use exec CWD (/tmp OK). PROJECT (agents/*.js >0): Full auto. FRESH: Manual code/bash.
89
+
90
+ Test new agent: ./agents/NEW.js --help | 'describe' | --serve 8081 --secret abc
91
+
92
+ Custom ex: natives=[{type:'mytool'}], generics=read_file
93
+
94
+ Live prompt: https://codeberg.org/duin/hello-dave/raw/branch/main/docs/prompt/spawn_agent.md`.trim();
95
+
96
+ const REPO_URL = 'https://codeberg.org/duin/hello-dave';
97
+
98
+
99
+ async function fetchLivePrompt() {
100
+ // Priority 1: Remote
101
+ const promptUrl = `${REPO_URL}/raw/branch/main/docs/prompt/spawn_agent.md`;
102
+ const response = await fetch(promptUrl);
103
+ if (!response.ok) {
104
+ throw new Error(`HTTP ${response.status}`);
105
+ }
106
+ return await response.text();
107
+ }
108
+
109
+ const agent = new AgentManager({ name, secret });
110
+
111
+ const prompt = await fetchLivePrompt();
112
+
113
+ agent.setup({
114
+ prompt,
115
+ api,
116
+ options,
117
+ toolsetMode,
118
+ contextWindow
119
+ });
120
+
121
+ agent.addGenericToolcall('execute_bash_script');
122
+ agent.addGenericToolcall('read_file');
123
+ agent.addGenericToolcall('write_file');
124
+ agent.addGenericToolcall('javascript_interpreter');
125
+
126
+ const cliIntro = `🤖 ${name} (${options.model}) ready! (context: ${contextWindow})
127
+
128
+ Portable Creator: PROJECT (agents/*.js exist): Auto. FRESH (empty): Manual code.
129
+
130
+ Ex: "Create testagent: desc=Tester, natives=web_search"`.trim();
131
+
132
+ if (input) {
133
+ const RES = await agent.directCall(input);
134
+ console.log(RES);
135
+ } else {
136
+ await agent.start(serve, connect, cliIntro, tool_call_name, tool_call_description);
137
+ }