@yeaft/webchat-agent 0.1.441 → 0.1.442

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 (2) hide show
  1. package/claude.js +41 -1
  2. package/package.json +1 -1
package/claude.js CHANGED
@@ -5,6 +5,24 @@ import ctx from './context.js';
5
5
  import { sendConversationList, sendOutput, sendError, handleAskUserQuestion } from './conversation.js';
6
6
  import { startSubagentWatcher, stopSubagentWatcher, cleanupSubagentWatchers } from './subagent.js';
7
7
 
8
+ /**
9
+ * Detect whether a user message is a Claude Code compact summary.
10
+ * These appear after context compaction and should not be displayed in the UI.
11
+ *
12
+ * @param {string} text — user message content
13
+ * @returns {boolean}
14
+ */
15
+ function isCompactSummary(text) {
16
+ if (!text || text.length < 200) return false;
17
+ // Claude Code compact summary always starts with this exact text
18
+ if (text.includes('This session is being continued from a previous conversation')) return true;
19
+ // Alternate compact summary indicator (Claude Code uses <system-reminder> blocks)
20
+ if (text.includes('The summary below covers the earlier portion of the conversation')) return true;
21
+ // Context compaction with numbered sections (1. Primary Request, 2. Key Technical Concepts, etc.)
22
+ if (/^[\s\S]*Summary:[\s\S]*\d+\.\s+(Primary Request|Key Technical|Current Work)/m.test(text)) return true;
23
+ return false;
24
+ }
25
+
8
26
  /**
9
27
  * Determine maxContextTokens and autoCompactThreshold from model name.
10
28
  * Returns defaults suitable for the model's context window size.
@@ -423,7 +441,7 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
423
441
 
424
442
  // 过滤 compact summary 消息(compact_boundary 之后的 user 消息)
425
443
  if (message.type === 'user' && state._compactSummaryPending) {
426
- console.log(`[${conversationId}] Filtering compact summary message`);
444
+ console.log(`[${conversationId}] Filtering compact summary message (pending flag)`);
427
445
  continue;
428
446
  }
429
447
  // compact 后的 <local-command-stdout>Compacted </local-command-stdout> 标记 summary 结束
@@ -431,6 +449,28 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
431
449
  state._compactSummaryPending = false;
432
450
  }
433
451
 
452
+ // 兜底过滤: Claude Code 的 compact summary 有时不触发 compact_boundary,
453
+ // 直接以 user 消息形式出现。通过内容特征检测过滤。
454
+ if (message.type === 'user') {
455
+ const userText = typeof message.content === 'string'
456
+ ? message.content
457
+ : (Array.isArray(message.content) ? message.content.map(b => b.text || '').join('') : '');
458
+ if (userText && isCompactSummary(userText)) {
459
+ console.log(`[${conversationId}] Filtering compact summary message (content match)`);
460
+ // 补发 compact 完成通知(如果之前没发过)
461
+ if (!state._compactCompleteSent) {
462
+ state._compactCompleteSent = true;
463
+ ctx.sendToServer({
464
+ type: 'compact_status',
465
+ conversationId,
466
+ status: 'completed',
467
+ message: 'Context compacted successfully'
468
+ });
469
+ }
470
+ continue;
471
+ }
472
+ }
473
+
434
474
  // 捕获 result 消息中的 usage 信息
435
475
  if (message.type === 'result') {
436
476
  // Log result message keys for debugging slash command output
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.441",
3
+ "version": "0.1.442",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",