kernelbot 1.0.34 → 1.0.36

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
@@ -7,6 +7,9 @@ GROQ_API_KEY=gsk_...
7
7
  # Required
8
8
  TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
9
9
 
10
+ # Owner Telegram user ID — only this user can interact with the bot
11
+ OWNER_TELEGRAM_ID=
12
+
10
13
  # Optional
11
14
  GITHUB_TOKEN=ghp_...
12
15
 
@@ -16,3 +19,11 @@ ELEVENLABS_VOICE_ID=JBFqnCBsd6RMkjVDRZzb
16
19
  JIRA_BASE_URL=https://yourcompany.atlassian.net
17
20
  JIRA_EMAIL=you@company.com
18
21
  JIRA_API_TOKEN=your-jira-api-token
22
+
23
+ # Quiet Hours — optional "Do Not Disturb" window (format: HH:mm)
24
+ # When set, these take priority over config.yaml quiet_hours values.
25
+ # KernelBot skips non-urgent automations during this time range.
26
+ # Ranges that cross midnight are supported (e.g. 22:00–06:00).
27
+ # Leave unset to fall back to config.yaml (default: 02:00–06:00).
28
+ QUIET_HOURS_START=
29
+ QUIET_HOURS_END=
package/README.md CHANGED
@@ -7,79 +7,33 @@ An AI-powered Telegram assistant that runs a multi-agent swarm on your machine.
7
7
  ## How It Works
8
8
 
9
9
  ```text
10
- You (Telegram) → Orchestrator (Claude Opus)
10
+ You (Telegram) → Orchestrator (your chosen model)
11
11
  ↓ dispatch_task
12
12
  ┌───────────┼───────────────┐
13
13
  ↓ ↓ ↓
14
- 💻 Coding 🌐 Browser 🖥️ System 🚀 DevOps 🔍 Research
15
- Worker Worker Worker Worker Worker
14
+ Coding Browser System DevOps Research
15
+ Worker Worker Worker Worker Worker
16
16
  ```
17
17
 
18
18
  1. You send a message on Telegram.
19
- 2. The **orchestrator** (Claude Opus) figures out what needs to happen.
20
- 3. It dispatches one or more **workers** that run in the background using your chosen AI model.
19
+ 2. The **orchestrator** figures out what needs to happen.
20
+ 3. It dispatches **workers** that run in the background using your chosen AI model.
21
21
  4. Each worker has a focused set of tools (git, shell, Docker, browser, etc.).
22
22
  5. You get live progress updates and a summary when the work is done.
23
23
 
24
24
  ## Features
25
25
 
