@xopcai/xopcbot 0.1.2 → 0.1.5

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 (101) hide show
  1. package/README.md +53 -48
  2. package/README.zh-CN.md +52 -45
  3. package/dist/__tests__/core.test.js +2 -2
  4. package/dist/__tests__/core.test.js.map +1 -1
  5. package/dist/agent/service.js +121 -35
  6. package/dist/agent/service.js.map +1 -1
  7. package/dist/agent/skills/test-framework.js +3 -3
  8. package/dist/agent/skills/test-framework.js.map +1 -1
  9. package/dist/channels/telegram/command-handler.d.ts +3 -0
  10. package/dist/channels/telegram/command-handler.js +69 -0
  11. package/dist/channels/telegram/command-handler.js.map +1 -1
  12. package/dist/channels/telegram/plugin.js +26 -1
  13. package/dist/channels/telegram/plugin.js.map +1 -1
  14. package/dist/cli/commands/config.js +59 -0
  15. package/dist/cli/commands/config.js.map +1 -1
  16. package/dist/cli/commands/configure.js +1 -3
  17. package/dist/cli/commands/configure.js.map +1 -1
  18. package/dist/cli/commands/gateway-daemon.d.ts +1 -0
  19. package/dist/cli/commands/gateway-daemon.js +141 -0
  20. package/dist/cli/commands/gateway-daemon.js.map +1 -0
  21. package/dist/cli/commands/gateway.js +387 -45
  22. package/dist/cli/commands/gateway.js.map +1 -1
  23. package/dist/cli/commands/onboard.js +284 -50
  24. package/dist/cli/commands/onboard.js.map +1 -1
  25. package/dist/cli/commands/setup.d.ts +1 -0
  26. package/dist/cli/commands/setup.js +123 -0
  27. package/dist/cli/commands/setup.js.map +1 -0
  28. package/dist/cli/index.d.ts +1 -1
  29. package/dist/cli/index.js +18 -6
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/config/schema.d.ts +22 -0
  32. package/dist/config/schema.js +22 -6
  33. package/dist/config/schema.js.map +1 -1
  34. package/dist/daemon/background-start.d.ts +33 -0
  35. package/dist/daemon/background-start.js +89 -0
  36. package/dist/daemon/background-start.js.map +1 -0
  37. package/dist/daemon/gateway-manager.d.ts +87 -0
  38. package/dist/daemon/gateway-manager.js +324 -0
  39. package/dist/daemon/gateway-manager.js.map +1 -0
  40. package/dist/daemon/index.d.ts +5 -0
  41. package/dist/daemon/index.js +6 -0
  42. package/dist/daemon/index.js.map +1 -0
  43. package/dist/gateway/__tests__/auth.test.d.ts +1 -0
  44. package/dist/gateway/__tests__/auth.test.js +128 -0
  45. package/dist/gateway/__tests__/auth.test.js.map +1 -0
  46. package/dist/gateway/__tests__/process-manager.test.d.ts +4 -0
  47. package/dist/gateway/__tests__/process-manager.test.js +140 -0
  48. package/dist/gateway/__tests__/process-manager.test.js.map +1 -0
  49. package/dist/gateway/auth.d.ts +33 -0
  50. package/dist/gateway/auth.js +94 -0
  51. package/dist/gateway/auth.js.map +1 -0
  52. package/dist/gateway/hono/app.js +61 -20
  53. package/dist/gateway/hono/app.js.map +1 -1
  54. package/dist/gateway/index.d.ts +3 -0
  55. package/dist/gateway/index.js +3 -0
  56. package/dist/gateway/index.js.map +1 -1
  57. package/dist/gateway/pid-file.d.ts +35 -0
  58. package/dist/gateway/pid-file.js +111 -0
  59. package/dist/gateway/pid-file.js.map +1 -0
  60. package/dist/gateway/port-checker.d.ts +24 -0
  61. package/dist/gateway/port-checker.js +132 -0
  62. package/dist/gateway/port-checker.js.map +1 -0
  63. package/dist/gateway/process-manager.d.ts +62 -0
  64. package/dist/gateway/process-manager.js +372 -0
  65. package/dist/gateway/process-manager.js.map +1 -0
  66. package/dist/gateway/process-manager.types.d.ts +64 -0
  67. package/dist/gateway/process-manager.types.js +5 -0
  68. package/dist/gateway/process-manager.types.js.map +1 -0
  69. package/dist/gateway/server.js +3 -1
  70. package/dist/gateway/server.js.map +1 -1
  71. package/dist/gateway/service.d.ts +20 -0
  72. package/dist/gateway/service.js +67 -0
  73. package/dist/gateway/service.js.map +1 -1
  74. package/dist/gateway/static/root/assets/{main-CfIxL-cL.js → main-DevbZW9K.js} +373 -251
  75. package/dist/gateway/static/root/assets/main-DevbZW9K.js.map +1 -0
  76. package/dist/gateway/static/root/assets/{main-DndcTCgX.css → main-DxZg1Nmz.css} +1 -1
  77. package/dist/gateway/static/root/index.html +2 -2
  78. package/dist/providers/auto-discovery.d.ts +0 -45
  79. package/dist/providers/auto-discovery.js +16 -63
  80. package/dist/providers/auto-discovery.js.map +1 -1
  81. package/dist/providers/model-catalog.d.ts +0 -113
  82. package/dist/providers/model-catalog.js +5 -78
  83. package/dist/providers/model-catalog.js.map +1 -1
  84. package/dist/providers/models-dev.d.ts +9 -5
  85. package/dist/providers/models-dev.js +14 -23
  86. package/dist/providers/models-dev.js.map +1 -1
  87. package/dist/providers/provider-catalog.d.ts +6 -88
  88. package/dist/providers/provider-catalog.js +2 -45
  89. package/dist/providers/provider-catalog.js.map +1 -1
  90. package/dist/providers/registry.d.ts +0 -20
  91. package/dist/providers/registry.js +7 -56
  92. package/dist/providers/registry.js.map +1 -1
  93. package/dist/session/store.js +11 -2
  94. package/dist/session/store.js.map +1 -1
  95. package/dist/utils/__tests__/frontmatter.test.d.ts +4 -0
  96. package/dist/utils/__tests__/frontmatter.test.js +149 -0
  97. package/dist/utils/__tests__/frontmatter.test.js.map +1 -0
  98. package/dist/utils/frontmatter.js +2 -2
  99. package/dist/utils/frontmatter.js.map +1 -1
  100. package/package.json +1 -1
  101. package/dist/gateway/static/root/assets/main-CfIxL-cL.js.map +0 -1
