@j-o-r/hello-dave 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -33
- package/README.md +240 -0
- package/TODO.md +13 -0
- package/{examples → agents}/ask_agent.js +5 -5
- package/{examples → agents}/codeserver.sh +14 -14
- package/{examples → agents}/daisy_agent.js +5 -5
- package/{examples → agents}/docs_agent.js +5 -5
- package/{examples → agents}/gpt_agent.js +5 -5
- package/{examples → agents}/grok_agent.js +5 -5
- package/{examples → agents}/memory_agent.js +5 -5
- package/{examples → agents}/npm_agent.js +5 -5
- package/{examples → agents}/prompt_agent.js +5 -5
- package/agents/spawn_agent.js +137 -0
- package/{examples → agents}/test_agent.js +6 -6
- package/{examples → agents}/todo_agent.js +5 -5
- package/bin/codeDave +58 -0
- package/bin/dave.js +3 -5
- package/docs/agent-manager.md +244 -0
- package/docs/bin-dave.md +62 -0
- package/docs/codeserver-pattern.md +191 -0
- package/docs/generic-toolset.md +326 -0
- package/docs/howtos/agent-networking.md +253 -0
- package/docs/howtos/spawn-agents.md.bak +200 -0
- package/docs/howtos/spawn-agents.md.bak_new +200 -0
- package/docs/jsdoc-best-practices.md +278 -0
- package/docs/multi-agent-clusters.md +265 -0
- package/docs/multi-agent-clusters.md.bak +229 -0
- package/docs/path-resolution-best-practices.md +104 -0
- package/docs/project-overview.md +67 -0
- package/docs/prompt/spawn_agent.md +173 -0
- package/docs/prompt/spawn_agent.md.bak +201 -0
- package/docs/prompt-class.md +141 -0
- package/docs/suggestions.md +38 -0
- package/docs/todo-archive-v0.0.8.md +1 -0
- package/docs/todo-archive.md +44 -0
- package/docs/tools-syntax-validation.md +121 -0
- package/docs/toolset.md +164 -0
- package/docs/xai-responses.md +111 -0
- package/docs/xai_collections.md +106 -0
- package/lib/AgentClient.js +111 -67
- package/lib/AgentManager.js +111 -80
- package/lib/AgentServer.js +144 -104
- package/lib/Cli.js +126 -93
- package/lib/Prompt.js +38 -5
- package/lib/Session.js +102 -79
- package/lib/ToolSet.js +79 -60
- package/lib/fafs.js +54 -19
- package/lib/genericToolset.js +129 -136
- package/lib/wsCli.js +50 -19
- package/lib/wsIO.js +10 -6
- package/package.json +3 -3
- package/types/AgentClient.d.ts +69 -35
- package/types/AgentManager.d.ts +50 -56
- package/types/AgentServer.d.ts +63 -16
- package/types/Cli.d.ts +56 -10
- package/types/Prompt.d.ts +36 -4
- package/types/Session.d.ts +23 -9
- package/types/ToolSet.d.ts +49 -32
- package/types/fafs.d.ts +68 -25
- package/types/wsCli.d.ts +14 -0
- package/types/wsIO.d.ts +9 -5
- package/utils/search_sessions.sh +100 -53
- package/bin/spawn_agent.js +0 -293
- package/lib/genericToolset.js.bak_syntax +0 -402
- /package/{examples → agents}/code_agent.js +0 -0
- /package/{examples → agents}/readme_agent.js +0 -0
package/lib/AgentManager.js
CHANGED
|
@@ -1,56 +1,83 @@
|
|
|
1
1
|
import { Prompt, Cli, AgentClient, AgentServer, API, ToolSet, Session, env } from './index.js';
|
|
2
2
|
import toolsPool from './genericToolset.js'
|
|
3
3
|
/**
|
|
4
|
-
* @
|
|
5
|
-
* @
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
4
|
+
* @module lib/AgentManager
|
|
5
|
+
* @exports default AgentManager
|
|
6
|
+
* High-level orchestrator for AI agent lifecycle: configures Prompt/Session/ToolSet, launches CLI/Server/Client modes.
|
|
7
|
+
* Supports chaining setup() → start(); adds generic tools; direct calls.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {import('./API/x.ai/text.js').XOptions} XOptions
|
|
12
|
+
* @typedef {import('./API/x.ai/responses.js').XAIOptions} XAIOptions
|
|
13
|
+
* @typedef {import('./API/openai.com/reponses/text.js').OAOptions} OAOptions
|
|
14
|
+
* @typedef {import('./API/anthropic.com/text.js').ANTHOptions} ANTHOptions
|
|
15
|
+
*/
|
|
9
16
|
/**
|
|
10
|
-
* @typedef {Object} Setup
|
|
11
|
-
* @property {string} prompt - Initial system prompt
|
|
12
|
-
* @property {XAIOptions|OAOptions|XOptions|ANTHOptions} options -
|
|
13
|
-
* @property {'gpt'|'xai'|'claude'} api - AI
|
|
14
|
-
* @property {number} [contextWindow] -
|
|
15
|
-
* @property {'auto'|'required'|
|
|
16
|
-
* @property {boolean} [debug] - verbose output
|
|
17
|
-
*/
|
|
17
|
+
* @typedef {Object} Setup
|
|
18
|
+
* @property {string} prompt - Initial system prompt.
|
|
19
|
+
* @property {XAIOptions|OAOptions|XOptions|ANTHOptions} options - API model options.
|
|
20
|
+
* @property {'gpt'|'xai'|'claude'} api - AI provider.
|
|
21
|
+
* @property {number} [contextWindow=300000] - Token limit for context.
|
|
22
|
+
* @property {'auto'|'required'|null} [toolsetMode] - Toolset activation mode.
|
|
23
|
+
* @property {boolean} [debug] - Enable verbose output.
|
|
24
|
+
*/
|
|
18
25
|
/**
|
|
19
|
-
* @typedef {Object} Options
|
|
20
|
-
* @property {string} name - Agent name
|
|
21
|
-
* @property {string} secret -
|
|
22
|
-
* @property {string} [cachePath] -
|
|
23
|
-
|
|
26
|
+
* @typedef {Object} Options
|
|
27
|
+
* @property {string} name - Agent name (validated /^[a-z_0-9]{2,}$/).
|
|
28
|
+
* @property {string} secret - WS auth secret (base64-encoded).
|
|
29
|
+
* @property {string} [cachePath='.cache/hello-dave'] - Session cache directory.
|
|
30
|
+
* @example { name: 'code-agent', secret: 'mysecret' }
|
|
31
|
+
*/
|
|
32
|
+
/** @const {RegExp} Validates agent/tool names (lowercase a-z0-9_, min 2 chars). */
|
|
33
|
+
const validNameRegex = /^[a-z_0-9]{2,}$/;
|
|
34
|
+
|
|
24
35
|
class AgentManager {
|
|
25
|
-
/** @type {Prompt} */
|
|
36
|
+
/** @private @type {Prompt} */
|
|
26
37
|
#prompt;
|
|
27
|
-
/** @type {Session} */
|
|
38
|
+
/** @private @type {Session} */
|
|
28
39
|
#sessionStorage;
|
|
40
|
+
/** @private @type {string} */
|
|
29
41
|
#name = 'agent';
|
|
42
|
+
/** @private @type {string} */
|
|
30
43
|
#secret = '';
|
|
44
|
+
/** @private @type {string} */
|
|
31
45
|
#cachePath = '.cache/hello-dave';
|
|
46
|
+
/** @private @type {boolean} */
|
|
32
47
|
#debug = false;
|
|
48
|
+
/** @private @type {string} */
|
|
33
49
|
#model = '';
|
|
50
|
+
/** @private @type {number} */
|
|
34
51
|
#contextWindow = 0;
|
|
52
|
+
/** @private @type {string} */
|
|
35
53
|
#sysPrompt = '';
|
|
54
|
+
|
|
36
55
|
/**
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
* Initializes AgentManager with base options.
|
|
57
|
+
* Validates name regex; encodes secret.
|
|
58
|
+
* @param {Options} options - Base configuration.
|
|
59
|
+
* @throws {Error} Invalid name (regex) or options.
|
|
60
|
+
* @chainable
|
|
61
|
+
*/
|
|
39
62
|
constructor(options) {
|
|
40
63
|
this.#name = options.name || this.#name;
|
|
41
64
|
if (options.secret && typeof options.secret === 'string') {
|
|
42
65
|
this.#secret = Buffer.from(options.secret).toString('base64');
|
|
43
66
|
}
|
|
44
|
-
const validNameRegex = /^[a-z_0-9]{2,}$/;
|
|
45
67
|
if (!validNameRegex.test(this.#name)) {
|
|
46
|
-
throw new Error(`Invalid agent 'name'
|
|
68
|
+
throw new Error(`Invalid agent 'name': '${this.#name}'. Must match /^[a-z_0-9]{2,}$/`);
|
|
47
69
|
}
|
|
48
70
|
this.#cachePath = options.cachePath || this.#cachePath;
|
|
49
71
|
}
|
|
50
72
|
|
|
51
73
|
/**
|
|
52
|
-
|
|
53
|
-
|
|
74
|
+
* Configures the Prompt/Session/ToolSet with API adaptor.
|
|
75
|
+
* Adds system prompt; chains to start().
|
|
76
|
+
* @param {Setup} setup - AI setup details.
|
|
77
|
+
* @returns {AgentManager} This instance (chainable).
|
|
78
|
+
* @throws {Error} Invalid setup.
|
|
79
|
+
* @example mgr.setup({ prompt: 'You are a coder...', api: 'gpt', options: { model: 'gpt-4o' } });
|
|
80
|
+
*/
|
|
54
81
|
setup(setup) {
|
|
55
82
|
const {
|
|
56
83
|
prompt,
|
|
@@ -63,9 +90,6 @@ class AgentManager {
|
|
|
63
90
|
this.#sysPrompt = prompt;
|
|
64
91
|
this.#contextWindow = contextWindow;
|
|
65
92
|
if (options?.model) this.#model = options.model;
|
|
66
|
-
this.#sysPrompt = prompt;
|
|
67
|
-
this.#contextWindow = contextWindow;
|
|
68
|
-
if (options?.model) this.#model = options.model;
|
|
69
93
|
let toolset;
|
|
70
94
|
if (toolsetMode) {
|
|
71
95
|
toolset = new ToolSet(toolsetMode);
|
|
@@ -77,43 +101,48 @@ class AgentManager {
|
|
|
77
101
|
this.#sessionStorage = new Session(this.#name, this.#prompt, this.#cachePath);
|
|
78
102
|
this.#prompt.add('system', prompt, true);
|
|
79
103
|
this.#prompt.setAdaptor(API.text[api], toolset, options);
|
|
80
|
-
return this;
|
|
104
|
+
return this;
|
|
81
105
|
}
|
|
82
106
|
|
|
83
107
|
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
108
|
+
* @private
|
|
109
|
+
* Launches interactive CLI mode.
|
|
110
|
+
* @param {string} description - CLI intro message.
|
|
111
|
+
* @returns {void}
|
|
112
|
+
* @throws {Error} No setup() called.
|
|
113
|
+
*/
|
|
87
114
|
#startCli(description) {
|
|
88
115
|
if (!this.#prompt) throw new Error('Run setup first');
|
|
89
116
|
const cli = new Cli({ prompt: this.#prompt, session: this.#sessionStorage, description });
|
|
90
117
|
setTimeout(() => {
|
|
91
|
-
// This resolves issues with log output after the console has been started
|
|
92
118
|
cli.start();
|
|
93
119
|
}, 1000);
|
|
94
120
|
}
|
|
95
121
|
|
|
96
122
|
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
123
|
+
* @private
|
|
124
|
+
* Attaches this agent as a WS client to another server (for chaining agents).
|
|
125
|
+
* @param {string} name - Tool name.
|
|
126
|
+
* @param {string} description - Tool desc.
|
|
127
|
+
* @param {string} [url='ws://127.0.0.1:8000/ws'] - Target WS URL.
|
|
128
|
+
* @returns {AgentClient} New client instance.
|
|
129
|
+
* @throws {Error} No setup().
|
|
130
|
+
*/
|
|
104
131
|
#attach(name, description, url = 'ws://127.0.0.1:8000/ws') {
|
|
105
132
|
if (!this.#prompt) throw new Error('Run setup first');
|
|
106
133
|
return new AgentClient({ prompt: this.#prompt, name, description, url, secret: this.#secret });
|
|
107
134
|
}
|
|
108
135
|
|
|
109
136
|
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
137
|
+
* @private
|
|
138
|
+
* Enables server mode: Registers this agent for remote tool calls.
|
|
139
|
+
* Optionally attaches as client too.
|
|
140
|
+
* @param {string} name - Server/tool name.
|
|
141
|
+
* @param {string} [description=''] - Desc (auto from sysPrompt).
|
|
142
|
+
* @param {number} [port=8000] - Port.
|
|
143
|
+
* @returns {void}
|
|
144
|
+
* @throws {Error} No setup/toolset.
|
|
145
|
+
*/
|
|
117
146
|
#enableServer(name, description = '', port = 8000) {
|
|
118
147
|
if (!this.#prompt) throw new Error('Run setup first');
|
|
119
148
|
if (!this.#prompt.toolset) throw new Error('No toolset defined');
|
|
@@ -125,64 +154,68 @@ class AgentManager {
|
|
|
125
154
|
prompt: this.#prompt,
|
|
126
155
|
session: this.#sessionStorage,
|
|
127
156
|
debug: this.#debug
|
|
128
|
-
|
|
129
157
|
});
|
|
130
|
-
// trigger reset on all Agents
|
|
131
158
|
this.#prompt.on('reset', () => {
|
|
132
|
-
// Generate new context for all Agents
|
|
133
159
|
server.resetAll();
|
|
134
|
-
})
|
|
160
|
+
});
|
|
135
161
|
}
|
|
162
|
+
|
|
136
163
|
/**
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
164
|
+
* Direct synchronous call to the underlying Prompt.
|
|
165
|
+
* @param {string} input - User input.
|
|
166
|
+
* @returns {Promise<string>} Response.
|
|
167
|
+
* @throws {Error} No setup.
|
|
168
|
+
*/
|
|
141
169
|
async directCall(input) {
|
|
142
170
|
const res = await this.#prompt.call(input);
|
|
143
171
|
return res;
|
|
144
172
|
}
|
|
145
|
-
|
|
173
|
+
|
|
174
|
+
/** @returns {Prompt} Underlying Prompt instance. */
|
|
146
175
|
getPrompt() { return this.#prompt; }
|
|
147
|
-
|
|
176
|
+
|
|
177
|
+
/** @returns {ToolSet|null} Toolset if configured. */
|
|
148
178
|
getToolset() { return this.#prompt.toolset; }
|
|
149
|
-
|
|
179
|
+
|
|
180
|
+
/** @returns {Promise<import('./fafs.js').EnvironmentInfo>} System env info. */
|
|
150
181
|
async environment() {
|
|
151
182
|
return env();
|
|
152
183
|
}
|
|
184
|
+
|
|
153
185
|
/**
|
|
154
|
-
* Adds a pre-defined generic tool from
|
|
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 -
|
|
156
|
-
* @throws {Error}
|
|
186
|
+
* Adds a pre-defined generic tool from toolsPool to this agent's ToolSet.
|
|
187
|
+
* @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.
|
|
188
|
+
* @throws {Error} Invalid name, no toolset, or tool missing.
|
|
189
|
+
* @example mgr.addGenericToolcall('read_file');
|
|
157
190
|
*/
|
|
158
191
|
addGenericToolcall(name) {
|
|
159
|
-
const validNameRegex = /^[a-z_0-9]{2,}$/;
|
|
160
192
|
if (!validNameRegex.test(name)) {
|
|
161
|
-
throw new Error(`Invalid 'name': '${name}'. Must match /^[a-z_0-9]{2,}
|
|
193
|
+
throw new Error(`Invalid 'name': '${name}'. Must match /^[a-z_0-9]{2,}$/`);
|
|
162
194
|
}
|
|
163
|
-
if (!this.#prompt.toolset) throw new Error('No ToolSet defined')
|
|
195
|
+
if (!this.#prompt.toolset) throw new Error('No ToolSet defined');
|
|
164
196
|
let tool = toolsPool.get(name);
|
|
165
|
-
if (!tool) throw new Error(
|
|
197
|
+
if (!tool) throw new Error(`Tool '${name}' not found in pool`);
|
|
166
198
|
this.#prompt.toolset.add(name, tool.description, tool.parameters, tool.method);
|
|
167
199
|
}
|
|
168
200
|
|
|
169
201
|
/**
|
|
170
|
-
* Smart launcher:
|
|
171
|
-
*
|
|
172
|
-
* @param {
|
|
173
|
-
* @param {string} [
|
|
174
|
-
* @param {string} [
|
|
175
|
-
* @param {string} [
|
|
202
|
+
* Smart launcher: CLI (default), server (servePort), or client (connectUrl).
|
|
203
|
+
* Auto-generates intros/descriptions if empty.
|
|
204
|
+
* @param {number} [servePort] - Launch server on port.
|
|
205
|
+
* @param {string} [connectUrl] - Connect as client to WS.
|
|
206
|
+
* @param {string} [cliIntro=""] - CLI intro text.
|
|
207
|
+
* @param {string} [toolName=""] - Tool/server name (falls back to #name).
|
|
208
|
+
* @param {string} [toolDescription=""] - Tool desc.
|
|
209
|
+
* @returns {Promise<void>}
|
|
210
|
+
* @throws {Error} No setup; invalid names/ports.
|
|
211
|
+
* @example mgr.start(8000); // Server\nmgr.start(undefined, 'ws://other:8001/ws'); // Client\nmgr.start(); // CLI
|
|
176
212
|
*/
|
|
177
213
|
async start(servePort, connectUrl, cliIntro = "", toolName = "", toolDescription = "") {
|
|
178
214
|
if (!this.#prompt) throw new Error("Run setup first");
|
|
179
215
|
|
|
180
|
-
const validNameRegex = /^[a-z_0-9]{2,}$/;
|
|
181
|
-
|
|
182
216
|
toolName = toolName || this.#name;
|
|
183
|
-
// Validate 'toolName' (or fallback agent name)
|
|
184
217
|
if (!validNameRegex.test(toolName)) {
|
|
185
|
-
throw new Error(`Invalid 'toolName'
|
|
218
|
+
throw new Error(`Invalid 'toolName': '${toolName}'. Must match /^[a-z_0-9]{2,}$/`);
|
|
186
219
|
}
|
|
187
220
|
|
|
188
221
|
if (!toolDescription && this.#sysPrompt) {
|
|
@@ -190,22 +223,20 @@ class AgentManager {
|
|
|
190
223
|
}
|
|
191
224
|
|
|
192
225
|
if (!cliIntro) {
|
|
193
|
-
const introStr = this.#name
|
|
226
|
+
const introStr = `${this.#name} ${this.#model || "unknown-model"} - context: ${this.#contextWindow}`;
|
|
194
227
|
cliIntro = introStr.trim();
|
|
195
228
|
}
|
|
229
|
+
|
|
196
230
|
if (servePort) {
|
|
197
231
|
console.log(toolName);
|
|
198
232
|
console.log(toolDescription);
|
|
199
233
|
this.#enableServer(toolName, toolDescription, servePort);
|
|
200
|
-
// A server can also be a client
|
|
201
234
|
if (connectUrl) {
|
|
202
235
|
this.#attach(toolName, toolDescription, connectUrl);
|
|
203
236
|
}
|
|
204
237
|
} else if (connectUrl) {
|
|
205
|
-
// Connect to a agent 'server' and enable via websocket / toolcalls
|
|
206
238
|
this.#attach(toolName, toolDescription, connectUrl);
|
|
207
239
|
} else {
|
|
208
|
-
// Terminal user CLI
|
|
209
240
|
this.#startCli(cliIntro);
|
|
210
241
|
}
|
|
211
242
|
}
|