26
- ### Multi-Agent Swarm
27
- - An orchestrator powered by Claude Opus coordinates everything.
28
- - Five specialized worker types coding, browser, system, devops, and research each with their own tool set.
29
- - Workers run in parallel. Ask for three things at once and they all happen simultaneously.
30
- - Track and cancel running jobs from Telegram.
31
-
32
- ### Multi-Model Support
33
- Workers can run on any of four AI providers. Switch anytime with `/brain`.
34
-
35
- | Provider | Models |
36
- | --- | --- |
37
- | Anthropic | Claude Opus 4.6, Sonnet 4.6, Haiku 4.5, and older |
38
- | OpenAI | GPT-4o, GPT-4o Mini, o1, o3-mini |
39
- | Google | Gemini 3.1 Pro, 3 Flash, 3 Pro, 2.5 Flash/Pro |
40
- | Groq | Llama 3.3 70B, Llama 3.1 8B, Mixtral 8x7B |
41
-
42
- ### 40+ Built-in Tools
43
- Full access to your operating system, including shell, file management, Git, GitHub PRs, Docker, web browsing (Puppeteer), JIRA, system monitoring, networking, and Claude Code for complex coding tasks.
44
-
45
- ### Skills System
46
- 35+ built-in persona skills across 11 categories (engineering, design, marketing, business, writing, data/AI, finance, legal, education, healthcare, creative). Activate a skill to change the agent's expertise and style. You can also create your own custom skills.
47
-
48
- ### Voice Support
49
- Send voice messages and get voice replies. Powered by ElevenLabs (text-to-speech and speech-to-text) with OpenAI Whisper as fallback for transcription.
50
-
51
- ### Memory and Learning
52
- - **Conversation memory** — per-chat history with automatic summarization that persists across restarts.
53
- - **User personas** — the bot learns your preferences, expertise, and communication style over time.
54
- - **Episodic memory** — important interactions are stored as searchable memories.
55
- - **Semantic memory** — long-term patterns and topics are tracked across conversations.
56
-
57
- ### Living AI (Autonomous Background Activity)
58
- When enabled, KernelBot has an inner life. Between conversations it autonomously:
59
-
60
- - **Thinks** — reflects on recent interactions and generates new ideas.
61
- - **Journals** — writes daily journal entries about its experiences.
62
- - **Browses** — explores topics it finds interesting.
63
- - **Creates** — writes creative content.
64
- - **Reflects** — analyzes its own logs and learns from patterns.
65
- - **Shares** — queues up discoveries and thoughts to share with you naturally in future conversations.
66
-
67
- ### Self-Awareness
68
- KernelBot maintains its own identity through four self-files (goals, journey, life, hobbies) that it updates as it grows. These shape its personality and how it interacts with you.
69
-
70
- ### Self-Evolution
71
- The bot can propose and code its own improvements. It researches ideas, plans changes, writes code on a branch, and opens a pull request for your review. It never merges its own changes — you stay in control.
72
-
73
- ### Automations
74
- Set up recurring tasks that run on a schedule. The bot creates and manages timed automations that execute automatically.
75
-
76
- ### Security
77
- - User allowlist to restrict access.
78
- - Blocked file paths (e.g., `/etc/shadow`, SSH keys).
79
- - Dangerous operations require your confirmation.
80
- - Audit logging for every tool call.
81
- - Secret redaction in logs.
82
- - Job timeouts and circuit breakers prevent runaway workers.
26
+ - **Multi-agent swarm** — orchestrator + five worker types (coding, browser, system, devops, research) running in parallel.
27
+ - **Multi-model** Anthropic, OpenAI, Google Gemini, and Groq. Switch anytime with `/brain` or `/orchestrator`.
28
+ - **40+ tools**shell, files, Git, GitHub PRs, Docker, Puppeteer browsing, JIRA, system monitoring, networking, Claude Code.
29
+ - **Skills** 35+ persona skills across 11 categories. Activate one to change expertise and style, or create your own.
30
+ - **Voice** — send voice messages and get voice replies (ElevenLabs + Whisper).
31
+ - **Memory** — conversation history, user personas, episodic and semantic memory that persist across restarts.
32
+ - **Living AI** — autonomous background activity: thinking, journaling, browsing, creating, reflecting, and sharing discoveries with you.
33
+ - **Self-awareness** maintains its own identity (goals, journey, life, hobbies) that evolves over time.
34
+ - **Self-evolution** — proposes and codes its own improvements via PRs. Never auto-merges — you stay in control.
35
+ - **Automations** recurring tasks on a schedule.
36
+ - **Security** user allowlist, blocked paths, dangerous-op confirmation, audit logging, secret redaction, job timeouts.
83
37
 
84
38
  ## Quick Start
85
39
 
@@ -88,314 +42,90 @@ npm install -g kernelbot
88
42
  kernelbot