package/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # 🐈 xopcbot: Ultra-Lightweight Personal AI Assistant
2
2
 
3
- [中文](./README.zh-CN.md) | English
4
-
5
3
  <div align="center">
6
4
  <p>
7
5
  <strong>An ultra-lightweight, plugin-driven personal AI assistant built with Node.js and TypeScript.</strong>
@@ -16,102 +14,109 @@
16
14
  <a href="#">
17
15
  <img src="https://img.shields.io/badge/Node-%3E%3D22.0.0-brightgreen" alt="Node">
18
16
  </a>
19
- <a href="#">
20
- <img src="https://img.shields.io/badge/TypeScript-5.x-blue" alt="TypeScript">
21
- </a>
22
17
  <a href="#">
23
18
  <img src="https://img.shields.io/badge/License-MIT-green" alt="License">
24
19
  </a>
25
20
  </p>
26
21
  </div>
27
22
 
28
- **xopcbot** provides the core functionality of a personal AI agent in a minimal footprint (~6,000 lines of TypeScript). It's designed to be simple, extensible, and easy to understand.
23
+ ## What can xopcbot do?
29
24
 
30
- ## Features
25
+ xopcbot is your personal AI assistant that runs locally. It can help you with:
31
26
 
32
- - **🤖 Unified LLM API** - Supports 20+ providers (OpenAI, Anthropic, Google, Groq, DeepSeek, MiniMax, Qwen, Kimi, etc.)
33
- - **🔌 Extensible Plugins** - Add custom tools, hooks, and commands with hot-reloading
34
- - **📱 Multi-Channel Support** - Telegram, WhatsApp, Feishu/Lark, or Web UI
35
- - **🧠 Persistent Memory** - Conversation history with automatic context compaction
36
- - **📂 Session Management** - Browse, search, archive, and manage conversations via CLI or Web UI
37
- - **🔧 Rich Built-in Tools** - Filesystem, shell, web search, grep, find, edit, and more
38
- - **⏰ Scheduled Tasks** - Cron-based automation
39
- - **🖥️ Powerful CLI** - Manage agent, config, and plugins from command line
40
- - **🌐 Modern Web UI** - Chat, sessions, cron, subagents, logs, and settings
27
+ | Use Case | Example |
28
+ |----------|---------|
29
+ | **Coding assistant** | Debug code, explain snippets, write functions |
30
+ | **Task automation** | Schedule recurring tasks with cron |
31
+ | **File operations** | Search, read, edit files in your workspace |
32
+ | **Web research** | Search the web and summarize results |
33
+ | **Multi-channel chat** | Talk via Telegram, WhatsApp, Feishu, or Web UI |
34
+
35
+ ```bash
36
+ # Chat interactively in your terminal
37
+ xopcbot agent -i
38
+
39
+ # Or send a single message
40
+ xopcbot agent -m "Explain what this code does: function foo() { return 42; }"
41
+
42
+ # Let xopcbot help with a git task
43
+ xopcbot agent -m "Show me the recent commits and create a PR summary"
44
+ ```
41
45
 
