opencode-channels 0.1.0
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/README.md +187 -0
- package/bin/cli.js +24 -0
- package/bin/cli.ts +62 -0
- package/dist/bot/auto-binding.d.ts +6 -0
- package/dist/bot/auto-binding.d.ts.map +1 -0
- package/dist/bot/auto-binding.js +81 -0
- package/dist/bot/auto-binding.js.map +1 -0
- package/dist/bot/commands/agents.d.ts +9 -0
- package/dist/bot/commands/agents.d.ts.map +1 -0
- package/dist/bot/commands/agents.js +53 -0
- package/dist/bot/commands/agents.js.map +1 -0
- package/dist/bot/commands/base.d.ts +4 -0
- package/dist/bot/commands/base.d.ts.map +1 -0
- package/dist/bot/commands/base.js +241 -0
- package/dist/bot/commands/base.js.map +1 -0
- package/dist/bot/commands/dynamic.d.ts +8 -0
- package/dist/bot/commands/dynamic.d.ts.map +1 -0
- package/dist/bot/commands/dynamic.js +82 -0
- package/dist/bot/commands/dynamic.js.map +1 -0
- package/dist/bot/commands/index.d.ts +15 -0
- package/dist/bot/commands/index.d.ts.map +1 -0
- package/dist/bot/commands/index.js +25 -0
- package/dist/bot/commands/index.js.map +1 -0
- package/dist/bot/commands/models.d.ts +7 -0
- package/dist/bot/commands/models.d.ts.map +1 -0
- package/dist/bot/commands/models.js +60 -0
- package/dist/bot/commands/models.js.map +1 -0
- package/dist/bot/commands/sdk-commands.d.ts +5 -0
- package/dist/bot/commands/sdk-commands.d.ts.map +1 -0
- package/dist/bot/commands/sdk-commands.js +135 -0
- package/dist/bot/commands/sdk-commands.js.map +1 -0
- package/dist/bot/handlers/callback.d.ts +3 -0
- package/dist/bot/handlers/callback.d.ts.map +1 -0
- package/dist/bot/handlers/callback.js +52 -0
- package/dist/bot/handlers/callback.js.map +1 -0
- package/dist/bot/handlers/file.d.ts +3 -0
- package/dist/bot/handlers/file.d.ts.map +1 -0
- package/dist/bot/handlers/file.js +121 -0
- package/dist/bot/handlers/file.js.map +1 -0
- package/dist/bot/handlers/group.d.ts +3 -0
- package/dist/bot/handlers/group.d.ts.map +1 -0
- package/dist/bot/handlers/group.js +41 -0
- package/dist/bot/handlers/group.js.map +1 -0
- package/dist/bot/handlers/index.d.ts +4 -0
- package/dist/bot/handlers/index.d.ts.map +1 -0
- package/dist/bot/handlers/index.js +13 -0
- package/dist/bot/handlers/index.js.map +1 -0
- package/dist/bot/handlers/message.d.ts +15 -0
- package/dist/bot/handlers/message.d.ts.map +1 -0
- package/dist/bot/handlers/message.js +183 -0
- package/dist/bot/handlers/message.js.map +1 -0
- package/dist/bot/handlers/topic.d.ts +3 -0
- package/dist/bot/handlers/topic.d.ts.map +1 -0
- package/dist/bot/handlers/topic.js +43 -0
- package/dist/bot/handlers/topic.js.map +1 -0
- package/dist/bot/index.d.ts +5 -0
- package/dist/bot/index.d.ts.map +1 -0
- package/dist/bot/index.js +66 -0
- package/dist/bot/index.js.map +1 -0
- package/dist/cli/daemon.d.ts +6 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +255 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/init.d.ts +19 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +235 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/logs.d.ts +6 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +42 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/start.d.ts +4 -0
- package/dist/cli/start.d.ts.map +1 -0
- package/dist/cli/start.js +254 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/plugin/index.d.ts +4 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +73 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/server/api.d.ts +3 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +30 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/events.d.ts +18 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/events.js +131 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/filters.d.ts +19 -0
- package/dist/server/filters.d.ts.map +1 -0
- package/dist/server/filters.js +149 -0
- package/dist/server/filters.js.map +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +10 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/sdk.d.ts +36 -0
- package/dist/server/sdk.d.ts.map +1 -0
- package/dist/server/sdk.js +485 -0
- package/dist/server/sdk.js.map +1 -0
- package/dist/shared/config.d.ts +34 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +163 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/logger.d.ts +5 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +114 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/mapping.d.ts +90 -0
- package/dist/shared/mapping.d.ts.map +1 -0
- package/dist/shared/mapping.js +234 -0
- package/dist/shared/mapping.js.map +1 -0
- package/dist/shared/message-queue.d.ts +64 -0
- package/dist/shared/message-queue.d.ts.map +1 -0
- package/dist/shared/message-queue.js +138 -0
- package/dist/shared/message-queue.js.map +1 -0
- package/dist/shared/types.d.ts +284 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +7 -0
- package/dist/shared/types.js.map +1 -0
- package/index.js +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { CommandGroup } from '@grammyjs/commands';
|
|
2
|
+
import { getProjectByChat, getSessionByTopic, getGroupSettings } from '../../shared/mapping.js';
|
|
3
|
+
import { loadConfig } from '../../shared/config.js';
|
|
4
|
+
import { validateProjectPath } from '../auto-binding.js';
|
|
5
|
+
import { addGroupMapping, addTopicMapping } from '../../shared/mapping.js';
|
|
6
|
+
import { createSessionWithInfo, getAgents, getProviders, compactSession } from '../../server/sdk.js';
|
|
7
|
+
import { filterVisibleModels, formatModelList, formatAgentList } from '../../server/filters.js';
|
|
8
|
+
import { buildBoundMenu } from './dynamic.js';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import { execSync } from 'child_process';
|
|
12
|
+
function getHelpMessage() {
|
|
13
|
+
return ('👋 欢迎使用 OpenCode Channels Bot!\n\n' +
|
|
14
|
+
'📋 可用命令:\n' +
|
|
15
|
+
'/new [项目名] - 创建新项目并绑定\n' +
|
|
16
|
+
'/bind <项目路径> - 绑定已有项目\n' +
|
|
17
|
+
'/status - 查看当前绑定状态\n' +
|
|
18
|
+
'/agents - 切换 Agent\n' +
|
|
19
|
+
'/models - 切换 Model\n' +
|
|
20
|
+
'/compact - 压缩会话上下文\n' +
|
|
21
|
+
'/help - 显示帮助信息\n\n' +
|
|
22
|
+
'💡 示例:\n' +
|
|
23
|
+
'/new myproject - 创建 myproject 项目\n' +
|
|
24
|
+
'/new - 自动生成项目名');
|
|
25
|
+
}
|
|
26
|
+
function getUnboundMessage() {
|
|
27
|
+
return ('❌ 当前群组未绑定任何项目\n\n' +
|
|
28
|
+
'请先绑定或创建项目:\n' +
|
|
29
|
+
'/new [项目名] - 创建新项目\n' +
|
|
30
|
+
'/bind <项目路径> - 绑定已有项目');
|
|
31
|
+
}
|
|
32
|
+
function initGitRepo(projectPath) {
|
|
33
|
+
const readmePath = path.join(projectPath, 'README.md');
|
|
34
|
+
fs.writeFileSync(readmePath, `# Project\n\nCreated by OpenCode Channels Bot\n`);
|
|
35
|
+
execSync('git init', { cwd: projectPath, stdio: 'pipe' });
|
|
36
|
+
execSync('git add -A', { cwd: projectPath, stdio: 'pipe' });
|
|
37
|
+
execSync('git commit -m "Initial commit"', { cwd: projectPath, stdio: 'pipe' });
|
|
38
|
+
}
|
|
39
|
+
export function createBaseCommands() {
|
|
40
|
+
const group = new CommandGroup();
|
|
41
|
+
group.command('start', '显示帮助信息', async (ctx) => {
|
|
42
|
+
await ctx.reply(getHelpMessage());
|
|
43
|
+
});
|
|
44
|
+
group.command('help', '显示帮助信息', async (ctx) => {
|
|
45
|
+
await ctx.reply(getHelpMessage());
|
|
46
|
+
});
|
|
47
|
+
group.command('status', '查看绑定状态', async (ctx) => {
|
|
48
|
+
const chatId = ctx.chat?.id;
|
|
49
|
+
if (!chatId)
|
|
50
|
+
return;
|
|
51
|
+
const projectPath = getProjectByChat(chatId);
|
|
52
|
+
if (projectPath) {
|
|
53
|
+
await ctx.reply(`✅ 当前群组已绑定到项目:\n${projectPath}`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
await ctx.reply(getUnboundMessage());
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
group.command('new', '创建新项目', async (ctx) => {
|
|
60
|
+
const chatId = ctx.chat?.id;
|
|
61
|
+
if (!chatId)
|
|
62
|
+
return;
|
|
63
|
+
const config = loadConfig();
|
|
64
|
+
if (!config) {
|
|
65
|
+
await ctx.reply('❌ 配置文件未找到,请先运行 init 命令');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const text = ctx.message?.text || '';
|
|
69
|
+
const parts = text.split(/\s+/).filter(p => p && !p.startsWith('@'));
|
|
70
|
+
let projectName;
|
|
71
|
+
if (parts.length < 2) {
|
|
72
|
+
const now = new Date();
|
|
73
|
+
const timestamp = [
|
|
74
|
+
String(now.getMonth() + 1).padStart(2, '0'),
|
|
75
|
+
String(now.getDate()).padStart(2, '0'),
|
|
76
|
+
String(now.getHours()).padStart(2, '0'),
|
|
77
|
+
String(now.getMinutes()).padStart(2, '0'),
|
|
78
|
+
String(now.getSeconds()).padStart(2, '0'),
|
|
79
|
+
].join('');
|
|
80
|
+
const botInfo = await ctx.api.getMe();
|
|
81
|
+
const botName = botInfo.username || 'bot';
|
|
82
|
+
projectName = `${botName}_${timestamp}`;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
projectName = parts[1];
|
|
86
|
+
}
|
|
87
|
+
projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
88
|
+
const projectPath = path.join(config.workspace, projectName);
|
|
89
|
+
if (fs.existsSync(projectPath)) {
|
|
90
|
+
await ctx.reply(`❌ 项目已存在: ${projectName}\n请使用其他名称或使用 /bind 绑定`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
95
|
+
initGitRepo(projectPath);
|
|
96
|
+
addGroupMapping(chatId, projectPath);
|
|
97
|
+
const sessionInfo = await createSessionWithInfo(projectPath, `Telegram Chat ${chatId}`);
|
|
98
|
+
addTopicMapping(chatId, 0, sessionInfo.sessionId);
|
|
99
|
+
const menu = await buildBoundMenu(projectPath);
|
|
100
|
+
await ctx.api.setMyCommands(menu, { scope: { type: 'chat', chat_id: chatId } });
|
|
101
|
+
await ctx.reply(`✅ *项目创建并绑定成功!*\n\n` +
|
|
102
|
+
`📁 *项目名*: \`${projectName}\`\n` +
|
|
103
|
+
`📂 *路径*: \`${projectPath}\`\n` +
|
|
104
|
+
`🤖 *Agent*: \`${sessionInfo.agent || 'default'}\`\n` +
|
|
105
|
+
`🧠 *Model*: \`${sessionInfo.modelId || 'unknown'}\`\n\n` +
|
|
106
|
+
`现在可以直接发送消息与 AI 对话`, { parse_mode: 'Markdown' });
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
110
|
+
await ctx.reply(`❌ 创建项目失败: ${errorMessage}`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
group.command('bind', '绑定已有项目', async (ctx) => {
|
|
114
|
+
const chatId = ctx.chat?.id;
|
|
115
|
+
if (!chatId)
|
|
116
|
+
return;
|
|
117
|
+
const text = ctx.message?.text || '';
|
|
118
|
+
const parts = text.split(/\s+/).filter(p => p && !p.startsWith('@'));
|
|
119
|
+
if (parts.length < 2) {
|
|
120
|
+
await ctx.reply('❌ 请提供项目路径\n用法: /bind <项目路径>');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const projectPath = parts.slice(1).join(' ');
|
|
124
|
+
if (!validateProjectPath(projectPath)) {
|
|
125
|
+
await ctx.reply(`❌ 无效的项目路径: ${projectPath}\n请确保路径存在`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
addGroupMapping(chatId, projectPath);
|
|
130
|
+
const sessionInfo = await createSessionWithInfo(projectPath, `Telegram Chat ${chatId}`);
|
|
131
|
+
addTopicMapping(chatId, 0, sessionInfo.sessionId);
|
|
132
|
+
const menu = await buildBoundMenu(projectPath);
|
|
133
|
+
await ctx.api.setMyCommands(menu, { scope: { type: 'chat', chat_id: chatId } });
|
|
134
|
+
await ctx.reply(`✅ *项目绑定成功!*\n\n` +
|
|
135
|
+
`📂 *项目路径*: \`${projectPath}\`\n` +
|
|
136
|
+
`🤖 *Agent*: \`${sessionInfo.agent || 'default'}\`\n` +
|
|
137
|
+
`🧠 *Model*: \`${sessionInfo.modelId || 'unknown'}\`\n\n` +
|
|
138
|
+
`现在可以直接发送消息与 AI 对话`, { parse_mode: 'Markdown' });
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
142
|
+
await ctx.reply(`❌ 绑定失败: ${errorMessage}`);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
group.command('agents', '切换 Agent', async (ctx) => {
|
|
146
|
+
const chatId = ctx.chat?.id;
|
|
147
|
+
if (!chatId)
|
|
148
|
+
return;
|
|
149
|
+
const projectPath = getProjectByChat(chatId);
|
|
150
|
+
if (!projectPath) {
|
|
151
|
+
await ctx.reply(getUnboundMessage());
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
console.log(`[Command] 获取 Agents,项目路径: ${projectPath}`);
|
|
155
|
+
try {
|
|
156
|
+
const agents = await getAgents(projectPath);
|
|
157
|
+
console.log(`[Command] 获取到 ${agents.length} 个 Agents`);
|
|
158
|
+
if (agents.length === 0) {
|
|
159
|
+
await ctx.reply('❌ 暂无可用 Agent');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const agentList = formatAgentList(agents);
|
|
163
|
+
await ctx.reply(`🤖 可点击切换以下 Agent\n\n${agentList}`);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
167
|
+
console.error(`[Command] 获取 Agents 失败:`, errorMessage);
|
|
168
|
+
await ctx.reply(`❌ 获取 Agent 列表失败: ${errorMessage}`);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
group.command('models', '切换 Model', async (ctx) => {
|
|
172
|
+
const chatId = ctx.chat?.id;
|
|
173
|
+
if (!chatId)
|
|
174
|
+
return;
|
|
175
|
+
const projectPath = getProjectByChat(chatId);
|
|
176
|
+
if (!projectPath) {
|
|
177
|
+
await ctx.reply(getUnboundMessage());
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
console.log(`[Command] 获取 Models,项目路径: ${projectPath}`);
|
|
181
|
+
try {
|
|
182
|
+
const providers = await getProviders(projectPath);
|
|
183
|
+
console.log(`[Command] 获取到 ${providers.length} 个 Providers`);
|
|
184
|
+
if (providers.length === 0) {
|
|
185
|
+
await ctx.reply('❌ 暂无可用 Model');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const visibleModels = filterVisibleModels(providers);
|
|
189
|
+
console.log(`[Command] 筛选后 ${visibleModels.length} 个 Models`);
|
|
190
|
+
if (visibleModels.length === 0) {
|
|
191
|
+
await ctx.reply('❌ 暂无可用 Model(所有 Model 都被筛选掉了)');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const modelList = formatModelList(visibleModels);
|
|
195
|
+
await ctx.reply(`🧠 可点击切换以下模型${modelList}`, { parse_mode: 'HTML' });
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
199
|
+
console.error(`[Command] 获取 Models 失败:`, errorMessage);
|
|
200
|
+
await ctx.reply(`❌ 获取 Model 列表失败: ${errorMessage}`);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
group.command('compact', '压缩会话上下文', async (ctx) => {
|
|
204
|
+
const chatId = ctx.chat?.id;
|
|
205
|
+
if (!chatId)
|
|
206
|
+
return;
|
|
207
|
+
const projectPath = getProjectByChat(chatId);
|
|
208
|
+
if (!projectPath) {
|
|
209
|
+
await ctx.reply(getUnboundMessage());
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const topicId = ctx.message?.message_thread_id || 0;
|
|
213
|
+
const sessionId = getSessionByTopic(chatId, topicId);
|
|
214
|
+
if (!sessionId) {
|
|
215
|
+
await ctx.reply('❌ 未找到会话,请先发送消息创建会话');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const settings = getGroupSettings(chatId);
|
|
219
|
+
try {
|
|
220
|
+
await ctx.reply('⏳ 正在压缩会话上下文...');
|
|
221
|
+
const success = await compactSession(sessionId, projectPath, settings?.model);
|
|
222
|
+
if (success) {
|
|
223
|
+
await ctx.reply('✅ 会话上下文已压缩,历史消息已整理为摘要');
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
await ctx.reply('⚠️ 会话压缩完成,但未生成摘要');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
231
|
+
console.error(`[Command] 压缩会话失败:`, errorMessage);
|
|
232
|
+
await ctx.reply(`❌ 压缩失败: ${errorMessage}`);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
group.command('back', '返回主菜单', async (ctx) => {
|
|
236
|
+
await ctx.setMyCommands?.(group);
|
|
237
|
+
await ctx.reply('✅ 已返回主菜单');
|
|
238
|
+
});
|
|
239
|
+
return group;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/bot/commands/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BotCommand } from 'grammy/types';
|
|
2
|
+
import type { CommandInfo, RegisteredCommand } from '../../shared/types.js';
|
|
3
|
+
export declare function registerCommand(command: CommandInfo): RegisteredCommand;
|
|
4
|
+
export declare function getRegisteredCommand(telegramCmd: string): RegisteredCommand | undefined;
|
|
5
|
+
export declare function clearCommandRegistry(): void;
|
|
6
|
+
export declare function buildUnboundMenu(): Promise<BotCommand[]>;
|
|
7
|
+
export declare function buildBoundMenu(projectPath: string): Promise<BotCommand[]>;
|
|
8
|
+
//# sourceMappingURL=dynamic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/dynamic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA2B5E,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,CAiBvE;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEvF;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAO9D;AAED,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CA+B/E"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { getCommands } from '../../server/sdk.js';
|
|
2
|
+
const commandRegistry = new Map();
|
|
3
|
+
function sanitizeCommandName(name) {
|
|
4
|
+
const sanitized = name.toLowerCase().replace(/[^a-z0-9_]/g, '_');
|
|
5
|
+
const maxLength = 28;
|
|
6
|
+
return sanitized.length > maxLength ? sanitized.substring(0, maxLength) : sanitized;
|
|
7
|
+
}
|
|
8
|
+
function getCommandPrefix(source) {
|
|
9
|
+
switch (source) {
|
|
10
|
+
case 'command':
|
|
11
|
+
return 'cmd_';
|
|
12
|
+
case 'skill':
|
|
13
|
+
return 'sk_';
|
|
14
|
+
case 'mcp':
|
|
15
|
+
return 'mcp_';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function checkNeedsArgs(template) {
|
|
19
|
+
if (typeof template !== 'string')
|
|
20
|
+
return false;
|
|
21
|
+
return template.includes('$ARGUMENTS') || template.includes('${ARGUMENTS}');
|
|
22
|
+
}
|
|
23
|
+
export function registerCommand(command) {
|
|
24
|
+
const source = command.source || 'command';
|
|
25
|
+
const prefix = getCommandPrefix(source);
|
|
26
|
+
const sanitized = sanitizeCommandName(command.name);
|
|
27
|
+
const telegramCmd = `${prefix}${sanitized}`;
|
|
28
|
+
const registered = {
|
|
29
|
+
telegramCmd,
|
|
30
|
+
sdkName: command.name,
|
|
31
|
+
source,
|
|
32
|
+
description: command.description,
|
|
33
|
+
template: command.template,
|
|
34
|
+
needsArgs: checkNeedsArgs(command.template),
|
|
35
|
+
};
|
|
36
|
+
commandRegistry.set(telegramCmd, registered);
|
|
37
|
+
return registered;
|
|
38
|
+
}
|
|
39
|
+
export function getRegisteredCommand(telegramCmd) {
|
|
40
|
+
return commandRegistry.get(telegramCmd);
|
|
41
|
+
}
|
|
42
|
+
export function clearCommandRegistry() {
|
|
43
|
+
commandRegistry.clear();
|
|
44
|
+
}
|
|
45
|
+
export async function buildUnboundMenu() {
|
|
46
|
+
return [
|
|
47
|
+
{ command: 'start', description: '开始使用' },
|
|
48
|
+
{ command: 'new', description: '创建新项目' },
|
|
49
|
+
{ command: 'bind', description: '绑定已有项目' },
|
|
50
|
+
{ command: 'help', description: '帮助' },
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
export async function buildBoundMenu(projectPath) {
|
|
54
|
+
const baseCommands = [
|
|
55
|
+
{ command: 'status', description: '查看绑定状态' },
|
|
56
|
+
{ command: 'agents', description: '切换 Agent' },
|
|
57
|
+
{ command: 'models', description: '切换 Model' },
|
|
58
|
+
{ command: 'compact', description: '压缩会话上下文' },
|
|
59
|
+
{ command: 'help', description: '帮助' },
|
|
60
|
+
];
|
|
61
|
+
try {
|
|
62
|
+
const commands = await getCommands(projectPath);
|
|
63
|
+
console.log(`[DynamicMenu] 获取到 ${commands.length} 个 SDK 指令`);
|
|
64
|
+
const sdkCommands = [];
|
|
65
|
+
for (const cmd of commands) {
|
|
66
|
+
const registered = registerCommand(cmd);
|
|
67
|
+
const desc = cmd.description || cmd.name;
|
|
68
|
+
sdkCommands.push({
|
|
69
|
+
command: registered.telegramCmd,
|
|
70
|
+
description: desc.substring(0, 256),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
console.log(`[DynamicMenu] 注册了 ${sdkCommands.length} 个 SDK 指令`);
|
|
74
|
+
return [...baseCommands, ...sdkCommands];
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
78
|
+
console.error(`[DynamicMenu] 构建菜单失败: ${errorMessage}`);
|
|
79
|
+
return baseCommands;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=dynamic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic.js","sourceRoot":"","sources":["../../../src/bot/commands/dynamic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Bot } from 'grammy';
|
|
2
|
+
import { CommandGroup } from '@grammyjs/commands';
|
|
3
|
+
import type { BotContext } from '../../shared/types.js';
|
|
4
|
+
export interface CommandGroups {
|
|
5
|
+
base: CommandGroup<BotContext>;
|
|
6
|
+
agents: CommandGroup<BotContext>;
|
|
7
|
+
models: CommandGroup<BotContext>;
|
|
8
|
+
}
|
|
9
|
+
export declare function setupCommands(bot: Bot<BotContext>, projectPath?: string): Promise<CommandGroups>;
|
|
10
|
+
export declare function refreshAgentCommands(bot: Bot<BotContext>, commandGroups: CommandGroups, projectPath: string): Promise<void>;
|
|
11
|
+
export declare function refreshModelCommands(bot: Bot<BotContext>, commandGroups: CommandGroups, projectPath: string): Promise<void>;
|
|
12
|
+
export { createBaseCommands } from './base.js';
|
|
13
|
+
export { createAgentCommands } from './agents.js';
|
|
14
|
+
export { createModelCommands } from './models.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAY,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAKxD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACjC,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;CAClC;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CActG;AAED,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,EACpB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,EACpB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { commands } from '@grammyjs/commands';
|
|
2
|
+
import { createBaseCommands } from './base.js';
|
|
3
|
+
import { createAgentCommands, buildAgentCommandGroup } from './agents.js';
|
|
4
|
+
import { createModelCommands, buildModelCommandGroup } from './models.js';
|
|
5
|
+
export async function setupCommands(bot, projectPath) {
|
|
6
|
+
bot.use(commands());
|
|
7
|
+
const base = createBaseCommands();
|
|
8
|
+
const agents = createAgentCommands();
|
|
9
|
+
const models = createModelCommands();
|
|
10
|
+
bot.use(base);
|
|
11
|
+
bot.use(agents);
|
|
12
|
+
bot.use(models);
|
|
13
|
+
await base.setCommands(bot);
|
|
14
|
+
return { base, agents, models };
|
|
15
|
+
}
|
|
16
|
+
export async function refreshAgentCommands(bot, commandGroups, projectPath) {
|
|
17
|
+
await buildAgentCommandGroup(commandGroups.agents, projectPath, commandGroups.base);
|
|
18
|
+
}
|
|
19
|
+
export async function refreshModelCommands(bot, commandGroups, projectPath) {
|
|
20
|
+
await buildModelCommandGroup(commandGroups.models, projectPath, commandGroups.base);
|
|
21
|
+
}
|
|
22
|
+
export { createBaseCommands } from './base.js';
|
|
23
|
+
export { createAgentCommands } from './agents.js';
|
|
24
|
+
export { createModelCommands } from './models.js';
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bot/commands/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAgB,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAQ1E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAoB,EAAE,WAAoB;IAC5E,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IAErC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACd,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChB,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEhB,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAE5B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAoB,EACpB,aAA4B,EAC5B,WAAmB;IAEnB,MAAM,sBAAsB,CAAC,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAoB,EACpB,aAA4B,EAC5B,WAAmB;IAEnB,MAAM,sBAAsB,CAAC,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CommandGroup } from '@grammyjs/commands';
|
|
2
|
+
import type { BotContext } from '../../shared/types.js';
|
|
3
|
+
import { type ProviderInfo } from '../../server/sdk.js';
|
|
4
|
+
export declare function createModelCommands(): CommandGroup<BotContext>;
|
|
5
|
+
export declare function buildModelCommandGroup(group: CommandGroup<BotContext>, projectPath: string, baseCommands: CommandGroup<BotContext>): Promise<void>;
|
|
6
|
+
export declare function getModelCommandsList(providers: ProviderInfo[]): string;
|
|
7
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMpF,wBAAgB,mBAAmB,IAAI,YAAY,CAAC,UAAU,CAAC,CAE9D;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,YAAY,CAAC,UAAU,CAAC,EAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CActE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CommandGroup } from '@grammyjs/commands';
|
|
2
|
+
import { getProjectByChat, setGroupSettings } from '../../shared/mapping.js';
|
|
3
|
+
import { getProviders, updateConfig } from '../../server/sdk.js';
|
|
4
|
+
function sanitizeCommandName(name) {
|
|
5
|
+
return name.toLowerCase().replace(/[^a-z0-9_]/g, '_').substring(0, 28);
|
|
6
|
+
}
|
|
7
|
+
export function createModelCommands() {
|
|
8
|
+
return new CommandGroup();
|
|
9
|
+
}
|
|
10
|
+
export async function buildModelCommandGroup(group, projectPath, baseCommands) {
|
|
11
|
+
const providers = await getProviders(projectPath);
|
|
12
|
+
if (providers.length === 0) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (const provider of providers) {
|
|
16
|
+
for (const model of provider.models) {
|
|
17
|
+
const fullModelId = `${provider.id}/${model.id}`;
|
|
18
|
+
const cmdName = `model_${sanitizeCommandName(model.id)}`;
|
|
19
|
+
const description = `${provider.name}: ${model.name}`;
|
|
20
|
+
group.command(cmdName, description, async (ctx) => {
|
|
21
|
+
const chatId = ctx.chat?.id;
|
|
22
|
+
if (!chatId)
|
|
23
|
+
return;
|
|
24
|
+
const currentProject = getProjectByChat(chatId);
|
|
25
|
+
if (!currentProject) {
|
|
26
|
+
await ctx.reply('❌ 当前群组未绑定项目');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const success = await updateConfig(currentProject, { model: fullModelId });
|
|
30
|
+
if (success) {
|
|
31
|
+
setGroupSettings(chatId, { model: fullModelId });
|
|
32
|
+
await ctx.setMyCommands?.(baseCommands);
|
|
33
|
+
await ctx.reply(`✅ 已切换到 Model: *${model.name}*\n` +
|
|
34
|
+
`Provider: ${provider.name}`, { parse_mode: 'Markdown' });
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
await ctx.reply(`❌ 切换 Model 失败`);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
group.command('back', '返回主菜单', async (ctx) => {
|
|
43
|
+
await ctx.setMyCommands?.(baseCommands);
|
|
44
|
+
await ctx.reply('✅ 已返回主菜单');
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function getModelCommandsList(providers) {
|
|
48
|
+
if (providers.length === 0) {
|
|
49
|
+
return '暂无可用 Model';
|
|
50
|
+
}
|
|
51
|
+
const lines = [];
|
|
52
|
+
for (const provider of providers) {
|
|
53
|
+
for (const model of provider.models) {
|
|
54
|
+
const cmdName = `model_${sanitizeCommandName(model.id)}`;
|
|
55
|
+
lines.push(`/${cmdName} - ${provider.name}: ${model.name}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return lines.join('\n');
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/bot/commands/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Bot } from 'grammy';
|
|
2
|
+
import type { BotContext } from '../../shared/types.js';
|
|
3
|
+
export declare function setupSDKCommandHandlers(bot: Bot<BotContext>): void;
|
|
4
|
+
export declare function startPendingCommandCleanup(): void;
|
|
5
|
+
//# sourceMappingURL=sdk-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-commands.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/sdk-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,uBAAuB,CAAC;AAWxE,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,CAoGlE;AAoDD,wBAAgB,0BAA0B,IAAI,IAAI,CAcjD"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { getRegisteredCommand } from './dynamic.js';
|
|
2
|
+
import { getProjectByChat, getSessionByTopic, getGroupSettings } from '../../shared/mapping.js';
|
|
3
|
+
import { executeCommand } from '../../server/sdk.js';
|
|
4
|
+
const pendingCommands = new Map();
|
|
5
|
+
function getPendingKey(chatId, topicId, userId) {
|
|
6
|
+
return `${chatId}:${topicId}:${userId}`;
|
|
7
|
+
}
|
|
8
|
+
export function setupSDKCommandHandlers(bot) {
|
|
9
|
+
bot.hears(/^\/(cmd|sk|mcp)_(.+?)(@\w+)?(\s|$)/, async (ctx) => {
|
|
10
|
+
const text = ctx.message?.text || '';
|
|
11
|
+
const parts = text.split(/\s+/);
|
|
12
|
+
const commandWithBot = parts[0].slice(1);
|
|
13
|
+
const command = commandWithBot.split('@')[0];
|
|
14
|
+
const args = parts.slice(1).join(' ');
|
|
15
|
+
console.log(`[SDKCommand] 收到命令: ${command}, 参数: "${args}"`);
|
|
16
|
+
const registered = getRegisteredCommand(command);
|
|
17
|
+
if (!registered) {
|
|
18
|
+
console.log(`[SDKCommand] 命令未注册: ${command}`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log(`[SDKCommand] 命令已注册: ${registered.sdkName} (source: ${registered.source})`);
|
|
22
|
+
if (args) {
|
|
23
|
+
console.log(`[SDKCommand] 直接执行,参数: "${args}"`);
|
|
24
|
+
await handleExecuteCommand(ctx, registered.sdkName, args, registered.source);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
console.log(`[SDKCommand] 无参数,显示提示`);
|
|
28
|
+
const chatId = ctx.chat?.id;
|
|
29
|
+
const topicId = ctx.message?.message_thread_id || 0;
|
|
30
|
+
const userId = ctx.from?.id;
|
|
31
|
+
if (!chatId || !userId)
|
|
32
|
+
return;
|
|
33
|
+
const key = getPendingKey(chatId, topicId, userId);
|
|
34
|
+
pendingCommands.set(key, {
|
|
35
|
+
chatId,
|
|
36
|
+
topicId,
|
|
37
|
+
userId,
|
|
38
|
+
commandName: registered.sdkName,
|
|
39
|
+
source: registered.source,
|
|
40
|
+
timestamp: Date.now(),
|
|
41
|
+
});
|
|
42
|
+
await ctx.reply(`📝 执行指令: *${registered.sdkName}*\n\n` +
|
|
43
|
+
`${registered.description ? registered.description + '\n\n' : ''}` +
|
|
44
|
+
`是否需要附加说明?\n` +
|
|
45
|
+
`💬 直接回复文本,或点击按钮:`, {
|
|
46
|
+
parse_mode: 'Markdown',
|
|
47
|
+
reply_markup: {
|
|
48
|
+
inline_keyboard: [[
|
|
49
|
+
{ text: '🚀 直接执行', callback_data: `exec_cmd:${command}:` }
|
|
50
|
+
]]
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
bot.on('callback_query:data', async (ctx) => {
|
|
55
|
+
const data = ctx.callbackQuery.data;
|
|
56
|
+
if (!data?.startsWith('exec_cmd:'))
|
|
57
|
+
return;
|
|
58
|
+
const [_, telegramCmd, args] = data.split(':');
|
|
59
|
+
const registered = getRegisteredCommand(telegramCmd);
|
|
60
|
+
if (!registered)
|
|
61
|
+
return;
|
|
62
|
+
await ctx.answerCallbackQuery();
|
|
63
|
+
await handleExecuteCommand(ctx, registered.sdkName, args || '', registered.source);
|
|
64
|
+
const chatId = ctx.chat?.id;
|
|
65
|
+
const topicId = ctx.callbackQuery.message?.message_thread_id || 0;
|
|
66
|
+
const userId = ctx.from?.id;
|
|
67
|
+
if (chatId && userId) {
|
|
68
|
+
const key = getPendingKey(chatId, topicId, userId);
|
|
69
|
+
pendingCommands.delete(key);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
bot.on('message:text', async (ctx, next) => {
|
|
73
|
+
const chatId = ctx.chat?.id;
|
|
74
|
+
const topicId = ctx.message?.message_thread_id || 0;
|
|
75
|
+
const userId = ctx.from?.id;
|
|
76
|
+
if (!chatId || !userId) {
|
|
77
|
+
return next();
|
|
78
|
+
}
|
|
79
|
+
const key = getPendingKey(chatId, topicId, userId);
|
|
80
|
+
const pending = pendingCommands.get(key);
|
|
81
|
+
if (!pending) {
|
|
82
|
+
return next();
|
|
83
|
+
}
|
|
84
|
+
const args = ctx.message.text;
|
|
85
|
+
await handleExecuteCommand(ctx, pending.commandName, args, pending.source);
|
|
86
|
+
pendingCommands.delete(key);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function handleExecuteCommand(ctx, commandName, args, source) {
|
|
90
|
+
const chatId = ctx.chat?.id;
|
|
91
|
+
if (!chatId)
|
|
92
|
+
return;
|
|
93
|
+
const projectPath = getProjectByChat(chatId);
|
|
94
|
+
if (!projectPath) {
|
|
95
|
+
await ctx.reply('❌ 当前群组未绑定项目');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const topicId = ctx.message?.message_thread_id || ctx.callbackQuery?.message?.message_thread_id || 0;
|
|
99
|
+
const sessionId = getSessionByTopic(chatId, topicId);
|
|
100
|
+
if (!sessionId) {
|
|
101
|
+
await ctx.reply('❌ 未找到会话');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const settings = getGroupSettings(chatId);
|
|
105
|
+
try {
|
|
106
|
+
await ctx.reply(`⏳ 正在执行指令: ${commandName}...`);
|
|
107
|
+
const result = await executeCommand(sessionId, commandName, args, projectPath, settings?.agent, settings?.model);
|
|
108
|
+
const replyText = `✅ 指令执行完成\n\n🤖 Agent: ${result.agent}${result.modelId ? `\n🧠 Model: ${result.modelId}` : ''}\n\n${result.text}`;
|
|
109
|
+
const maxLength = 3500;
|
|
110
|
+
if (replyText.length > maxLength) {
|
|
111
|
+
await ctx.reply(replyText.substring(0, maxLength) + '\n\n[已截断]');
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
await ctx.reply(replyText);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
119
|
+
await ctx.reply(`❌ 执行失败: ${errorMessage}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export function startPendingCommandCleanup() {
|
|
123
|
+
setInterval(() => {
|
|
124
|
+
const now = Date.now();
|
|
125
|
+
const timeout = 5 * 60 * 1000;
|
|
126
|
+
const keysToDelete = [];
|
|
127
|
+
pendingCommands.forEach((pending, key) => {
|
|
128
|
+
if (now - pending.timestamp > timeout) {
|
|
129
|
+
keysToDelete.push(key);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
keysToDelete.forEach(key => pendingCommands.delete(key));
|
|
133
|
+
}, 60 * 1000);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=sdk-commands.js.map
|