@j-o-r/hello-dave 0.1.0 → 0.1.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 (173) hide show
  1. package/CHANGELOG.md +42 -25
  2. package/README.md +81 -221
  3. package/TODO.md +173 -35
  4. package/agents/agent_creator.js +105 -0
  5. package/agents/agent_creator.prompt.md +371 -0
  6. package/agents/ask_agent.js +64 -127
  7. package/agents/claude_agent.js +68 -0
  8. package/agents/code_agent.js +55 -135
  9. package/agents/code_agent.prompt.md +50 -0
  10. package/agents/echo_agent.js +76 -0
  11. package/agents/financial_expert.js +75 -0
  12. package/agents/gpt_agent.js +52 -103
  13. package/agents/gpt_code.js +81 -0
  14. package/agents/grok_agent.js +58 -114
  15. package/agents/minimax_agent.js +92 -0
  16. package/agents/mureka_agent.js +77 -0
  17. package/agents/planner_agent.js +172 -0
  18. package/agents/stability_agent.js +87 -0
  19. package/agents/test_agent.js +75 -157
  20. package/agents/weather_agent.js +73 -0
  21. package/agents/workflow_agent.js +189 -0
  22. package/bin/dave.js +436 -184
  23. package/docs/bin-dave.md +85 -35
  24. package/docs/cdn-ssh.md +100 -0
  25. package/docs/creating-agents.md +301 -0
  26. package/docs/creating-toolsets.md +336 -0
  27. package/docs/docs-organization.md +48 -0
  28. package/docs/project-overview.md +86 -51
  29. package/lib/API/elevenlabs.io/music.compose.md +441 -0
  30. package/lib/API/elevenlabs.io/music.create-composition-plan.md +370 -0
  31. package/lib/API/elevenlabs.io/music.stream.md +425 -0
  32. package/lib/API/lalal.ai/lalal.js +445 -0
  33. package/lib/API/lalal.ai/openapi.json +2614 -0
  34. package/lib/API/minimax/ImageToolset.js +82 -37
  35. package/lib/API/minimax/MusicToolset.js +125 -79
  36. package/lib/API/minimax/VideoToolset.js +170 -167
  37. package/lib/API/minimax/image.js +5 -1
  38. package/lib/API/minimax/music.js +210 -23
  39. package/lib/API/minimax/video.js +242 -53
  40. package/lib/API/mureka/MusicToolset.js +646 -0
  41. package/lib/API/mureka/README.md +41 -0
  42. package/lib/API/mureka/index.js +7 -0
  43. package/lib/API/mureka/music.js +658 -0
  44. package/lib/API/openai.com/index.js +7 -0
  45. package/lib/API/openai.com/{reponses/text.js → responses.js} +64 -18
  46. package/lib/API/openai.com/video.create.character.md +40 -0
  47. package/lib/API/openai.com/video.create.md +219 -0
  48. package/lib/API/openai.com/video.delete.md +44 -0
  49. package/lib/API/openai.com/video.download.md +31 -0
  50. package/lib/API/openai.com/video.edit.md +155 -0
  51. package/lib/API/openai.com/video.extend.md +166 -0
  52. package/lib/API/openai.com/video.fetch.character.md +43 -0
  53. package/lib/API/openai.com/video.js +784 -0
  54. package/lib/API/openai.com/video.list.md +201 -0
  55. package/lib/API/openai.com/video.remix.md +175 -0
  56. package/lib/API/openai.com/video.retrieve.md +139 -0
  57. package/lib/API/openai.com/videoToolset.js +616 -0
  58. package/lib/API/stability.ai/ImageToolset.js +131 -40
  59. package/lib/API/stability.ai/MusicToolset.js +79 -47
  60. package/lib/API/stability.ai/audio.js +63 -131
  61. package/lib/API/x.ai/chat.responses.md +1040 -0
  62. package/lib/API/x.ai/image.js +229 -59
  63. package/lib/API/x.ai/imageToolset.js +376 -0
  64. package/lib/API/x.ai/index.js +1 -3
  65. package/lib/API/x.ai/responses.js +9 -18
  66. package/lib/Agent.js +271 -0
  67. package/lib/Agent.js.old +284 -0
  68. package/lib/AgentLauncher.js +562 -0
  69. package/lib/Cli.js +87 -13
  70. package/lib/Prompt.js +23 -1
  71. package/lib/Session.js +5 -4
  72. package/lib/ToolSet.js +102 -6
  73. package/lib/agentLoader.js +369 -0
  74. package/lib/cdn.js +67 -231
  75. package/lib/{CdnToolset.js → cdnToolset.js} +47 -64
  76. package/lib/defaultToolsets.js +43 -0
  77. package/lib/fafs.js +1 -1
  78. package/lib/genericToolset.js +442 -119
  79. package/lib/handOffToolset.js +179 -0
  80. package/lib/index.js +34 -27
  81. package/lib/toolsetLoader.js +248 -0
  82. package/package.json +11 -5
  83. package/types/API/lalal.ai/lalal.d.ts +116 -0
  84. package/types/API/minimax/image.d.ts +2 -1
  85. package/types/API/minimax/music.d.ts +189 -26
  86. package/types/API/minimax/video.d.ts +100 -31
  87. package/types/API/mureka/index.d.ts +7 -0
  88. package/types/API/mureka/music.d.ts +472 -0
  89. package/types/API/openai.com/index.d.ts +7 -0
  90. package/types/API/openai.com/{reponses/text.d.ts → responses.d.ts} +11 -11
  91. package/types/API/openai.com/video.d.ts +409 -0
  92. package/types/API/openai.com/videoToolset.d.ts +24 -0
  93. package/types/API/stability.ai/audio.d.ts +14 -103
  94. package/types/API/stability.ai/image.d.ts +2 -2
  95. package/types/API/x.ai/image.d.ts +138 -26
  96. package/types/API/x.ai/imageToolset.d.ts +3 -0
  97. package/types/API/x.ai/index.d.ts +1 -3
  98. package/types/API/x.ai/responses.d.ts +4 -4
  99. package/types/Agent.d.ts +123 -0
  100. package/types/AgentLauncher.d.ts +222 -0
  101. package/types/Cli.d.ts +28 -8
  102. package/types/Prompt.d.ts +23 -5
  103. package/types/Session.d.ts +1 -1
  104. package/types/ToolSet.d.ts +10 -0
  105. package/types/agentLoader.d.ts +78 -0
  106. package/types/cdn.d.ts +15 -90
  107. package/types/defaultToolsets.d.ts +9 -0
  108. package/types/fafs.d.ts +1 -1
  109. package/types/genericToolset.d.ts +1 -1
  110. package/types/handOffToolset.d.ts +28 -0
  111. package/types/index.d.ts +19 -16
  112. package/types/toolsetLoader.d.ts +114 -0
  113. package/utils/format_log.js +101 -23
  114. package/utils/launch_agent.js +18 -0
  115. package/utils/list_sessions.sh +13 -5
  116. package/utils/search_sessions.sh +65 -29
  117. package/utils/toolsets.js +33 -0
  118. package/README.md.bak.1779452127 +0 -240
  119. package/agents/codeserver.sh +0 -47
  120. package/agents/daisy_agent.js +0 -173
  121. package/agents/docs_agent.js +0 -148
  122. package/agents/memory_agent.js +0 -263
  123. package/agents/minimax.js +0 -173
  124. package/agents/npm_agent.js +0 -202
  125. package/agents/prompt_agent.js +0 -133
  126. package/agents/readme_agent.js +0 -148
  127. package/agents/spawn_agent.js +0 -160
  128. package/agents/stability.js +0 -173
  129. package/agents/todo_agent.js +0 -175
  130. package/bin/codeDave +0 -58
  131. package/docs/agent-dave-websocket-protocol.md +0 -180
  132. package/docs/agent-manager.md +0 -244
  133. package/docs/codeserver-pattern.md +0 -191
  134. package/docs/generic-toolset.md +0 -326
  135. package/docs/howtos/agent-networking.md +0 -253
  136. package/docs/howtos/spawn-agents.md.bak +0 -200
  137. package/docs/howtos/spawn-agents.md.bak_new +0 -200
  138. package/docs/multi-agent-clusters.md +0 -265
  139. package/docs/music-toolsets.md +0 -137
  140. package/docs/path-resolution-best-practices.md +0 -104
  141. package/docs/plans/minimax-music-generation.md +0 -80
  142. package/docs/plans/unified-agent-architecture.md +0 -146
  143. package/docs/plans/websocket-streaming-plan.md.bak +0 -317
  144. package/docs/prompt/spawn_agent.md +0 -175
  145. package/docs/prompt/spawn_agent.md.bak +0 -201
  146. package/docs/prompt/task_clarification_and_documentation.md +0 -35
  147. package/docs/prompt-class.md +0 -141
  148. package/docs/todo-archive-infra-2026-04-21.md +0 -15
  149. package/docs/todo-archive-v0.0.8.md +0 -1
  150. package/docs/todo-archive-v0.1.0.md +0 -32
  151. package/docs/todo-archive.md +0 -44
  152. package/docs/tools-syntax-validation.md +0 -121
  153. package/docs/toolset.md +0 -164
  154. package/docs/xai-responses.md +0 -111
  155. package/docs/xai_collections.md +0 -106
  156. package/lib/API/x.ai/ImageToolset.js +0 -165
  157. package/lib/API/x.ai/text.js +0 -415
  158. package/lib/AgentClient.js +0 -248
  159. package/lib/AgentManager.js +0 -245
  160. package/lib/AgentServer.js +0 -404
  161. package/lib/wsCli.js +0 -287
  162. package/lib/wsIO.js +0 -90
  163. package/types/API/x.ai/text.d.ts +0 -286
  164. package/types/AgentClient.d.ts +0 -109
  165. package/types/AgentManager.d.ts +0 -100
  166. package/types/AgentServer.d.ts +0 -89
  167. package/types/wsCli.d.ts +0 -17
  168. package/types/wsIO.d.ts +0 -30
  169. package/utils/test.sh +0 -46
  170. /package/docs/{suggestions.md → _notes/token-counts.md} +0 -0
  171. /package/lib/API/openai.com/{reponses/MESSAGES.md → MESSAGES.md} +0 -0
  172. /package/types/API/{x.ai/ImageToolset.d.ts → mureka/MusicToolset.d.ts} +0 -0
  173. /package/types/{CdnToolset.d.ts → cdnToolset.d.ts} +0 -0
