kernelbot 1.0.28 → 1.0.30
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/.env.example +4 -0
- package/README.md +0 -0
- package/bin/kernel.js +13 -6
- package/config.example.yaml +14 -1
- package/package.json +1 -1
- package/src/agent.js +482 -27
- package/src/automation/automation-manager.js +0 -0
- package/src/automation/automation.js +0 -0
- package/src/automation/index.js +0 -0
- package/src/automation/scheduler.js +0 -0
- package/src/bot.js +340 -3
- package/src/claude-auth.js +93 -0
- package/src/coder.js +48 -6
- package/src/conversation.js +0 -0
- package/src/intents/detector.js +0 -0
- package/src/intents/index.js +0 -0
- package/src/intents/planner.js +0 -0
- package/src/persona.js +0 -0
- package/src/prompts/orchestrator.js +53 -5
- package/src/prompts/persona.md +0 -0
- package/src/prompts/system.js +0 -0
- package/src/prompts/workers.js +61 -2
- package/src/providers/anthropic.js +0 -0
- package/src/providers/base.js +0 -0
- package/src/providers/index.js +0 -0
- package/src/providers/models.js +0 -0
- package/src/providers/openai-compat.js +0 -0
- package/src/security/audit.js +0 -0
- package/src/security/auth.js +0 -0
- package/src/security/confirm.js +0 -0
- package/src/self.js +122 -0
- package/src/services/stt.js +139 -0
- package/src/services/tts.js +124 -0
- package/src/skills/catalog.js +0 -0
- package/src/skills/custom.js +0 -0
- package/src/swarm/job-manager.js +54 -7
- package/src/swarm/job.js +19 -1
- package/src/swarm/worker-registry.js +5 -0
- package/src/tools/browser.js +0 -0
- package/src/tools/categories.js +0 -0
- package/src/tools/coding.js +5 -0
- package/src/tools/docker.js +0 -0
- package/src/tools/git.js +0 -0
- package/src/tools/github.js +0 -0
- package/src/tools/index.js +0 -0
- package/src/tools/jira.js +0 -0
- package/src/tools/monitor.js +0 -0
- package/src/tools/network.js +0 -0
- package/src/tools/orchestrator-tools.js +76 -19
- package/src/tools/os.js +14 -1
- package/src/tools/persona.js +0 -0
- package/src/tools/process.js +0 -0
- package/src/utils/config.js +105 -2
- package/src/utils/display.js +0 -0
- package/src/utils/logger.js +0 -0
- package/src/worker.js +96 -5
package/src/worker.js
CHANGED
|
@@ -26,18 +26,22 @@ export class WorkerAgent {
|
|
|
26
26
|
* @param {string} opts.jobId - Job ID for logging
|
|
27
27
|
* @param {Array} opts.tools - Scoped tool definitions
|
|
28
28
|
* @param {string|null} opts.skillId - Active skill ID (for worker prompt)
|
|
29
|
+
* @param {string|null} opts.workerContext - Structured context (conversation history, persona, dependency results)
|
|
29
30
|
* @param {object} opts.callbacks - { onProgress, onComplete, onError }
|
|
30
31
|
* @param {AbortController} opts.abortController - For cancellation
|
|
31
32
|
*/
|
|
32
|
-
constructor({ config, workerType, jobId, tools, skillId, callbacks, abortController }) {
|
|
33
|
+
constructor({ config, workerType, jobId, tools, skillId, workerContext, callbacks, abortController }) {
|
|
33
34
|
this.config = config;
|
|
34
35
|
this.workerType = workerType;
|
|
35
36
|
this.jobId = jobId;
|
|
36
37
|
this.tools = tools;
|
|
37
38
|
this.skillId = skillId;
|
|
39
|
+
this.workerContext = workerContext || null;
|
|
38
40
|
this.callbacks = callbacks || {};
|
|
39
41
|
this.abortController = abortController || new AbortController();
|
|
40
42
|
this._cancelled = false;
|
|
43
|
+
this._toolCallCount = 0;
|
|
44
|
+
this._errors = [];
|
|
41
45
|
|
|
42
46
|
// Create provider from worker brain config
|
|
43
47
|
this.provider = createProvider(config);
|
|
@@ -51,7 +55,7 @@ export class WorkerAgent {
|
|
|
51
55
|
this.maxIterations = 200;
|
|
52
56
|
|
|
53
57
|
const logger = getLogger();
|
|
54
|
-
logger.info(`[Worker ${jobId}] Created: type=${workerType}, provider=${config.brain.provider}/${config.brain.model}, tools=${tools.length}, skill=${skillId || 'none'}`);
|
|
58
|
+
logger.info(`[Worker ${jobId}] Created: type=${workerType}, provider=${config.brain.provider}/${config.brain.model}, tools=${tools.length}, skill=${skillId || 'none'}, context=${workerContext ? 'yes' : 'none'}`);
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
/** Cancel this worker. */
|
|
@@ -66,7 +70,14 @@ export class WorkerAgent {
|
|
|
66
70
|
const logger = getLogger();
|
|
67
71
|
logger.info(`[Worker ${this.jobId}] Starting task: "${task.slice(0, 150)}"`);
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
// Build first message: context sections + task
|
|
74
|
+
let firstMessage = '';
|
|
75
|
+
if (this.workerContext) {
|
|
76
|
+
firstMessage += this.workerContext + '\n\n---\n\n';
|
|
77
|
+
}
|
|
78
|
+
firstMessage += task;
|
|
79
|
+
|
|
80
|
+
const messages = [{ role: 'user', content: firstMessage }];
|
|
70
81
|
|
|
71
82
|
try {
|
|
72
83
|
const result = await this._runLoop(messages);
|
|
@@ -74,8 +85,9 @@ export class WorkerAgent {
|
|
|
74
85
|
logger.info(`[Worker ${this.jobId}] Run completed but worker was cancelled — skipping callbacks`);
|
|
75
86
|
return;
|
|
76
87
|
}
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
const parsed = this._parseResult(result);
|
|
89
|
+
logger.info(`[Worker ${this.jobId}] Run finished successfully — structured=${!!parsed.structured}, result: "${(result || '').slice(0, 150)}"`);
|
|
90
|
+
if (this.callbacks.onComplete) this.callbacks.onComplete(result, parsed);
|
|
79
91
|
} catch (err) {
|
|
80
92
|
if (this._cancelled) {
|
|
81
93
|
logger.info(`[Worker ${this.jobId}] Run threw error but worker was cancelled — ignoring: ${err.message}`);
|
|
@@ -144,6 +156,8 @@ export class WorkerAgent {
|
|
|
144
156
|
logger.debug(`[Worker ${this.jobId}] Tool input: ${JSON.stringify(block.input).slice(0, 300)}`);
|
|
145
157
|
this._reportProgress(`🔧 ${summary}`);
|
|
146
158
|
|
|
159
|
+
this._toolCallCount++;
|
|
160
|
+
|
|
147
161
|
const result = await executeTool(block.name, block.input, {
|
|
148
162
|
config: this.config,
|
|
149
163
|
user: null, // workers don't have user context
|
|
@@ -151,8 +165,14 @@ export class WorkerAgent {
|
|
|
151
165
|
onUpdate: this.callbacks.onUpdate || null, // Real bot onUpdate (returns message_id for coder.js smart output)
|
|
152
166
|
sendPhoto: this.callbacks.sendPhoto || null,
|
|
153
167
|
sessionId: this.jobId, // Per-worker browser session isolation
|
|
168
|
+
signal: this.abortController.signal, // For killing child processes on cancellation
|
|
154
169
|
});
|
|
155
170
|
|
|
171
|
+
// Track errors
|
|
172
|
+
if (result && typeof result === 'object' && result.error) {
|
|
173
|
+
this._errors.push({ tool: block.name, error: result.error });
|
|
174
|
+
}
|
|
175
|
+
|
|
156
176
|
const resultStr = this._truncateResult(block.name, result);
|
|
157
177
|
logger.info(`[Worker ${this.jobId}] Tool ${block.name} result: ${resultStr.slice(0, 200)}`);
|
|
158
178
|
|
|
@@ -254,10 +274,81 @@ export class WorkerAgent {
|
|
|
254
274
|
return null;
|
|
255
275
|
}
|
|
256
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Parse the worker's final text into a structured WorkerResult.
|
|
279
|
+
* Attempts JSON parse from ```json fences, falls back to wrapping raw text.
|
|
280
|
+
*/
|
|
281
|
+
_parseResult(text) {
|
|
282
|
+
if (!text) {
|
|
283
|
+
return {
|
|
284
|
+
structured: false,
|
|
285
|
+
summary: 'Task completed.',
|
|
286
|
+
status: 'success',
|
|
287
|
+
details: '',
|
|
288
|
+
artifacts: [],
|
|
289
|
+
followUp: null,
|
|
290
|
+
toolsUsed: this._toolCallCount,
|
|
291
|
+
errors: this._errors,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Try to extract JSON from ```json ... ``` fences
|
|
296
|
+
const fenceMatch = text.match(/```json\s*\n?([\s\S]*?)\n?\s*```/);
|
|
297
|
+
if (fenceMatch) {
|
|
298
|
+
try {
|
|
299
|
+
const parsed = JSON.parse(fenceMatch[1]);
|
|
300
|
+
if (parsed.summary && parsed.status) {
|
|
301
|
+
return {
|
|
302
|
+
structured: true,
|
|
303
|
+
summary: parsed.summary || '',
|
|
304
|
+
status: parsed.status || 'success',
|
|
305
|
+
details: parsed.details || '',
|
|
306
|
+
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
307
|
+
followUp: parsed.followUp || null,
|
|
308
|
+
toolsUsed: this._toolCallCount,
|
|
309
|
+
errors: this._errors,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
} catch { /* fall through */ }
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Try raw JSON parse (no fences)
|
|
316
|
+
try {
|
|
317
|
+
const parsed = JSON.parse(text);
|
|
318
|
+
if (parsed.summary && parsed.status) {
|
|
319
|
+
return {
|
|
320
|
+
structured: true,
|
|
321
|
+
summary: parsed.summary || '',
|
|
322
|
+
status: parsed.status || 'success',
|
|
323
|
+
details: parsed.details || '',
|
|
324
|
+
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
325
|
+
followUp: parsed.followUp || null,
|
|
326
|
+
toolsUsed: this._toolCallCount,
|
|
327
|
+
errors: this._errors,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
} catch { /* fall through */ }
|
|
331
|
+
|
|
332
|
+
// Fallback: wrap raw text
|
|
333
|
+
return {
|
|
334
|
+
structured: false,
|
|
335
|
+
summary: text.slice(0, 200),
|
|
336
|
+
status: 'success',
|
|
337
|
+
details: text,
|
|
338
|
+
artifacts: [],
|
|
339
|
+
followUp: null,
|
|
340
|
+
toolsUsed: this._toolCallCount,
|
|
341
|
+
errors: this._errors,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
257
345
|
_reportProgress(text) {
|
|
258
346
|
if (this.callbacks.onProgress) {
|
|
259
347
|
try { this.callbacks.onProgress(text); } catch {}
|
|
260
348
|
}
|
|
349
|
+
if (this.callbacks.onHeartbeat) {
|
|
350
|
+
try { this.callbacks.onHeartbeat(text); } catch {}
|
|
351
|
+
}
|
|
261
352
|
}
|
|
262
353
|
|
|
263
354
|
_truncateResult(name, result) {
|