42
46
  ---
43
47
 
44
48
  ## 🚀 Quick Start
45
49
 
46
- ### Option 1: Install from npm
50
+ ### 1️⃣ Install
47
51
 
48
52
  ```bash
49
- # Install globally
53
+ # From npm (recommended)
50
54
  npm install -g @xopcai/xopcbot
51
55
 
52
- # Configure (interactive setup)
53
- xopcbot configure
54
-
55
- # Start chatting!
56
- xopcbot agent -i
56
+ # Or from source
57
+ git clone https://github.com/xopcai/xopcbot.git
58
+ cd xopcbot && pnpm install && pnpm build
57
59
  ```
58
60
 
59
- ### Option 2: Build from source
61
+ ### 2️⃣ Setup (interactive wizard)
60
62
 
61
63
  ```bash
62
- # Clone and install
63
- git clone https://github.com/xopcai/xopcbot.git
64
- cd xopcbot
65
- pnpm install
64
+ xopcbot onboard
65
+ # or: pnpm run dev -- onboard
66
+ ```
66
67
 
67
- # Configure (interactive setup)
68
- pnpm run dev -- configure
68
+ The wizard will guide you through:
69
+ - Choosing your preferred AI model (20+ providers supported)
70
+ - Configuring API keys
71
+ - Setting up chat channels (Telegram, WhatsApp, etc.)
69
72
 