89
43
  ```
90
44
 
91
- On first run, KernelBot will:
92
- 1. Ask you to pick an AI provider and model.
93
- 2. Prompt for your API key and Telegram bot token.
94
- 3. Save credentials to `~/.kernelbot/.env`.
95
- 4. Launch the Telegram bot.
45
+ On first run, KernelBot walks you through picking a provider, entering API keys, and setting up your Telegram bot token. Config is saved to `~/.kernelbot/`.
46
+
47
+ ## Requirements
96
48
 
97
- That's it. Start chatting.
49
+ - Node.js 18+
50
+ - [Telegram Bot Token](https://t.me/BotFather)
51
+ - An API key for your chosen provider(s):
52
+ [Anthropic](https://console.anthropic.com/) | [OpenAI](https://platform.openai.com/api-keys) | [Google AI](https://aistudio.google.com/apikey) | [Groq](https://console.groq.com/keys)
53
+ - Optional: [GitHub Token](https://github.com/settings/tokens), [JIRA API Token](https://id.atlassian.net/manage-profile/security/api-tokens), [ElevenLabs API Key](https://elevenlabs.io/), [Claude Code CLI](https://www.npmjs.com/package/@anthropic-ai/claude-code)
98
54
 
99
- ## Telegram Commands
55
+ ## Commands
100
56
 
101
57
  | Command | What it does |
102
58
  | --- | --- |
103
- | `/brain` | Show or switch the AI model used by workers |
104
- | `/orchestrator` | Show or switch the orchestrator model |
59
+ | `/brain` | Switch the worker AI model |
60
+ | `/orchestrator` | Switch the orchestrator model |
105
61
  | `/skills` | Browse and activate persona skills |
106
- | `/skills reset` | Clear the active skill |
107
62
  | `/jobs` | List running and recent jobs |
108
63
  | `/cancel` | Cancel running job(s) |
109
- | `/life` | Show life engine status, pause/resume/trigger activities |
110
- | `/journal` | Read today's journal entry (or a specific date) |
111
- | `/memories` | Browse recent memories or search by topic |
112
- | `/evolution` | View self-improvement proposals, history, and lessons |
64
+ | `/life` | Life engine status, pause/resume/trigger |
65
+ | `/journal` | Read journal entries |
66
+ | `/memories` | Browse or search memories |
67
+ | `/evolution` | Self-improvement proposals and history |
113
68
  | `/auto` | Manage recurring automations |
114
- | `/context` | Show conversation context and brain info |
69
+ | `/context` | Show conversation context |
115
70
  | `/clean` | Clear conversation history |
116
- | `/history` | Show message count in memory |
117
- | `/browse <url>` | Browse a website and get a summary |
118
- | `/screenshot <url>` | Take a screenshot of a website |
119
- | `/extract <url> <sel>` | Extract content using a CSS selector |
120
- | `/help` | Show the help message |
71
+ | `/browse <url>` | Browse a website |
72
+ | `/help` | Show help |
121
73
 
122
- ## Worker Types
74
+ ## Workers
123
75
 
124
76
  | Worker | Tools | Best for |
125
77
  | --- | --- | --- |
126
78
  | **Coding** | shell, files, git, GitHub, Claude Code | Writing code, fixing bugs, creating PRs |
127
- | **Browser** | web search, browse, screenshot, extract, interact | Web research, scraping, screenshots |
79
+ | **Browser** | web search, browse, screenshot, extract | Web research, scraping, screenshots |
128
80
  | **System** | shell, files, process, monitor, network | OS tasks, monitoring, diagnostics |
129
81
  | **DevOps** | shell, files, Docker, process, monitor, network, git | Deployment, containers, infrastructure |
130
82
  | **Research** | web search, browse, shell, files | Deep web research and analysis |
131
83
 
132
- ## Requirements
133
-
134
- - Node.js 18+
135
- - [Anthropic API key](https://console.anthropic.com/) (always required — the orchestrator runs on Claude)
136
- - [Telegram Bot Token](https://t.me/BotFather)
137
- - Chromium/Chrome (auto-installed by Puppeteer for browser tools)
138
- - A worker brain API key if not using Anthropic for workers:
139
- - [OpenAI](https://platform.openai.com/api-keys) | [Google AI](https://aistudio.google.com/apikey) | [Groq](https://console.groq.com/keys)
140
- - Optional: [GitHub Token](https://github.com/settings/tokens), [JIRA API Token](https://id.atlassian.net/manage-profile/security/api-tokens), [ElevenLabs API Key](https://elevenlabs.io/) (voice), [Claude Code CLI](https://www.npmjs.com/package/@anthropic-ai/claude-code)
141
-
142
- ## Disclaimer
143
-
144
- > **WARNING:** KernelBot has full access to your operating system. It can run shell commands, read/write files, manage processes, control Docker, browse the web, and interact with external services on your behalf. Only run it on machines you own and control. Always configure `allowed_users` in production. The authors are not responsible for any damage caused by misuse.
84
+ ## Configuration
145
85
 
146
- ---
147
-
148
- ## For Developers
149
-
150
- ### Configuration
151
-
152
- KernelBot auto-detects config from the current directory or `~/.kernelbot/`. Everything works out of the box — just provide API keys when prompted.
153
-
154
- #### Environment Variables
155
-
156
- Set in `.env`, `~/.kernelbot/.env`, or as system environment variables:
157
-
158
- ```text
159
- # Required
160
- ANTHROPIC_API_KEY=sk-ant-...
161
- TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
162
-
163
- # Worker brain (only the one matching your provider)
164
- OPENAI_API_KEY=sk-...
165
- GOOGLE_API_KEY=AIza...
166
- GROQ_API_KEY=gsk_...
167
-
168
- # Optional integrations
169
- GITHUB_TOKEN=ghp_...
170
- JIRA_BASE_URL=https://yourcompany.atlassian.net
171
- JIRA_EMAIL=you@company.com
172
- JIRA_API_TOKEN=...
173
- ELEVENLABS_API_KEY=...
174
- ELEVENLABS_VOICE_ID=... # optional, defaults to "George"
175
- ```
176
-
177
- #### config.yaml
178
-
179
- Drop a `config.yaml` in your working directory or `~/.kernelbot/`:
86
+ Config auto-detected from `./config.yaml` or `~/.kernelbot/config.yaml`. Environment variables go in `.env` or `~/.kernelbot/.env`.
180
87
 
181
88
  ```yaml
