@wu529778790/open-im 0.3.0 → 0.3.1

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.
@@ -29,11 +29,11 @@ class DynamicThrottle {
29
29
  this.lastUpdate = now;
30
30
  return errorDelay;
31
31
  }
32
- // 内容增长较小时,增加延迟
32
+ // 内容增长较小时,适当增加延迟
33
33
  const contentGrowth = contentLength - this.lastContentLength;
34
- if (contentGrowth < 100 && timeSinceLastUpdate < 1000) {
34
+ if (contentGrowth < 50 && timeSinceLastUpdate < 500) {
35
35
  this.lastUpdate = now;
36
- return 1000; // 内容增长缓慢,每秒更新一次
36
+ return 500; // 内容增长缓慢时,每 500ms 更新一次
37
37
  }
38
38
  // 内容增长较快,使用基础间隔
39
39
  this.lastUpdate = now;
@@ -99,6 +99,9 @@ export function setupTelegramHandlers(bot, config, sessionManager) {
99
99
  const taskKey = `${userId}:${msgId}`;
100
100
  // 创建动态节流器
101
101
  const throttle = new DynamicThrottle();
102
+ // 保存思考内容和状态
103
+ let savedThinkingText = '';
104
+ let hasThinkingContent = false; // 是否包含思考内容
102
105
  // 创建包装的流式更新函数(带串行化、智能跳过和防抖)
103
106
  const createStreamUpdateWrapper = () => {
104
107
  let lastUpdateTime = 0;
@@ -108,8 +111,8 @@ export function setupTelegramHandlers(bot, config, sessionManager) {
108
111
  let updateInProgress = false; // 串行化锁
109
112
  let scheduledContent = null; // 待更新内容
110
113
  let scheduledToolNote;
111
- // 流式输出时只显示最后 N 个字符,避免消息过大
112
- const STREAM_PREVIEW_LENGTH = 500;
114
+ // 流式输出时显示最后 N 个字符(增加到 1500 以提高流畅度)
115
+ const STREAM_PREVIEW_LENGTH = 1500;
113
116
  // 执行更新(串行化)
114
117
  const performUpdate = async (content, toolNote) => {
115
118
  if (updateInProgress) {
@@ -120,10 +123,40 @@ export function setupTelegramHandlers(bot, config, sessionManager) {
120
123
  }
121
124
  updateInProgress = true;
122
125
  try {
123
- // 流式输出时只显示最后部分内容,避免触发速率限制
124
- const displayContent = content.length > STREAM_PREVIEW_LENGTH
125
- ? `...(已输出 ${content.length} 字符,显示最后 ${STREAM_PREVIEW_LENGTH} 字符)...\n\n${content.slice(-STREAM_PREVIEW_LENGTH)}`
126
- : content;
126
+ let displayContent = content;
127
+ // 如果有思考内容,将其格式化后添加到前面
128
+ if (hasThinkingContent && savedThinkingText) {
129
+ // 思考内容使用引用格式,用分隔线区分
130
+ const thinkingFormatted = `💭 思考过程:\n${savedThinkingText}`;
131
+ const separator = '\n\n─────────\n\n';
132
+ // 组合内容
133
+ const combined = thinkingFormatted + separator + content;
134
+ // 如果组合后超过预览长度,截取最后部分(但保留思考内容)
135
+ if (combined.length > STREAM_PREVIEW_LENGTH) {
136
+ // 如果思考内容本身就很长,截取思考内容
137
+ const maxThinkingLength = 800;
138
+ const truncatedThinking = savedThinkingText.length > maxThinkingLength
139
+ ? `...(已省略 ${savedThinkingText.length - maxThinkingLength} 字符)...\n\n${savedThinkingText.slice(-maxThinkingLength)}`
140
+ : savedThinkingText;
141
+ displayContent = `💭 思考过程:\n${truncatedThinking}\n\n─────────\n\n`;
142
+ // 添加输出内容的最后部分
143
+ if (content.length > 800) {
144
+ displayContent += `...\n\n${content.slice(-800)}`;
145
+ }
146
+ else {
147
+ displayContent += content;
148
+ }
149
+ }
150
+ else {
151
+ displayContent = combined;
152
+ }
153
+ }
154
+ else {
155
+ // 没有思考内容,直接显示(如果超过预览长度则截取)
156
+ displayContent = content.length > STREAM_PREVIEW_LENGTH
157
+ ? `...\n\n${content.slice(-STREAM_PREVIEW_LENGTH)}`
158
+ : content;
159
+ }
127
160
  const note = toolNote ? '输出中...\n' + toolNote : '输出中...';
128
161
  await updateMessage(chatId, msgId, displayContent, 'streaming', note, toolId);
129
162
  throttle.recordSuccess();
@@ -144,15 +177,21 @@ export function setupTelegramHandlers(bot, config, sessionManager) {
144
177
  }
145
178
  }
146
179
  };
147
- // 防抖延迟(毫秒)
148
- const DEBOUNCE_MS = 200;
180
+ // 防抖延迟(毫秒)- 降低到 150ms 提高响应速度
181
+ const DEBOUNCE_MS = 150;
149
182
  let debounceTimer = null;
150
183
  return (content, toolNote) => {
184
+ // 检测是否是思考内容
185
+ if (content.startsWith('💭 **思考中...**')) {
186
+ // 保存思考内容(去掉前缀)
187
+ savedThinkingText = content.replace('💭 **思考中...**\n\n', '');
188
+ hasThinkingContent = true;
189
+ }
151
190
  const now = Date.now();
152
191
  const elapsed = now - lastUpdateTime;
153
- // 智能跳过:内容增长小于 50 字符且距离上次更新不足 1 秒
192
+ // 智能跳过:内容增长小于 30 字符且距离上次更新不足 500ms(降低阈值,提高流畅度)
154
193
  const contentGrowth = content.length - lastContentLength;
155
- if (contentGrowth < 50 && elapsed < 1000 && lastContentLength > 0) {
194
+ if (contentGrowth < 30 && elapsed < 500 && lastContentLength > 0) {
156
195
  // 跳过此次更新,但更新长度记录
157
196
  lastContentLength = content.length;
158
197
  lastContent = content;
@@ -178,9 +217,21 @@ export function setupTelegramHandlers(bot, config, sessionManager) {
178
217
  await runAITask({ config, sessionManager }, { userId, chatId, workDir, sessionId, convId, platform: 'telegram', taskKey }, prompt, toolAdapter, {
179
218
  throttleMs: THROTTLE_MS,
180
219
  streamUpdate: streamUpdateWrapper,
220
+ onThinkingToText: (content) => {
221
+ // 从思考转到文本输出时,标记有思考内容
222
+ // 注意:此时不保存文本内容,因为后续会通过 streamUpdate 持续更新
223
+ },
181
224
  sendComplete: async (content, note) => {
182
225
  throttle.reset();
183
- await sendFinalMessages(chatId, msgId, content, note, toolId);
226
+ // 完成时,如果有思考内容,将其包含在最终消息中
227
+ if (savedThinkingText && hasThinkingContent) {
228
+ const thinkingFormatted = `💭 思考过程:\n${savedThinkingText}\n\n─────────\n\n`;
229
+ const combined = thinkingFormatted + content;
230
+ await sendFinalMessages(chatId, msgId, combined, note, toolId);
231
+ }
232
+ else {
233
+ await sendFinalMessages(chatId, msgId, content, note, toolId);
234
+ }
184
235
  },
185
236
  sendError: async (error) => {
186
237
  throttle.reset();
@@ -188,6 +239,9 @@ export function setupTelegramHandlers(bot, config, sessionManager) {
188
239
  },
189
240
  extraCleanup: () => {
190
241
  throttle.reset();
242
+ // 清理思考内容
243
+ savedThinkingText = '';
244
+ hasThinkingContent = false;
191
245
  stopTyping();
192
246
  runningTasks.delete(taskKey);
193
247
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wu529778790/open-im",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Multi-platform IM bridge for AI CLI tools (Claude, Codex, Cursor)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",