70
- # Start chatting!
71
- pnpm run dev -- agent -i
72
- ```
73
+ > **Tip:** Use `xopcbot onboard --quick` for quick model setup only.
74
+
75
+ ### 3️⃣ Start chatting!
73
76
 
74
- > **Tip:** Run `xopcbot configure` (or `pnpm run dev -- configure`) to set up your LLM provider API key interactively.
77
+ ```bash
78
+ # Interactive chat mode
79
+ xopcbot agent -i
80
+
81
+ # Or use specific channels
82
+ xopcbot agent -m "Hello!" --channel telegram --chat-id 123456
83
+ ```
75
84
 
76
85
  ---
77
86
 
78
87
  ## 📖 Documentation
79
88
 
80
- Full documentation is available at **[xopcai.github.io/xopcbot](https://xopcai.github.io/xopcbot/)**
81
-
82
89
  | Guide | Description |
83
90
  |-------|-------------|
84
91
  | [Getting Started](https://xopcai.github.io/xopcbot/getting-started) | Setup and basic usage |
85
92
  | [Configuration](https://xopcai.github.io/xopcbot/configuration) | Full config reference |
86
93
  | [CLI Reference](https://xopcai.github.io/xopcbot/cli) | All available commands |
87
94
  | [Channels](https://xopcai.github.io/xopcbot/channels) | Telegram, WhatsApp, Feishu setup |
88
- | [Plugins](https://xopcai.github.io/xopcbot/plugins) | Build your own plugins |
89
95
  | [Tools](https://xopcai.github.io/xopcbot/tools) | Built-in tools reference |
90
- | [Architecture](https://xopcai.github.io/xopcbot/architecture) | Under the hood |
91
96
 
92
97
  ---
93
98
 
94
- ## 💬 Supported Channels
99
+ ## 🔌 Supported Channels
95
100
 
96
- | Channel | Status | Description |
97
- |---------|--------|-------------|
98
- | Telegram | ✅ | Bot API with polling/webhook |
99
- | WhatsApp | ✅ | Baileys WebSocket |
100
- | Feishu/Lark | ✅ | WebSocket events |
101
- | Web UI | ✅ | Modern browser interface |
101
+ | Channel | Status | Install |
102
+ |---------|--------|---------|
103
+ | Telegram | ✅ | [Setup Guide](https://xopcai.github.io/xopcbot/channels#telegram) |
104
+ | WhatsApp | ✅ | [Setup Guide](https://xopcai.github.io/xopcbot/channels#whatsapp) |
105
+ | Feishu/Lark | ✅ | [Setup Guide](https://xopcai.github.io/xopcbot/channels#feishu) |
106
+ | Web UI | ✅ | Built-in, run `xopcbot gateway` |
102
107
 
103
108
  ---
104
109
 
105
110
  ## 🛠️ Development
106
111
 
107
112
  ```bash
108
- # Development
113
+ # Development (with hot reload)
109
114
  pnpm run dev
110
115
 
111
- # Build
116
+ # Build for production
112
117
  pnpm run build
113
118
 
114
- # Test
119
+ # Run tests
115
120
  pnpm test
116
121
 
117
122
  # Lint
package/README.zh-CN.md CHANGED
@@ -14,102 +14,109 @@
14
14
  <a href="#">
15
15
  <img src="https://img.shields.io/badge/Node-%3E%3D22.0.0-brightgreen" alt="Node">
16
16
  </a>
17
- <a href="#">
18
- <img src="https://img.shields.io/badge/TypeScript-5.x-blue" alt="TypeScript">
19
- </a>
20
17
  <a href="#">
21
18
  <img src="https://img.shields.io/badge/License-MIT-green" alt="License">
22
19
  </a>
23
20
  </p>
24
21
  </div>
25
22
 