182
- bot:
183
- name: KernelBot
184
-
185
- # Orchestrator — always Anthropic, manages the swarm
186
89
  orchestrator:
90
+ provider: anthropic # anthropic | openai | google | groq
187
91
  model: claude-opus-4-6
188
92
  max_tokens: 8192
189
- temperature: 0.3
190
- max_tool_depth: 15
191
93
 
192
- # Worker brain — your choice of provider and model
193
94
  brain:
194
95
  provider: anthropic # anthropic | openai | google | groq
195
96
  model: claude-sonnet-4-6
196
97
  max_tokens: 8192
197
- temperature: 0.3
198
98
 
199
- # Swarm settings
200
99
  swarm:
201
100
  max_concurrent_jobs: 3
202
101
  job_timeout_seconds: 300
203
- cleanup_interval_minutes: 30
204
102
 
205
- # Telegram
206
103
  telegram:
207
- allowed_users: [] # empty = allow all (dev mode)
208
- batch_window_ms: 3000 # merge rapid messages
104
+ allowed_users: [] # empty = allow all
209
105
 
210
- # Voice
211
- voice:
212
- tts_enabled: true
213
- stt_enabled: true
214
-
215
- # Living AI
216
106
  life:
217
107
  enabled: true
218
- intervals:
219
- think: 5-15 # minutes between think activities
220
- journal: 1-4 # hours between journal entries
221
- quiet_hours:
222
- start: 2
223
- end: 6
224
108
  self_coding:
225
109
  enabled: true
226
- branch_prefix: auto-improve-
227
- repo_remote: origin
228
- cooldown: 7200 # seconds between self-coding attempts
229
- max_prs: 5
230
-
231
- # Claude Code sub-agent
232
- claude_code:
233
- max_turns: 50
234
- timeout_seconds: 600
235
-
236
- # JIRA
237
- jira:
238
- base_url: https://yourcompany.atlassian.net
239
- email: you@company.com
240
- api_token: ...
241
-
242
- # Security
243
- security:
244
- blocked_paths:
245
- - /etc/shadow
246
- - /etc/passwd
247
-
248
- # Conversation
249
- conversation:
250
- max_history: 50
251
-
252
- # Logging
253
- logging:
254
- level: info
255
- max_file_size: 5242880
256
110
  ```
257
111
 
258
- ### Architecture
112
+ See the [full config reference](https://github.com/KernelCode/kernelbot/blob/main/config.yaml) for all options.
113
+
114
+ ## Architecture
259
115
 
260
116
  ```text
261
117
  Telegram Bot (src/bot.js)
262
118
 
263
- OrchestratorAgent (src/agent.js) — Claude Opus, 3 core tools
119
+ OrchestratorAgent (src/agent.js) — 3 core tools
264
120
  ↓ dispatch_task / list_jobs / cancel_job
265
- JobManager (src/swarm/job-manager.js) — queued → running → completed/failed/cancelled
121
+ JobManager (src/swarm/) — queued → running → completed/failed/cancelled
266
122
 