@@ -0,0 +1,369 @@
1
+ /**
2
+ * lib/agentLoader.js
3
+ *
4
+ * Internal loader and discovery utilities for clean Agent-based agents.
5
+ *
6
+ * Supports both default framework discovery and caller-bound discovery via:
7
+ *
8
+ * const loader = createAgentLoader({ from: import.meta.url });
9
+ *
10
+ * Search / discovery order:
11
+ * - When `from` is supplied: only <nearest-package-root-from-from>/agents
12
+ * - Otherwise: only <framework-package-root>/agents
13
+ *
14
+ * @module agentLoader
15
+ */
16
+
17
+ import fs from 'node:fs/promises';
18
+ import path from 'node:path';
19
+ import { fileURLToPath, pathToFileURL } from 'node:url';
20
+
21
+ const __filename = fileURLToPath(import.meta.url);
22
+ const __dirname = path.dirname(__filename);
23
+
24
+ /**
25
+ * Valid agent name pattern.
26
+ *
27
+ * @const {RegExp}
28
+ */
29
+ const validAgentNameRegex = /^[a-z0-9_]{2,}$/;
30
+
31
+ /**
32
+ * @typedef {object} AgentLoaderOptions
33
+ * @property {string|URL} [from] - Caller module URL/path, usually caller import.meta.url.
34
+ * @property {(string|URL)[]} [agentDirs] - Explicit agent directories. Used only when `from` is not supplied.
35
+ */
36
+
37
+ /**
38
+ * Return true when a child path is the base path or nested under it.
39
+ *
40
+ * @param {string} base - Real absolute base directory.
41
+ * @param {string} child - Real absolute candidate path.
42
+ * @returns {boolean} Whether child is inside base.
43
+ */
44
+ const isInsidePath = (base, child) => {
45
+ const relative = path.relative(base, child);
46
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
47
+ };
48
+
49
+ /**
50
+ * Convert a filesystem path or file URL to an absolute filesystem path.
51
+ *
52
+ * @param {string|URL} value - Path or file URL.
53
+ * @returns {string} Absolute filesystem path.
54
+ */
55
+ function toPath(value) {
56
+ if (value instanceof URL) return fileURLToPath(value);
57
+ if (typeof value === 'string' && value.startsWith('file:')) return fileURLToPath(value);
58
+ return path.resolve(String(value));
59
+ }
60
+
61
+ /**
62
+ * Return true if a path exists and is readable.
63
+ *
64
+ * @param {string} targetPath - Filesystem path to check.
65
+ * @returns {Promise<boolean>} True when the path is readable.
66
+ */
67
+ async function canRead(targetPath) {
68
+ try {
69
+ await fs.access(targetPath, fs.constants.R_OK);
70
+ return true;
71
+ } catch {
72
+ return false;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Find the nearest package root by walking upward until package.json is found.
78
+ *
79
+ * @param {string|URL} from - Starting file path, directory path, or file URL.
80
+ * @returns {Promise<string|null>} Package root path, or null.
81
+ */
82
+ export async function findNearestPackageRoot(from) {
83
+ if (!from) return null;
84
+
85
+ let currentPath = toPath(from);
86
+
87
+ try {
88
+ const stat = await fs.stat(currentPath);
89
+ if (stat.isFile()) currentPath = path.dirname(currentPath);
90
+ } catch {
91
+ currentPath = path.dirname(currentPath);
92
+ }
93
+
94
+ let currentDir = path.resolve(currentPath);
95
+
96
+ while (true) {
97
+ const packageJsonPath = path.join(currentDir, 'package.json');
98
+ if (await canRead(packageJsonPath)) return currentDir;
99
+
100
+ const parentDir = path.dirname(currentDir);
101
+ if (parentDir === currentDir) return null;
102
+ currentDir = parentDir;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Push a directory into a list if present.
108
+ *
109
+ * @param {string[]} dirs - Directory accumulator.
110
+ * @param {string|null|undefined} dir - Directory candidate.
111
+ * @returns {void}
112
+ */
113
+ function pushDir(dirs, dir) {
114
+ if (dir) dirs.push(path.resolve(dir));
115
+ }
116
+
117
+ /**
118
+ * Build ordered agent directory candidates.
119
+ *
120
+ * When `options.from` is supplied, discovery is intentionally strict: the only
121
+ * directory searched is the `agents` directory under the nearest package root
122
+ * found from that caller module URL/path.
123
+ *
124
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
125
+ * @returns {Promise<string[]>} Absolute agent directory candidates.
126
+ */
127
+ export async function getAgentDirs(options = {}) {
128
+ const dirs = [];
129
+
130
+ if (options.from) {
131
+ const callerRoot = await findNearestPackageRoot(options.from);
132
+ if (!callerRoot) {
133
+ throw new Error(`Could not find package.json from ${String(options.from)}`);
134
+ }
135
+
136
+ return [path.join(callerRoot, 'agents')];
137
+ }
138
+
139
+ if (Array.isArray(options.agentDirs)) {
140
+ for (const dir of options.agentDirs) pushDir(dirs, toPath(dir));
141
+ return [...new Set(dirs)];
142
+ }
143
+
144
+ const frameworkRoot = await findNearestPackageRoot(import.meta.url);
145
+ return [frameworkRoot ? path.join(frameworkRoot, 'agents') : path.resolve(__dirname, '..', 'agents')];
146
+ }
147
+
148
+ /**
149
+ * Build roots allowed for direct path loading.
150
+ *
151
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
152
+ * @returns {Promise<string[]>} Real absolute allowed roots.
153
+ */
154
+ async function getAllowedDirectPathRoots(options = {}) {
155
+ const roots = [];
156
+
157
+ if (options.from) {
158
+ const callerRoot = await findNearestPackageRoot(options.from);
159
+ if (!callerRoot) {
160
+ throw new Error(`Could not find package.json from ${String(options.from)}`);
161
+ }
162
+ roots.push(callerRoot);
163
+ } else if (Array.isArray(options.agentDirs)) {
164
+ for (const dir of options.agentDirs) roots.push(toPath(dir));
165
+ } else {
166
+ const frameworkRoot = await findNearestPackageRoot(import.meta.url);
167
+ roots.push(frameworkRoot || path.resolve(__dirname, '..'));
168
+ }
169
+
170
+ const realRoots = [];
171
+ for (const root of roots) {
172
+ try {
173
+ realRoots.push(await fs.realpath(root));
174
+ } catch {}
175
+ }
176
+
177
+ return [...new Set(realRoots)];
178
+ }
179
+
180
+ /**
181
+ * Resolve a direct `.js` agent path supplied on the command line.
182
+ *
183
+ * @param {string} agentPath - Relative or absolute path to an agent module.
184
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
185
+ * @returns {Promise<string|null>} Real absolute path, or null when not path-like.
186
+ * @throws {Error} If the path-like spec is invalid or unsafe.
187
+ */
188
+ const resolveDirectAgentPath = async (agentPath, options = {}) => {
189
+ if (!agentPath.includes('/') && !agentPath.includes('\\')) return null;
190
+
191
+ const resolved = path.resolve(process.cwd(), agentPath);
192
+ const parsed = path.parse(resolved);
193
+ if (parsed.ext !== '.js' || !validAgentNameRegex.test(parsed.name)) {
194
+ throw new Error(
195
+ `Invalid agent path "${agentPath}". Direct agent paths must end in <valid_agent_name>.js, ` +
196
+ `where the basename matches /^[a-z0-9_]{2,}$/ (for example agents/gpt_agent.js).`
197
+ );
198
+ }
199
+
200
+ const realFile = await fs.realpath(resolved);
201
+ const allowedRoots = await getAllowedDirectPathRoots(options);
202
+ if (!allowedRoots.some(root => isInsidePath(root, realFile))) {
203
+ throw new Error(`Agent path "${agentPath}" escapes the configured project/package roots`);
204
+ }
205
+
206
+ await fs.access(realFile, fs.constants.R_OK);
207
+ return realFile;
208
+ };
209
+
210
+ /**
211
+ * Discover all available agents by performing a lightweight filesystem scan.
212
+ *
213
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
214
+ * @returns {Promise<Array<{name: string, path: string, desc: string}>>}
215
+ * Array of discovered agents.
216
+ */
217
+ export async function listAgents(options = {}) {
218
+ const dirCandidates = await getAgentDirs(options);
219
+
220
+ /** @type {Map<string, {name: string, path: string, desc: string}>} */
221
+ const found = new Map();
222
+
223
+ for (const dir of dirCandidates) {
224
+ try {
225
+ const entries = await fs.readdir(dir, { withFileTypes: true });
226
+ for (const entry of entries) {
227
+ if (!entry.isFile() || !entry.name.endsWith('.js')) continue;
228
+
229
+ const base = entry.name.replace(/\.js$/, '');
230
+ if (!validAgentNameRegex.test(base) || found.has(base)) continue;
231
+
232
+ const fullPath = path.join(dir, entry.name);
233
+ let desc = '[ERROR]';
234
+
235
+ try {
236
+ const mod = await import(pathToFileURL(fullPath).href);
237
+ let agent = mod.default ?? mod.agent ?? mod;
238
+
239
+ if (typeof agent === 'function') {
240
+ try {
241
+ agent = await agent();
242
+ } catch {
243
+ agent = null;
244
+ }
245
+ }
246
+
247
+ if (agent && typeof agent === 'object') {
248
+ if (typeof agent.description === 'string' && agent.description.trim()) {
249
+ desc = agent.description.trim();
250
+ } else if (typeof agent.call_description === 'string' && agent.call_description.trim()) {
251
+ desc = agent.call_description.trim();
252
+ }
253
+ }
254
+
255
+ if ((!desc || desc === '[ERROR]') && typeof mod.call_description === 'string' && mod.call_description.trim()) {
256
+ desc = mod.call_description.trim();
257
+ }
258
+
259
+ if (!desc || typeof desc !== 'string' || desc.length === 0) {
260
+ desc = '[ERROR]';
261
+ } else if (desc.length > 180) {
262
+ desc = `${desc.slice(0, 177).trimEnd()}...`;
263
+ }
264
+ } catch {
265
+ desc = '[ERROR]';
266
+ }
267
+
268
+ found.set(base, { name: base, path: fullPath, desc });
269
+ }
270
+ } catch {
271
+ // Directory does not exist or is not readable — silently skip.
272
+ }
273
+ }
274
+
275
+ return Array.from(found.values());
276
+ }
277
+
278
+ /**
279
+ * Resolve the absolute path to an agent module by name.
280
+ *
281
+ * @param {string} agentName - The agent identifier or safe direct path.
282
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
283
+ * @returns {Promise<string>} Absolute path to the matching .js file.
284
+ */
285
+ export async function resolveAgentPath(agentName, options = {}) {
286
+ if (!agentName || typeof agentName !== 'string') {
287
+ throw new Error('agentName is required');
288
+ }
289
+
290
+ const directPath = await resolveDirectAgentPath(agentName, options);
291
+ if (directPath) return directPath;
292
+
293
+ if (!validAgentNameRegex.test(agentName)) {
294
+ throw new Error(
295
+ `Invalid agentName "${agentName}". ` +
296
+ `Must match /^[a-z0-9_]{2,}$/ (lowercase letters a-z, digits 0-9, and underscore _ only; min 2 characters). ` +
297
+ `Or pass a safe direct path like agents/gpt_agent.js.`
298
+ );
299
+ }
300
+
301
+ const fileName = `${agentName}.js`;
302
+ const dirCandidates = await getAgentDirs(options);
303
+ const candidates = dirCandidates.map(dir => path.join(dir, fileName));
304
+
305
+ for (const p of candidates) {
306
+ if (await canRead(p)) return p;
307
+ }
308
+
309
+ const searched = candidates.map(c => ` - ${c}`).join('\n');
310
+ throw new Error(`Agent "${agentName}" not found.\nSearched:\n${searched}`);
311
+ }
312
+
313
+ /**
314
+ * Load (import + validate) a clean Agent instance by name.
315
+ *
316
+ * @param {string} agentName - Agent identifier to load.
317
+ * @param {Array<any>} [extraArgs=[]] - Optional factory arguments.
318
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
319
+ * @returns {Promise<import('./Agent.js').default>} Loaded Agent instance.
320
+ */
321
+ export async function loadAgent(agentName, extraArgs = [], options = {}) {
322
+ const resolved = await resolveAgentPath(agentName, options);
323
+ const mod = await import(pathToFileURL(resolved).href);
324
+ let agent = mod.default ?? mod.agent ?? mod;
325
+
326
+ if (!agent) {
327
+ throw new Error(`Module ${resolved} did not export a usable default.`);
328
+ }
329
+
330
+ if (typeof agent === 'function') {
331
+ agent = await agent(...extraArgs);
332
+ }
333
+
334
+ if (agent && typeof agent === 'object') {
335
+ try {
336
+ if (Object.isExtensible(agent)) {
337
+ agent.__loadedFrom = resolved;
338
+ agent.__loadedAs = path.parse(resolved).name;
339
+ if (extraArgs.length) agent.__extraArgs = extraArgs;
340
+ }
341
+ } catch {}
342
+ }
343
+
344
+ if (!agent || typeof agent.getPrompt !== 'function' || typeof agent.name !== 'string') {
345
+ throw new Error(`Loaded "${agentName}" is not a valid Agent instance. Use clean Agent-based agents for handoff.`);
346
+ }
347
+
348
+ return agent;
349
+ }
350
+
351
+ /**
352
+ * Create an isolated agent loader bound to a caller/project context.
353
+ *
354
+ * @param {AgentLoaderOptions} [options={}] - Loader options.
355
+ * @returns {{
356
+ * getAgentDirs: () => Promise<string[]>,
357
+ * listAgents: () => Promise<Array<{name: string, path: string, desc: string}>>,
358
+ * resolveAgentPath: (agentName: string) => Promise<string>,
359
+ * loadAgent: (agentName: string, extraArgs?: Array<any>) => Promise<import('./Agent.js').default>
360
+ * }} Configured loader API.
361
+ */
362
+ export function createAgentLoader(options = {}) {
363
+ return {
364
+ getAgentDirs: () => getAgentDirs(options),
365
+ listAgents: () => listAgents(options),
366
+ resolveAgentPath: (agentName) => resolveAgentPath(agentName, options),
367
+ loadAgent: (agentName, extraArgs = []) => loadAgent(agentName, extraArgs, options)
368
+ };
369
+ }