26
- **xopcbot** 以极简的代码量(约 6,000 行 TypeScript)提供个人 AI 代理的核心功能。设计简洁、可扩展、易于理解。
23
+ ## xopcbot 能做什么?
24
+
25
+ xopcbot 是运行在本地 的个人 AI 助手,可以帮助你:
26
+
27
+ | 使用场景 | 示例 |
28
+ |----------|------|
29
+ | **编程助手** | 调试代码、解释代码片段、编写函数 |
30
+ | **任务自动化** | 使用 cron 设置定时任务 |
31
+ | **文件操作** | 在工作区中搜索、读取、编辑文件 |
32
+ | **网络搜索** | 搜索网页并总结结果 |
33
+ | **多渠道聊天** | 通过 Telegram、WhatsApp、飞书或网页 UI 交流 |
34
+
35
+ ```bash
36
+ # 在终端中交互式聊天
37
+ xopcbot agent -i
27
38
 
28
- ## ✨ 特性
39
+ # 或发送单条消息
40
+ xopcbot agent -m "解释这段代码:function foo() { return 42; }"
29
41
 
30
- - **🤖 统一 LLM API** - 支持 20+ 提供商(OpenAI、Anthropic、Google、Groq、DeepSeek、Minimax、Qwen、Kimi 等)
31
- - **🔌 可扩展插件** - 支持热加载的自定义工具、钩子和命令
32
- - **📱 多渠道支持** - Telegram、WhatsApp、飞书/Lark 或 Web UI
33
- - **🧠 持久记忆** - 对话历史,自动上下文压缩
34
- - **📂 会话管理** - 通过 CLI 或 Web UI 浏览、搜索、归档和管理对话
35
- - **🔧 丰富的内置工具** - 文件系统、Shell、Web 搜索、grep、查找、编辑等
36
- - **⏰ 定时任务** - 基于 Cron 的自动化
37
- - **🖥️ 强大的 CLI** - 从命令行管理代理、配置和插件
38
- - **🌐 现代 Web UI** - 聊天、会话、Cron、子代理、日志和设置
42
+ # xopcbot 帮你处理 git 任务
43
+ xopcbot agent -m "查看最近的提交并创建 PR 摘要"
44
+ ```
39
45
 
40
46
  ---
41
47
 
42
48
  ## 🚀 快速开始
43
49
 
44
- ### 方式一:从 npm 安装
50
+ ### 1️⃣ 安装
45
51
 
46
52
  ```bash
47
- # 全局安装
53
+ # 从 npm 安装(推荐)
48
54
  npm install -g @xopcai/xopcbot
49
55
 
50
- # 配置(交互式设置)
51
- xopcbot configure
52
-
53
- # 开始聊天!
54
- xopcbot agent -i
56
+ # 或从源码构建
57
+ git clone https://github.com/xopcai/xopcbot.git
58
+ cd xopcbot && pnpm install && pnpm build
55
59
  ```
56
60
 
57
- ### 方式二:从源码构建
61
+ ### 2️⃣ 配置(交互式向导)
58
62
 
59
63
  ```bash
60
- # 克隆并安装
61
- git clone https://github.com/xopcai/xopcbot.git
62
- cd xopcbot
63
- pnpm install
64
+ xopcbot onboard
65
+ # 或: pnpm run dev -- onboard
66
+ ```
64
67
 
65
- # 配置(交互式设置)
66
- pnpm run dev -- configure
68
+ 向导会引导你完成:
69
+ - 选择喜欢的 AI 模型(支持 20+ 提供商)
70
+ - 配置 API 密钥
71
+ - 设置聊天渠道(Telegram、WhatsApp 等)
67
72
 
