kernelbot 1.0.28 → 1.0.32

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 CHANGED
@@ -9,6 +9,10 @@ TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
9
9
 
10
10
  # Optional
11
11
  GITHUB_TOKEN=ghp_...
12
+
13
+ # ElevenLabs Voice (optional — enables voice replies and transcription)
14
+ ELEVENLABS_API_KEY=xi_...
15
+ ELEVENLABS_VOICE_ID=JBFqnCBsd6RMkjVDRZzb
12
16
  JIRA_BASE_URL=https://yourcompany.atlassian.net
13
17
  JIRA_EMAIL=you@company.com
14
18
  JIRA_API_TOKEN=your-jira-api-token
package/bin/kernel.js CHANGED
@@ -20,11 +20,18 @@ import {
20
20
  import { createAuditLogger } from '../src/security/audit.js';
21
21
  import { ConversationManager } from '../src/conversation.js';
22
22
  import { UserPersonaManager } from '../src/persona.js';
23
+ import { SelfManager } from '../src/self.js';
23
24
  import { Agent } from '../src/agent.js';
24
25
  import { JobManager } from '../src/swarm/job-manager.js';
25
26
  import { startBot } from '../src/bot.js';
26
27
  import { AutomationManager } from '../src/automation/index.js';
27
28
  import { createProvider, PROVIDERS } from '../src/providers/index.js';
29
+ import { MemoryManager } from '../src/life/memory.js';
30
+ import { JournalManager } from '../src/life/journal.js';
31
+ import { ShareQueue } from '../src/life/share-queue.js';
32
+ import { EvolutionTracker } from '../src/life/evolution.js';
33
+ import { CodebaseKnowledge } from '../src/life/codebase.js';
34
+ import { LifeEngine } from '../src/life/engine.js';
28
35
  import {
29
36
  loadCustomSkills,
30
37
  getCustomSkills,
@@ -125,14 +132,19 @@ async function startBotFlow(config) {
125
132
 
126
133
  const checks = [];
127
134
 
128
- // Orchestrator always needs Anthropic API key
135
+ // Orchestrator check dynamic provider
136
+ const orchProviderKey = config.orchestrator.provider || 'anthropic';
137
+ const orchProviderDef = PROVIDERS[orchProviderKey];
138
+ const orchLabel = orchProviderDef ? orchProviderDef.name : orchProviderKey;
129
139
  checks.push(
130
- await showStartupCheck('Orchestrator (Anthropic) API', async () => {
131
- const orchestratorKey = config.orchestrator.api_key || process.env.ANTHROPIC_API_KEY;
132
- if (!orchestratorKey) throw new Error('ANTHROPIC_API_KEY is required for the orchestrator');
140
+ await showStartupCheck(`Orchestrator (${orchLabel}) API`, async () => {
141
+ const orchestratorKey = config.orchestrator.api_key
142
+ || (orchProviderDef && process.env[orchProviderDef.envKey])
143
+ || process.env.ANTHROPIC_API_KEY;
144
+ if (!orchestratorKey) throw new Error(`${orchProviderDef?.envKey || 'ANTHROPIC_API_KEY'} is required for the orchestrator`);
133
145
  const provider = createProvider({
134
146
  brain: {
135
- provider: 'anthropic',
147
+ provider: orchProviderKey,
136
148
  model: config.orchestrator.model,
137
149
  max_tokens: config.orchestrator.max_tokens,
138
150
  temperature: config.orchestrator.temperature,
@@ -168,6 +180,7 @@ async function startBotFlow(config) {
168
180
 
169
181
  const conversationManager = new ConversationManager(config);
170
182
  const personaManager = new UserPersonaManager();
183
+ const selfManager = new SelfManager();
171
184
  const jobManager = new JobManager({
172
185
  jobTimeoutSeconds: config.swarm.job_timeout_seconds,
173
186
  cleanupIntervalMinutes: config.swarm.cleanup_interval_minutes,
@@ -175,9 +188,25 @@ async function startBotFlow(config) {
175
188
 
176
189
  const automationManager = new AutomationManager();
177
190
 
178
- const agent = new Agent({ config, conversationManager, personaManager, jobManager, automationManager });
191
+ // Life system managers
192
+ const memoryManager = new MemoryManager();
193
+ const journalManager = new JournalManager();
194
+ const shareQueue = new ShareQueue();
195
+ const evolutionTracker = new EvolutionTracker();
196
+ const codebaseKnowledge = new CodebaseKnowledge({ config });
179
197
 
180
- startBot(config, agent, conversationManager, jobManager, automationManager);
198
+ const agent = new Agent({ config, conversationManager, personaManager, selfManager, jobManager, automationManager, memoryManager, shareQueue });
199
+
200
+ // Wire codebase knowledge to agent for LLM-powered scanning
201
+ codebaseKnowledge.setAgent(agent);
202
+
203
+ // Life Engine — autonomous inner life
204
+ const lifeEngine = new LifeEngine({
205
+ config, agent, memoryManager, journalManager, shareQueue,
206
+ evolutionTracker, codebaseKnowledge, selfManager,
207
+ });
208
+
209
+ startBot(config, agent, conversationManager, jobManager, automationManager, { lifeEngine, memoryManager, journalManager, shareQueue, evolutionTracker, codebaseKnowledge });
181
210
 
182
211
  // Periodic job cleanup and timeout enforcement
183
212
  const cleanupMs = (config.swarm.cleanup_interval_minutes || 30) * 60 * 1000;
@@ -186,7 +215,39 @@ async function startBotFlow(config) {
186
215
  jobManager.enforceTimeouts();
187
216
  }, Math.min(cleanupMs, 60_000)); // enforce timeouts every minute at most
188
217
 
218
+ // Periodic memory pruning (daily)
219
+ const retentionDays = config.life?.memory_retention_days || 90;
220
+ setInterval(() => {
221
+ memoryManager.pruneOld(retentionDays);
222
+ shareQueue.prune(7);
223
+ }, 24 * 3600_000);
224
+
189
225
  showStartupComplete();
226
+
227
+ // Start life engine if enabled
228
+ const lifeEnabled = config.life?.enabled !== false;
229
+ if (lifeEnabled) {
230
+ logger.info('[Startup] Life engine enabled — waking up...');
231
+ lifeEngine.wakeUp().then(() => {
232
+ lifeEngine.start();
233
+ logger.info('[Startup] Life engine running');
234
+ }).catch(err => {
235
+ logger.error(`[Startup] Life engine wake-up failed: ${err.message}`);
236
+ lifeEngine.start(); // still start heartbeat even if wake-up fails
237
+ });
238
+
239
+ // Initial codebase scan (background, non-blocking)
240
+ if (config.life?.self_coding?.enabled) {
241
+ codebaseKnowledge.scanChanged().then(count => {
242
+ if (count > 0) logger.info(`[Startup] Codebase scan: ${count} files indexed`);
243
+ }).catch(err => {
244
+ logger.warn(`[Startup] Codebase scan failed: ${err.message}`);
245
+ });
246
+ }
247
+ } else {
248
+ logger.info('[Startup] Life engine disabled');
249
+ }
250
+
190
251
  return true;
191
252
  }
192
253
 
@@ -5,16 +5,22 @@ bot:
5
5
  name: KernelBot
6
6
  description: AI engineering agent with full OS control
7
7
 
8
+ orchestrator:
9
+ provider: anthropic # anthropic | openai | google | groq — switchable via /orchestrator
10
+ # model: claude-opus-4-6
11
+
8
12
  brain:
9
- provider: anthropic # anthropic | openai | google | groq
13
+ provider: anthropic # anthropic | openai | google | groq — switchable via /brain
10
14
  model: claude-sonnet-4-20250514
11
15
  max_tokens: 8192
12
16
  temperature: 0.3
13
17
  max_tool_depth: 25
14
18
 
15
19
  claude_code:
20
+ # model: claude-opus-4-6 # switchable via /claudemodel
16
21
  max_turns: 50
17
22
  timeout_seconds: 600
23
+ # auth_mode: system # system | api_key | oauth_token — switchable via /claude
18
24
  # workspace_dir: /tmp/kernelbot-workspaces # default: ~/.kernelbot/workspaces
19
25
 
20
26
  github:
@@ -43,3 +49,41 @@ logging:
43
49
 
44
50
  conversation:
45
51
  max_history: 50
52
+
53
+ # Voice — ElevenLabs TTS & STT
54
+ # Requires ELEVENLABS_API_KEY in .env
55
+ voice:
56
+ tts_enabled: true # Send voice replies alongside text (default: true if API key present)
57
+ stt_enabled: true # Transcribe user voice messages (default: true if API key present)
58
+ # voice_id: JBFqnCBsd6RMkjVDRZzb # ElevenLabs voice ID (override ELEVENLABS_VOICE_ID env var)
59
+
60
+ # Inner Life — autonomous thinking, journaling, browsing, creating
61
+ # Data stored at ~/.kernelbot/life/
62
+ life:
63
+ enabled: true # Enable autonomous inner life
64
+ min_interval_minutes: 30 # Minimum time between activities
65
+ max_interval_minutes: 120 # Maximum time between activities
66
+ activity_weights: # Relative probability weights
67
+ think: 30 # Inner monologue, self-questioning
68
+ browse: 25 # Explore interests via web search
69
+ journal: 20 # Write daily journal entries
70
+ create: 15 # Creative expression (poems, stories, thoughts)
71
+ self_code: 10 # Self-evolution proposals (requires self_coding.enabled)
72
+ code_review: 5 # Codebase scanning + PR status checks
73
+ reflect: 8 # Read logs, analyze interactions, find improvement patterns
74
+ proactive_sharing: true # Share discoveries with users proactively
75
+ proactive_max_per_day: 3 # Max proactive messages per day
76
+ memory_retention_days: 90 # Days to keep episodic memories
77
+ self_coding:
78
+ enabled: false # Allow self-evolution (safety-gated, opt-in)
79
+ branch_prefix: evolution # Git branch prefix for evolution PRs
80
+ # repo_remote: Owner/Repo # GitHub owner/repo for PRs (auto-detected if omitted)
81
+ cooldown_hours: 2 # Min hours between evolution attempts
82
+ max_active_prs: 3 # Max concurrent open evolution PRs
83
+ max_proposals_per_day: 3 # Max new proposals per day
84
+ allowed_scopes: all # all | safe | prompts_only
85
+ code_review_cooldown_hours: 4 # Hours between code review activities
86
+ codebase_scan_interval_hours: 24 # Hours between full codebase scans
87
+ quiet_hours:
88
+ start: 2 # Hour to start quiet period (no activities)
89
+ end: 6 # Hour to end quiet period
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kernelbot",
3
- "version": "1.0.28",
3
+ "version": "1.0.32",
4
4
  "description": "KernelBot — AI engineering agent with full OS control",
5
5
  "type": "module",
6
6
  "author": "Abdullah Al-Taheri <abdullah@altaheri.me>",