kernelbot 1.0.38 → 1.0.40
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/bin/kernel.js +335 -451
- package/config.example.yaml +1 -1
- package/knowledge_base/active_inference_foraging.md +126 -0
- package/knowledge_base/index.md +1 -1
- package/package.json +2 -1
- package/skills/business/business-analyst.md +32 -0
- package/skills/business/product-manager.md +32 -0
- package/skills/business/project-manager.md +32 -0
- package/skills/business/startup-advisor.md +32 -0
- package/skills/creative/music-producer.md +32 -0
- package/skills/creative/photographer.md +32 -0
- package/skills/creative/video-producer.md +32 -0
- package/skills/data/bi-analyst.md +37 -0
- package/skills/data/data-scientist.md +38 -0
- package/skills/data/ml-engineer.md +38 -0
- package/skills/design/graphic-designer.md +38 -0
- package/skills/design/product-designer.md +41 -0
- package/skills/design/ui-ux.md +38 -0
- package/skills/education/curriculum-designer.md +32 -0
- package/skills/education/language-teacher.md +32 -0
- package/skills/education/tutor.md +32 -0
- package/skills/engineering/data-eng.md +55 -0
- package/skills/engineering/devops.md +56 -0
- package/skills/engineering/mobile-dev.md +55 -0
- package/skills/engineering/security-eng.md +55 -0
- package/skills/engineering/sr-backend.md +55 -0
- package/skills/engineering/sr-frontend.md +55 -0
- package/skills/finance/accountant.md +35 -0
- package/skills/finance/crypto-defi.md +39 -0
- package/skills/finance/financial-analyst.md +35 -0
- package/skills/healthcare/health-wellness.md +32 -0
- package/skills/healthcare/medical-researcher.md +33 -0
- package/skills/legal/contract-reviewer.md +35 -0
- package/skills/legal/legal-advisor.md +36 -0
- package/skills/marketing/content-marketer.md +38 -0
- package/skills/marketing/growth.md +38 -0
- package/skills/marketing/seo.md +43 -0
- package/skills/marketing/social-media.md +43 -0
- package/skills/writing/academic-writer.md +33 -0
- package/skills/writing/copywriter.md +32 -0
- package/skills/writing/creative-writer.md +32 -0
- package/skills/writing/tech-writer.md +33 -0
- package/src/agent.js +153 -118
- package/src/automation/scheduler.js +36 -3
- package/src/bot.js +147 -64
- package/src/coder.js +30 -8
- package/src/conversation.js +96 -19
- package/src/dashboard/dashboard.css +6 -0
- package/src/dashboard/dashboard.js +28 -1
- package/src/dashboard/index.html +12 -0
- package/src/dashboard/server.js +77 -15
- package/src/dashboard/shared.js +10 -1
- package/src/life/codebase.js +2 -1
- package/src/life/daydream_engine.js +386 -0
- package/src/life/engine.js +88 -6
- package/src/life/evolution.js +4 -3
- package/src/prompts/orchestrator.js +1 -1
- package/src/prompts/system.js +1 -1
- package/src/prompts/workers.js +8 -1
- package/src/providers/anthropic.js +3 -1
- package/src/providers/base.js +33 -0
- package/src/providers/index.js +1 -1
- package/src/providers/models.js +22 -0
- package/src/providers/openai-compat.js +3 -0
- package/src/services/x-api.js +14 -3
- package/src/skills/loader.js +382 -0
- package/src/swarm/worker-registry.js +2 -2
- package/src/tools/browser.js +10 -3
- package/src/tools/coding.js +16 -0
- package/src/tools/docker.js +13 -0
- package/src/tools/git.js +31 -29
- package/src/tools/jira.js +11 -2
- package/src/tools/monitor.js +9 -1
- package/src/tools/network.js +34 -0
- package/src/tools/orchestrator-tools.js +2 -1
- package/src/tools/os.js +20 -6
- package/src/utils/config.js +87 -83
- package/src/utils/display.js +118 -66
- package/src/utils/logger.js +1 -1
- package/src/utils/timeAwareness.js +72 -0
- package/src/worker.js +26 -33
- package/src/skills/catalog.js +0 -506
- package/src/skills/custom.js +0 -128
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time Awareness Utility — Riyadh-local helpers.
|
|
3
|
+
*
|
|
4
|
+
* Provides timezone-aware helpers anchored to Asia/Riyadh so that
|
|
5
|
+
* automated tasks can respect the user's real-world schedule.
|
|
6
|
+
*
|
|
7
|
+
* Quiet hours (02:00 – 10:00 Riyadh time) are intentionally wider than
|
|
8
|
+
* the generic defaults in timeUtils.js because the owner fasts during
|
|
9
|
+
* Ramadan and typically sleeps through the early-morning hours.
|
|
10
|
+
*
|
|
11
|
+
* @module utils/timeAwareness
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const TIMEZONE = 'Asia/Riyadh';
|
|
15
|
+
const QUIET_START_HOUR = 2;
|
|
16
|
+
const QUIET_END_HOUR = 10;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Return the current date/time in the Asia/Riyadh timezone.
|
|
20
|
+
*
|
|
21
|
+
* The returned object contains the full ISO-style formatted string,
|
|
22
|
+
* the numeric hour (0-23), and the raw Date for further processing.
|
|
23
|
+
*
|
|
24
|
+
* @returns {{ formatted: string, hour: number, date: Date }}
|
|
25
|
+
*/
|
|
26
|
+
export function getCurrentRiyadhTime() {
|
|
27
|
+
const now = new Date();
|
|
28
|
+
|
|
29
|
+
const formatted = now.toLocaleString('en-US', {
|
|
30
|
+
weekday: 'long',
|
|
31
|
+
year: 'numeric',
|
|
32
|
+
month: 'long',
|
|
33
|
+
day: 'numeric',
|
|
34
|
+
hour: '2-digit',
|
|
35
|
+
minute: '2-digit',
|
|
36
|
+
second: '2-digit',
|
|
37
|
+
hour12: true,
|
|
38
|
+
timeZone: TIMEZONE,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const hourParts = new Intl.DateTimeFormat('en-US', {
|
|
42
|
+
hour: 'numeric',
|
|
43
|
+
hour12: false,
|
|
44
|
+
timeZone: TIMEZONE,
|
|
45
|
+
}).formatToParts(now);
|
|
46
|
+
|
|
47
|
+
const hour = parseInt(
|
|
48
|
+
hourParts.find((p) => p.type === 'hour')?.value || '0',
|
|
49
|
+
10,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
return { formatted, hour, date: now };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check whether the current Riyadh time falls within quiet hours.
|
|
57
|
+
*
|
|
58
|
+
* Quiet hours are defined as **02:00 – 10:00 (Asia/Riyadh)** to
|
|
59
|
+
* respect the user's sleep schedule during Ramadan fasting, when
|
|
60
|
+
* they tend to sleep through the early-morning period.
|
|
61
|
+
*
|
|
62
|
+
* Automated tasks (notifications, self-improvement PRs, noisy jobs)
|
|
63
|
+
* should check this flag and defer non-urgent work until after the
|
|
64
|
+
* quiet window closes.
|
|
65
|
+
*
|
|
66
|
+
* @returns {boolean} `true` when the current Riyadh time is between
|
|
67
|
+
* 02:00 and 10:00 (inclusive start, exclusive end).
|
|
68
|
+
*/
|
|
69
|
+
export function isQuietHours() {
|
|
70
|
+
const { hour } = getCurrentRiyadhTime();
|
|
71
|
+
return hour >= QUIET_START_HOUR && hour < QUIET_END_HOUR;
|
|
72
|
+
}
|
package/src/worker.js
CHANGED
|
@@ -3,7 +3,7 @@ import { executeTool } from './tools/index.js';
|
|
|
3
3
|
import { closeSession } from './tools/browser.js';
|
|
4
4
|
import { getMissingCredential } from './utils/config.js';
|
|
5
5
|
import { getWorkerPrompt } from './prompts/workers.js';
|
|
6
|
-
import {
|
|
6
|
+
import { buildSkillPrompt } from './skills/loader.js';
|
|
7
7
|
import { getLogger } from './utils/logger.js';
|
|
8
8
|
import { truncateToolResult } from './utils/truncate.js';
|
|
9
9
|
|
|
@@ -23,17 +23,17 @@ export class WorkerAgent {
|
|
|
23
23
|
* @param {string} opts.workerType - coding, browser, system, devops, research
|
|
24
24
|
* @param {string} opts.jobId - Job ID for logging
|
|
25
25
|
* @param {Array} opts.tools - Scoped tool definitions
|
|
26
|
-
* @param {string|null} opts.
|
|
26
|
+
* @param {string[]|null} opts.skillIds - Active skill IDs (for worker prompt)
|
|
27
27
|
* @param {string|null} opts.workerContext - Structured context (conversation history, persona, dependency results)
|
|
28
28
|
* @param {object} opts.callbacks - { onProgress, onComplete, onError }
|
|
29
29
|
* @param {AbortController} opts.abortController - For cancellation
|
|
30
30
|
*/
|
|
31
|
-
constructor({ config, workerType, jobId, tools,
|
|
31
|
+
constructor({ config, workerType, jobId, tools, skillIds, workerContext, callbacks, abortController }) {
|
|
32
32
|
this.config = config;
|
|
33
33
|
this.workerType = workerType;
|
|
34
34
|
this.jobId = jobId;
|
|
35
35
|
this.tools = tools;
|
|
36
|
-
this.
|
|
36
|
+
this.skillIds = skillIds || [];
|
|
37
37
|
this.workerContext = workerContext || null;
|
|
38
38
|
this.callbacks = callbacks || {};
|
|
39
39
|
this.abortController = abortController || new AbortController();
|
|
@@ -45,8 +45,8 @@ export class WorkerAgent {
|
|
|
45
45
|
// Create provider from worker brain config
|
|
46
46
|
this.provider = createProvider(config);
|
|
47
47
|
|
|
48
|
-
// Build system prompt
|
|
49
|
-
const skillPrompt =
|
|
48
|
+
// Build system prompt with combined skill expertise
|
|
49
|
+
const skillPrompt = buildSkillPrompt(this.skillIds);
|
|
50
50
|
this.systemPrompt = getWorkerPrompt(workerType, config, skillPrompt);
|
|
51
51
|
|
|
52
52
|
// Safety ceiling — not a real limit, just prevents infinite loops
|
|
@@ -54,7 +54,7 @@ export class WorkerAgent {
|
|
|
54
54
|
this.maxIterations = 200;
|
|
55
55
|
|
|
56
56
|
const logger = getLogger();
|
|
57
|
-
logger.info(`[Worker ${jobId}] Created: type=${workerType}, provider=${config.brain.provider}/${config.brain.model}, tools=${tools.length},
|
|
57
|
+
logger.info(`[Worker ${jobId}] Created: type=${workerType}, provider=${config.brain.provider}/${config.brain.model}, tools=${tools.length}, skills=${this.skillIds.length > 0 ? this.skillIds.join(',') : 'none'}, context=${workerContext ? 'yes' : 'none'}`);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/** Cancel this worker. */
|
|
@@ -297,41 +297,34 @@ export class WorkerAgent {
|
|
|
297
297
|
|
|
298
298
|
const _str = (v) => typeof v === 'string' ? v : (v ? JSON.stringify(v, null, 2) : '');
|
|
299
299
|
|
|
300
|
+
/** Try to build a structured result from a parsed JSON object. */
|
|
301
|
+
const _fromParsed = (parsed) => {
|
|
302
|
+
if (!parsed?.summary || !parsed?.status) return null;
|
|
303
|
+
return {
|
|
304
|
+
structured: true,
|
|
305
|
+
summary: String(parsed.summary || ''),
|
|
306
|
+
status: String(parsed.status || 'success'),
|
|
307
|
+
details: _str(parsed.details),
|
|
308
|
+
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
309
|
+
followUp: parsed.followUp ? String(parsed.followUp) : null,
|
|
310
|
+
toolsUsed: this._toolCallCount,
|
|
311
|
+
errors: this._errors,
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
|
|
300
315
|
// Try to extract JSON from ```json ... ``` fences
|
|
301
316
|
const fenceMatch = text.match(/```json\s*\n?([\s\S]*?)\n?\s*```/);
|
|
302
317
|
if (fenceMatch) {
|
|
303
318
|
try {
|
|
304
|
-
const
|
|
305
|
-
if (
|
|
306
|
-
return {
|
|
307
|
-
structured: true,
|
|
308
|
-
summary: String(parsed.summary || ''),
|
|
309
|
-
status: String(parsed.status || 'success'),
|
|
310
|
-
details: _str(parsed.details),
|
|
311
|
-
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
312
|
-
followUp: parsed.followUp ? String(parsed.followUp) : null,
|
|
313
|
-
toolsUsed: this._toolCallCount,
|
|
314
|
-
errors: this._errors,
|
|
315
|
-
};
|
|
316
|
-
}
|
|
319
|
+
const result = _fromParsed(JSON.parse(fenceMatch[1]));
|
|
320
|
+
if (result) return result;
|
|
317
321
|
} catch { /* fall through */ }
|
|
318
322
|
}
|
|
319
323
|
|
|
320
324
|
// Try raw JSON parse (no fences)
|
|
321
325
|
try {
|
|
322
|
-
const
|
|
323
|
-
if (
|
|
324
|
-
return {
|
|
325
|
-
structured: true,
|
|
326
|
-
summary: String(parsed.summary || ''),
|
|
327
|
-
status: String(parsed.status || 'success'),
|
|
328
|
-
details: _str(parsed.details),
|
|
329
|
-
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
330
|
-
followUp: parsed.followUp ? String(parsed.followUp) : null,
|
|
331
|
-
toolsUsed: this._toolCallCount,
|
|
332
|
-
errors: this._errors,
|
|
333
|
-
};
|
|
334
|
-
}
|
|
326
|
+
const result = _fromParsed(JSON.parse(text));
|
|
327
|
+
if (result) return result;
|
|
335
328
|
} catch { /* fall through */ }
|
|
336
329
|
|
|
337
330
|
// Fallback: wrap raw text
|