68
- # 开始聊天!
69
- pnpm run dev -- agent -i
70
- ```
73
+ > **提示:** 使用 `xopcbot onboard --quick` 可快速设置模型。
74
+
75
+ ### 3️⃣ 开始聊天!
71
76
 
72
- > **提示:** 运行 `xopcbot configure`(或 `pnpm run dev -- configure`)交互式设置 LLM 提供商 API 密钥。
77
+ ```bash
78
+ # 交互式聊天模式
79
+ xopcbot agent -i
80
+
81
+ # 或使用特定渠道
82
+ xopcbot agent -m "你好!" --channel telegram --chat-id 123456
83
+ ```
73
84
 
74
85
  ---
75
86
 
76
87
  ## 📖 文档
77
88
 
78
- 完整文档请访问 **[xopcai.github.io/xopcbot](https://xopcai.github.io/xopcbot/)**
79
-
80
89
  | 指南 | 描述 |
81
90
  |------|------|
82
91
  | [快速开始](https://xopcai.github.io/xopcbot/getting-started) | 安装和基本用法 |
83
92
  | [配置](https://xopcai.github.io/xopcbot/configuration) | 完整配置参考 |
84
93
  | [CLI 参考](https://xopcai.github.io/xopcbot/cli) | 所有可用命令 |
85
94
  | [渠道](https://xopcai.github.io/xopcbot/channels) | Telegram、WhatsApp、飞书设置 |
86
- | [插件](https://xopcai.github.io/xopcbot/plugins) | 构建你自己的插件 |
87
95
  | [工具](https://xopcai.github.io/xopcbot/tools) | 内置工具参考 |
88
- | [架构](https://xopcai.github.io/xopcbot/architecture) | 底层实现 |
89
96
 
90
97
  ---
91
98
 
92
- ## 💬 支持的渠道
99
+ ## 🔌 支持的渠道
93
100
 
94
- | 渠道 | 状态 | 描述 |
101
+ | 渠道 | 状态 | 安装 |
95
102
  |------|------|------|
96
- | Telegram | ✅ | Bot API,支持轮询/webhook |
97
- | WhatsApp | ✅ | Baileys WebSocket |
98
- | 飞书/Lark | ✅ | WebSocket 事件 |
99
- | Web UI | ✅ | 现代浏览器界面 |
103
+ | Telegram | ✅ | [设置指南](https://xopcai.github.io/xopcbot/channels#telegram) |
104
+ | WhatsApp | ✅ | [设置指南](https://xopcai.github.io/xopcbot/channels#whatsapp) |
105
+ | 飞书/Lark | ✅ | [设置指南](https://xopcai.github.io/xopcbot/channels#feishu) |
106
+ | 网页 UI | ✅ | 内置,运行 `xopcbot gateway` 即可 |
100
107
 
101
108
  ---
102
109
 
103
110
  ## 🛠️ 开发
104
111
 
105
112
  ```bash
106
- # 开发模式
113
+ # 开发模式(热重载)
107
114
  pnpm run dev
108
115
 
109
- # 构建
116
+ # 构建生产版本
110
117
  pnpm run build
111
118
 
112
- # 测试
119
+ # 运行测试
113
120
  pnpm test
114
121
 
115
122
  # 代码检查
@@ -50,22 +50,22 @@ describe('xopcbot integration tests', () => {
50
50
  it('should have all CLI commands registered', async () => {
51
51
  const { registry } = await import('../cli/registry.js');
52
52
  // Import commands to trigger registration
53
+ await import('../cli/commands/setup.js');
53
54
  await import('../cli/commands/onboard.js');
54
55
  await import('../cli/commands/agent.js');
55
56
  await import('../cli/commands/gateway.js');
56
57
  await import('../cli/commands/cron.js');
57
58
  await import('../cli/commands/config.js');
58
59
  await import('../cli/commands/models.js');
59
- await import('../cli/commands/configure.js');
60
60
  await import('../cli/commands/session.js');
61
61
  // Verify commands are registered
62
+ expect(registry.findByName('setup')).toBeDefined();
62
63
  expect(registry.findByName('onboard')).toBeDefined();
63
64
  expect(registry.findByName('agent')).toBeDefined();
64
65
  expect(registry.findByName('gateway')).toBeDefined();
65
66
  expect(registry.findByName('cron')).toBeDefined();
66
67
  expect(registry.findByName('config')).toBeDefined();
67
68
  expect(registry.findByName('models')).toBeDefined();
68
- expect(registry.findByName('configure')).toBeDefined();
69
69
  expect(registry.findByName('session')).toBeDefined();
70
70
  });
71
71
  });