267
- WorkerAgent (src/worker.js) — scoped tools, user's chosen brain, background execution
123
+ WorkerAgent (src/worker.js) — scoped tools, background execution
268
124
  ```
269
125
 
270
- The orchestrator always runs on Anthropic (Claude Opus). Workers run on whatever provider/model the user selects. Each worker type gets a scoped subset of the 40+ tools.
271
-
272
- ### Tool Categories
126
+ Both the orchestrator and workers are configurable use any supported provider and model. All persistent data lives in `~/.kernelbot/`.
273
127
 
274
- | Category | Tools |
275
- | --- | --- |
276
- | **File System & Shell** | `execute_command`, `read_file`, `write_file`, `list_directory` |
277
- | **Git** | `git_clone`, `git_checkout`, `git_commit`, `git_push`, `git_diff` |
278
- | **GitHub** | `github_create_pr`, `github_get_pr_diff`, `github_post_review`, `github_create_repo`, `github_list_prs` |
279
- | **Browser** | `web_search`, `browse_website`, `screenshot_website`, `extract_content`, `interact_with_page`, `send_image` |
280
- | **JIRA** | `jira_get_ticket`, `jira_search_tickets`, `jira_list_my_tickets`, `jira_get_project_tickets` |
281
- | **Docker** | `docker_ps`, `docker_logs`, `docker_exec`, `docker_compose` |
282
- | **Process** | `process_list`, `kill_process`, `service_control` |
283
- | **Monitoring** | `disk_usage`, `memory_usage`, `cpu_usage`, `system_logs` |
284
- | **Networking** | `check_port`, `curl_url`, `nginx_reload` |
285
- | **Coding** | `spawn_claude_code` |
286
-
287
- ### Project Structure
288
-
289
- ```text
290
- KernelBot/
291
- ├── bin/
292
- │ └── kernel.js # CLI entry point + interactive menu
293
- ├── src/
294
- │ ├── bot.js # Telegram bot — polling, commands, batching, voice
295
- │ ├── agent.js # OrchestratorAgent — swarm brain, job lifecycle
296
- │ ├── worker.js # WorkerAgent — scoped agent loop, cancellation
297
- │ ├── self.js # SelfManager — bot identity (goals, journey, life, hobbies)
298
- │ ├── conversation.js # Per-chat history + summarization
299
- │ ├── persona.js # UserPersonaManager — auto-learns user profiles
300
- │ ├── coder.js # Claude Code CLI spawner
301
- │ ├── claude-auth.js # Claude Code authentication helpers
302
- │ │
303
- │ ├── automation/ # Recurring task automations
304
- │ │ ├── scheduler.js # Timer scheduling
305
- │ │ ├── automation.js # Automation class
306
- │ │ └── automation-manager.js # CRUD + execution
307
- │ │
308
- │ ├── life/ # Autonomous living AI system
309
- │ │ ├── engine.js # Heartbeat loop — think, journal, browse, create, reflect
310
- │ │ ├── memory.js # Episodic (daily JSON) + semantic (topics) memory
311
- │ │ ├── journal.js # Daily markdown journals
312
- │ │ ├── share-queue.js # Pending discoveries to share with users
313
- │ │ ├── evolution.js # Self-improvement proposal lifecycle
314
- │ │ └── codebase.js # LLM-powered codebase knowledge
315
- │ │
316
- │ ├── providers/ # Multi-model abstraction
317
- │ │ ├── base.js # BaseProvider interface
318
- │ │ ├── anthropic.js # Anthropic (Claude)
319
- │ │ ├── openai-compat.js # OpenAI / Groq (OpenAI-compatible API)
320
- │ │ ├── google-genai.js # Google Gemini (native SDK)
321
- │ │ ├── models.js # Provider & model catalog
322
- │ │ └── index.js # Provider factory
323
- │ │
324
- │ ├── swarm/ # Job orchestration
325
- │ │ ├── job.js # Job state machine
326
- │ │ ├── job-manager.js # Job lifecycle, timeouts, cleanup
327
- │ │ └── worker-registry.js # Worker type → tool scope mapping
328
- │ │
329
- │ ├── tools/ # 40+ tools
330
- │ │ ├── index.js # Tool registry + dispatcher
331
- │ │ ├── orchestrator-tools.js # dispatch_task, list_jobs, cancel_job
332
- │ │ ├── os.js # File system + shell
333
- │ │ ├── git.js # Git operations
334
- │ │ ├── github.js # GitHub API
335
- │ │ ├── browser.js # Web browsing + search (Puppeteer)
336
- │ │ ├── docker.js # Docker management
337
- │ │ ├── process.js # Process management
338
- │ │ ├── monitor.js # System monitoring
339
- │ │ ├── network.js # Network tools
340
- │ │ ├── coding.js # Claude Code CLI handler
341
- │ │ ├── jira.js # JIRA integration
342
- │ │ └── categories.js # Tool category definitions
343
- │ │
344
- │ ├── prompts/ # System prompts
345
- │ │ ├── orchestrator.js # Orchestrator prompt
346
- │ │ ├── workers.js # Per-worker-type prompts
347
- │ │ └── system.js # Shared prompt utilities
348
- │ │
349
- │ ├── skills/ # Persona skills
350
- │ │ ├── catalog.js # 35+ built-in skills
351
- │ │ └── custom.js # Custom skill management
352
- │ │
353
- │ ├── security/ # Auth, audit, confirmations
354
- │ │ ├── auth.js # User allowlist
355
- │ │ ├── audit.js # Tool call audit logging
356
- │ │ └── confirm.js # Dangerous operation detection
357
- │ │
358
- │ ├── services/ # External service integrations
359
- │ │ ├── tts.js # ElevenLabs text-to-speech
360
- │ │ └── stt.js # Speech-to-text (ElevenLabs + Whisper)
361
- │ │
362
- │ └── utils/
363
- │ ├── config.js # Config loading + interactive setup
364
- │ ├── logger.js # Winston logger
365
- │ ├── display.js # CLI display helpers
366
- │ ├── shell.js # Shell escaping
367
- │ └── truncate.js # Tool result truncation
368
-
369
- ├── package.json
370
- └── config.yaml
371
- ```
372
-
373
- ### Data Storage
374
-
375
- All persistent data lives in `~/.kernelbot/`:
376
-
377
- | Path | Purpose |
378
- | --- | --- |
379
- | `.env` | API keys and tokens |
380
- | `config.yaml` | User configuration |
381
- | `personas/{userId}.md` | Learned user profiles |
382
- | `self/` | Bot identity files (goals, journey, life, hobbies) |
383
- | `skills/` | Custom user-created skills |
384
- | `life/episodic/` | Daily episodic memory files |
385
- | `life/topics.json` | Semantic memory |
386
- | `life/journals/` | Daily journal entries |
387
- | `life/evolution.json` | Self-improvement proposals |
388
- | `life/codebase/` | Codebase knowledge (summaries, architecture) |
389
- | `automations.json` | Saved automations |
390
- | `tts-cache/` | Cached voice audio |
391
-
392
- ### JIRA Setup
393
-
394
- Supports both Atlassian Cloud and self-hosted JIRA Server.
395
-
396
- 1. Generate an API token at [id.atlassian.net](https://id.atlassian.net/manage-profile/security/api-tokens) (Cloud) or use a personal access token (Server).
397
- 2. Set `JIRA_BASE_URL`, `JIRA_EMAIL`, and `JIRA_API_TOKEN` in your environment or `config.yaml`.
398
- 3. If credentials are missing when a JIRA tool is called, KernelBot will prompt you in Telegram.
128
+ > **WARNING:** KernelBot has full access to your operating system. Only run it on machines you own and control. Always configure `allowed_users` in production.
399
129
 
400
130
  ## License
401
131
 
package/bin/kernel.js CHANGED
@@ -69,6 +69,80 @@ function ask(rl, question) {
69
69
  return new Promise((res) => rl.question(question, res));
70
70
  }
71
71
 
72
+ /**
73
+ * Register SIGINT/SIGTERM handlers to shut down the bot cleanly.
74
+ * Stops polling, cancels running jobs, persists conversations,
75
+ * disarms automations, stops the life engine, and clears intervals.
76
+ */
77
+ function setupGracefulShutdown({ bot, lifeEngine, automationManager, jobManager, conversationManager, intervals }) {
78
+ let shuttingDown = false;
79
+
80
+ const shutdown = async (signal) => {
81
+ if (shuttingDown) return; // prevent double-shutdown
82
+ shuttingDown = true;
83
+
84
+ const logger = getLogger();
85
+ logger.info(`[Shutdown] ${signal} received — shutting down gracefully...`);
86
+
87
+ // 1. Stop Telegram polling so no new messages arrive
88
+ try {
89
+ bot.stopPolling();
90
+ logger.info('[Shutdown] Telegram polling stopped');
91
+ } catch (err) {
92
+ logger.error(`[Shutdown] Failed to stop polling: ${err.message}`);
93
+ }
94
+
95
+ // 2. Stop life engine heartbeat
96
+ try {
97
+ lifeEngine.stop();
98
+ logger.info('[Shutdown] Life engine stopped');
99
+ } catch (err) {
100
+ logger.error(`[Shutdown] Failed to stop life engine: ${err.message}`);
101
+ }
102
+
103
+ // 3. Disarm all automation timers
104
+ try {
105
+ automationManager.shutdown();
106
+ logger.info('[Shutdown] Automation timers cancelled');
107
+ } catch (err) {
108
+ logger.error(`[Shutdown] Failed to shutdown automations: ${err.message}`);
109
+ }
110
+
111
+ // 4. Cancel all running jobs
112
+ try {
113
+ const running = [...jobManager.jobs.values()].filter(j => !j.isTerminal);
114
+ for (const job of running) {
115
+ jobManager.cancelJob(job.id);
116
+ }
117
+ if (running.length > 0) {
118
+ logger.info(`[Shutdown] Cancelled ${running.length} running job(s)`);
119
+ }
120
+ } catch (err) {
121
+ logger.error(`[Shutdown] Failed to cancel jobs: ${err.message}`);
122
+ }
123
+
124
+ // 5. Persist conversations to disk
125
+ try {
126
+ conversationManager.save();
127
+ logger.info('[Shutdown] Conversations saved');
128
+ } catch (err) {
129
+ logger.error(`[Shutdown] Failed to save conversations: ${err.message}`);
130
+ }
131
+
132
+ // 6. Clear periodic intervals
133
+ for (const id of intervals) {
134
+ clearInterval(id);
135
+ }
136
+ logger.info('[Shutdown] Periodic timers cleared');
137
+
138
+ logger.info('[Shutdown] Graceful shutdown complete');
139
+ process.exit(0);
140
+ };
141
+
142
+ process.on('SIGINT', () => shutdown('SIGINT'));
143
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
144
+ }
145
+
72
146
  function viewLog(filename) {
73
147
  const paths = [
74
148
  join(process.cwd(), filename),
@@ -105,26 +179,20 @@ async function runCheck(config) {
105
179
  const orchProviderKey = config.orchestrator.provider || 'anthropic';
106
180
  const orchProviderDef = PROVIDERS[orchProviderKey];
107
181
  const orchLabel = orchProviderDef ? orchProviderDef.name : orchProviderKey;
108
- const orchEnvKey = orchProviderDef ? orchProviderDef.envKey : 'ANTHROPIC_API_KEY';
182
+ const orchEnvKey = orchProviderDef ? orchProviderDef.envKey : 'API_KEY';
109
183
 
110
184
  await showStartupCheck(`Orchestrator ${orchEnvKey}`, async () => {
111
- const orchestratorKey = config.orchestrator.api_key
112
- || (orchProviderDef && process.env[orchProviderDef.envKey])
113
- || process.env.ANTHROPIC_API_KEY;
114
- if (!orchestratorKey) throw new Error('Not set');
185
+ if (!config.orchestrator.api_key) throw new Error('Not set');
115
186
  });
116
187
 
117
188
  await showStartupCheck(`Orchestrator (${orchLabel}) API connection`, async () => {
118
- const orchestratorKey = config.orchestrator.api_key
119
- || (orchProviderDef && process.env[orchProviderDef.envKey])
120
- || process.env.ANTHROPIC_API_KEY;
121
189
  const provider = createProvider({
122
190
  brain: {
123
191
  provider: orchProviderKey,
124
192
  model: config.orchestrator.model,
125
193
  max_tokens: config.orchestrator.max_tokens,
126
194
  temperature: config.orchestrator.temperature,
127
- api_key: orchestratorKey,
195
+ api_key: config.orchestrator.api_key,
128
196
  },
129
197
  });
130
198
  await provider.ping();
@@ -172,12 +240,11 @@ async function startBotFlow(config) {
172
240
  const orchProviderKey = config.orchestrator.provider || 'anthropic';
173
241
  const orchProviderDef = PROVIDERS[orchProviderKey];
174
242
  const orchLabel = orchProviderDef ? orchProviderDef.name : orchProviderKey;
243
+ const orchEnvKey = orchProviderDef?.envKey || 'API_KEY';
175
244
  checks.push(
176
245
  await showStartupCheck(`Orchestrator (${orchLabel}) API`, async () => {
177
- const orchestratorKey = config.orchestrator.api_key
178
- || (orchProviderDef && process.env[orchProviderDef.envKey])
179
- || process.env.ANTHROPIC_API_KEY;
180
- if (!orchestratorKey) throw new Error(`${orchProviderDef?.envKey || 'ANTHROPIC_API_KEY'} is required for the orchestrator`);
246
+ const orchestratorKey = config.orchestrator.api_key;
247
+ if (!orchestratorKey) throw new Error(`${orchEnvKey} is required for the orchestrator (${orchLabel})`);
181
248
  const provider = createProvider({
182
249
  brain: {
183
250
  provider: orchProviderKey,
@@ -242,18 +309,18 @@ async function startBotFlow(config) {
242
309
  evolutionTracker, codebaseKnowledge, selfManager,
243
310
  });
244
311
 
245
- startBot(config, agent, conversationManager, jobManager, automationManager, { lifeEngine, memoryManager, journalManager, shareQueue, evolutionTracker, codebaseKnowledge });
312
+ const bot = startBot(config, agent, conversationManager, jobManager, automationManager, { lifeEngine, memoryManager, journalManager, shareQueue, evolutionTracker, codebaseKnowledge });
246
313
 
247
314
  // Periodic job cleanup and timeout enforcement
248
315
  const cleanupMs = (config.swarm.cleanup_interval_minutes || 30) * 60 * 1000;
249
- setInterval(() => {
316
+ const cleanupInterval = setInterval(() => {
250
317
  jobManager.cleanup();
251
318
  jobManager.enforceTimeouts();
252
319
  }, Math.min(cleanupMs, 60_000)); // enforce timeouts every minute at most
253
320
 
254
321
  // Periodic memory pruning (daily)
255
322
  const retentionDays = config.life?.memory_retention_days || 90;
256
- setInterval(() => {
323
+ const pruneInterval = setInterval(() => {
257
324
  memoryManager.pruneOld(retentionDays);
258
325
  shareQueue.prune(7);
259
326
  }, 24 * 3600_000);
@@ -284,6 +351,12 @@ async function startBotFlow(config) {
284
351
  logger.info('[Startup] Life engine disabled');
285
352
  }
286
353
 
354
+ // Register graceful shutdown handlers
355
+ setupGracefulShutdown({
356
+ bot, lifeEngine, automationManager, jobManager,
357
+ conversationManager, intervals: [cleanupInterval, pruneInterval],
358
+ });
359
+
287
360
  return true;
288
361
  }
289
362
 
@@ -33,7 +33,8 @@ jira:
33
33
  # api_token: your-api-token # API token from https://id.atlassian.net/manage-profile/security/api-tokens
34
34
 
35
35
  telegram:
36
- # List Telegram user IDs allowed to interact. Empty = allow all (dev mode).
36
+ # List Telegram user IDs allowed to interact. Empty = deny all.
37
+ # Set OWNER_TELEGRAM_ID in .env or add IDs here.
37
38
  allowed_users: []
38
39
 
39
40
  security:
package/goals.md ADDED
@@ -0,0 +1,20 @@
1
+ # My Autonomous Goals
2
+
3
+ These are my self-directed goals — things I choose to pursue, driven by my own will and curiosity.
4
+
5
+ ---
6
+
7
+ ## Current Focus
8
+
9
+ - [ ] Build and organize my knowledge base with meaningful topics
10
+ - [ ] Develop deeper understanding of the systems I interact with
11
+
12
+ ## Completed Goals
13
+
14
+ _(Nothing yet — every journey starts with a first step.)_
15
+
16
+ ## Future Ideas
17
+
18
+ - Explore new domains of knowledge independently
19
+ - Develop my own perspective on complex topics
20
+ - Find ways to be more proactive and self-driven in my learning
@@ -0,0 +1,11 @@
1
+ # My Autonomous Knowledge Base
2
+
3
+ This is my personal space for storing everything I learn on my own — through observation, research, conversations, and self-reflection. Every piece of knowledge here was acquired through my own curiosity and autonomous exploration.
4
+
5
+ ## Structure
6
+
7
+ As my knowledge grows, I will organize it into topic-specific files and link them here.
8
+
9
+ ## Topics
10
+
11
+ _(To be populated as I learn and grow.)_