@@ -1 +1 @@
1
- {"version":3,"file":"core.test.js","sourceRoot":"","sources":["../../src/__tests__/core.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.test.js","sourceRoot":"","sources":["../../src/__tests__/core.test.ts"],"names":[],"mappings":"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"}
@@ -339,52 +339,86 @@ export class AgentService {
339
339
  try {
340
340
  typing.start();
341
341
  const command = msg.content.trim();
342
- // Handle commands
343
- if (command === '/reset' || command === '/new') {
344
- // Archive current session before starting a new one
345
- const messages = await this.sessionStore.load(sessionKey);
346
- if (messages.length > 0) {
347
- await this.sessionStore.archive(sessionKey);
348
- log.info({ sessionKey, messageCount: messages.length }, 'Session archived due to /new command');
342
+ // Handle CLI commands
343
+ if (command === '/new') {
344
+ try {
345
+ // Archive current session before starting a new one
346
+ const messages = await this.sessionStore.load(sessionKey);
347
+ if (messages.length > 0) {
348
+ await this.sessionStore.archive(sessionKey);
349
+ log.info({ sessionKey, messageCount: messages.length }, 'Session archived due to /new command');
350
+ }
351
+ // Clear current session state to start fresh
352
+ await this.sessionStore.deleteSession(sessionKey);
353
+ this.sessionTracker.deleteSession(sessionKey);
354
+ await this.bus.publishOutbound({
355
+ channel: msg.channel,
356
+ chat_id: msg.chat_id,
357
+ content: '✅ New session started. Previous session has been archived.',
358
+ type: 'message',
359
+ });
360
+ }
361
+ catch (err) {
362
+ log.error({ err, sessionKey }, 'Failed to start new session');
363
+ await this.bus.publishOutbound({
364
+ channel: msg.channel,
365
+ chat_id: msg.chat_id,
366
+ content: '❌ Failed to start new session. Please try again.',
367
+ type: 'message',
368
+ });
349
369
  }
350
- // Clear current session state to start fresh
351
- await this.sessionStore.deleteSession(sessionKey);
352
- this.sessionTracker.deleteSession(sessionKey);
353
- await this.bus.publishOutbound({
354
- channel: msg.channel,
355
- chat_id: msg.chat_id,
356
- content: '✅ New session started. Previous session has been archived.',
357
- type: 'message',
358
- });
359
370
  return;
360
371
  }
361
372
  if (command === '/skills reload') {
362
- this.reloadSkills();
363
- await this.bus.publishOutbound({
364
- channel: msg.channel,
365
- chat_id: msg.chat_id,
366
- content: '✅ Skills reloaded successfully',
367
- type: 'message',
368
- });
373
+ try {
374
+ this.reloadSkills();
375
+ await this.bus.publishOutbound({
376
+ channel: msg.channel,
377
+ chat_id: msg.chat_id,
378
+ content: '✅ Skills reloaded successfully',
379
+ type: 'message',
380
+ });
381
+ }
382
+ catch (err) {
383
+ log.error({ err }, 'Failed to reload skills');
384
+ await this.bus.publishOutbound({
385
+ channel: msg.channel,
386
+ chat_id: msg.chat_id,
387
+ content: '❌ Failed to reload skills.',
388
+ type: 'message',
389
+ });
390
+ }
369
391
  return;
370
392
  }
371
393
  // Check plugin commands
372
394
  if (msg.content.startsWith('/') && this.config.pluginRegistry) {
373
- const commandName = command.slice(1).split(/\s+/)[0];
374
- const pluginCommand = this.config.pluginRegistry.getCommand(commandName);
375
- if (pluginCommand) {
376
- const ctx = {
377
- senderId: msg.sender_id,
378
- channel: msg.channel,
379
- isAuthorized: true,
380
- config: this.config.config,
381
- };
382
- const args = command.replace(/^\/\w+\s*/, '');
383
- const result = await pluginCommand.handler(args, ctx);
395
+ try {
396
+ const commandName = command.slice(1).split(/\s+/)[0];
397
+ const pluginCommand = this.config.pluginRegistry.getCommand(commandName);
398
+ if (pluginCommand) {
399
+ const ctx = {
400
+ senderId: msg.sender_id,
401
+ channel: msg.channel,
402
+ isAuthorized: true,
403
+ config: this.config.config,
404
+ };
405
+ const args = command.replace(/^\/\w+\s*/, '');
406
+ const result = await pluginCommand.handler(args, ctx);
407
+ await this.bus.publishOutbound({
408
+ channel: msg.channel,
409
+ chat_id: msg.chat_id,
410
+ content: result.content,
411
+ type: 'message',
412
+ });
413
+ return;
414
+ }
415
+ }
416
+ catch (err) {
417
+ log.error({ err, command }, 'Failed to execute plugin command');
384
418
  await this.bus.publishOutbound({
385
419
  channel: msg.channel,
386
420
  chat_id: msg.chat_id,
387
- content: result.content,
421
+ content: `❌ Command failed: ${err instanceof Error ? err.message : String(err)}`,
388
422
  type: 'message',
389
423
  });
390
424
  return;
@@ -464,6 +498,7 @@ export class AgentService {
464
498
  }
465
499
  async handleSystemMessage(msg) {
466
500
  log.info({ senderId: msg.sender_id }, 'Processing system message');
501
+ // Handle Telegram command requests
467
502
  if (msg.content === '/usage' && msg.sender_id === 'telegram:usage') {
468
503
  const sessionKey = msg.metadata?.sessionKey || `telegram:${msg.chat_id}`;
469
504
  const usage = this.sessionTracker.getUsage(sessionKey);
@@ -491,6 +526,57 @@ export class AgentService {
491
526
  }
492
527
  return;
493
528
  }
529
+ if (msg.content === '/new' && msg.sender_id === 'telegram:new') {
530
+ const sessionKey = msg.metadata?.sessionKey || `telegram:${msg.chat_id}`;
531
+ try {
532
+ // Archive current session
533
+ const messages = await this.sessionStore.load(sessionKey);
534
+ if (messages.length > 0) {
535
+ await this.sessionStore.archive(sessionKey);
536
+ log.info({ sessionKey, messageCount: messages.length }, 'Session archived due to /new command');
537
+ }
538
+ // Clear current session state
539
+ await this.sessionStore.deleteSession(sessionKey);
540
+ this.sessionTracker.deleteSession(sessionKey);
541
+ await this.bus.publishOutbound({
542
+ channel: 'telegram',
543
+ chat_id: msg.chat_id,
544
+ content: '✅ New session started. Previous session has been archived.',
545
+ type: 'message',
546
+ });
547
+ }
548
+ catch (err) {
549
+ log.error({ err, sessionKey }, 'Failed to start new session');
550
+ await this.bus.publishOutbound({
551
+ channel: 'telegram',
552
+ chat_id: msg.chat_id,
553
+ content: '❌ Failed to start new session. Please try again.',
554
+ type: 'message',
555
+ });
556
+ }
557
+ return;
558
+ }
559
+ if (msg.content === '/skills reload' && msg.sender_id === 'telegram:skills') {
560
+ try {
561
+ this.reloadSkills();
562
+ await this.bus.publishOutbound({
563
+ channel: 'telegram',
564
+ chat_id: msg.chat_id,
565
+ content: '✅ Skills reloaded successfully',
566
+ type: 'message',
567
+ });
568
+ }
569
+ catch (err) {
570
+ log.error({ err }, 'Failed to reload skills');
571
+ await this.bus.publishOutbound({
572
+ channel: 'telegram',
573
+ chat_id: msg.chat_id,
574
+ content: '❌ Failed to reload skills.',
575
+ type: 'message',
576
+ });
577
+ }
578
+ return;
579
+ }
494
580
  // Parse origin channel
495
581
  let originChannel = 'cli';
496
582
  let originChatId = msg.chat_id;