@luckydraw/cumulus 0.30.30 → 0.30.31

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/CHANGELOG.md CHANGED
@@ -1,10 +1,7 @@
1
1
  # Changelog
2
2
 
3
- ## v0.30.29
4
- - Attach files of any type to messages, with upload progress shown
5
- - Stricter MCP config validation catches setup errors earlier
6
- - Cleaner responses with literal `<thinking>` tags suppressed
7
- - Updated documentation reflecting current features
3
+ ## v0.30.30
4
+ - Bug fixes and stability improvements
8
5
 
9
6
 
10
7
  ## v0.30.29
File without changes
@@ -494,6 +494,78 @@
494
494
  ' 30% { transform: translateY(-0.4em); opacity: 1; }',
495
495
  '}',
496
496
 
497
+ /* ── Activity chip (task 070) ── */
498
+ '.cumulus-activity-chip {',
499
+ ' display: block;',
500
+ ' margin: 0 0 0.5em 0;',
501
+ ' font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;',
502
+ ' font-size: 0.82em;',
503
+ ' background: #2a2a2a;',
504
+ ' border: 1px solid #3a3a3a;',
505
+ ' border-radius: 6px;',
506
+ ' color: #b8b8b8;',
507
+ ' user-select: none;',
508
+ ' overflow: hidden;',
509
+ '}',
510
+ '.cumulus-activity-chip-header {',
511
+ ' display: flex;',
512
+ ' align-items: center;',
513
+ ' gap: 0.5em;',
514
+ ' padding: 0.35em 0.6em;',
515
+ ' cursor: pointer;',
516
+ '}',
517
+ '.cumulus-activity-chip-header:hover { background: #303030; }',
518
+ '.cumulus-activity-chip-icon {',
519
+ ' flex: 0 0 auto;',
520
+ ' width: 1.2em;',
521
+ ' text-align: center;',
522
+ '}',
523
+ '.cumulus-activity-chip-text {',
524
+ ' flex: 1 1 auto;',
525
+ ' overflow: hidden;',
526
+ ' text-overflow: ellipsis;',
527
+ ' white-space: nowrap;',
528
+ '}',
529
+ '.cumulus-activity-chip-chevron {',
530
+ ' flex: 0 0 auto;',
531
+ ' font-size: 0.7em;',
532
+ ' color: #888;',
533
+ ' transition: transform 0.15s ease;',
534
+ '}',
535
+ '.cumulus-activity-chip.expanded .cumulus-activity-chip-chevron {',
536
+ ' transform: rotate(90deg);',
537
+ '}',
538
+ '.cumulus-activity-chip-body {',
539
+ ' border-top: 1px solid #3a3a3a;',
540
+ ' background: #232323;',
541
+ ' padding: 0.4em 0.6em;',
542
+ ' display: flex;',
543
+ ' flex-direction: column;',
544
+ ' gap: 0.3em;',
545
+ '}',
546
+ '.cumulus-activity-row {',
547
+ ' display: flex;',
548
+ ' gap: 0.5em;',
549
+ ' align-items: flex-start;',
550
+ ' line-height: 1.4;',
551
+ '}',
552
+ '.cumulus-activity-row-icon {',
553
+ ' flex: 0 0 auto;',
554
+ ' width: 1.2em;',
555
+ ' text-align: center;',
556
+ '}',
557
+ '.cumulus-activity-row-text {',
558
+ ' flex: 1 1 auto;',
559
+ ' word-break: break-word;',
560
+ ' white-space: pre-wrap;',
561
+ ' color: #c8c8c8;',
562
+ '}',
563
+ '.cumulus-activity-row.thinking .cumulus-activity-row-text { color: #9a9aff; font-style: italic; }',
564
+ '.cumulus-activity-row.tool_use .cumulus-activity-row-text { color: #d4b86a; }',
565
+ '.cumulus-activity-row.tool_result .cumulus-activity-row-text { color: #8fbf8f; }',
566
+ '.cumulus-activity-row.tool_result.error .cumulus-activity-row-text { color: #d97a7a; }',
567
+ '.cumulus-activity-row.system .cumulus-activity-row-text { color: #888; }',
568
+
497
569
  /* ── Loading indicator ── */
498
570
  '.cumulus-loading {',
499
571
  ' color: #666; font-style: italic; padding: 0.4em 0;',
@@ -3841,6 +3913,10 @@
3841
3913
  hasOlderMessages: false,
3842
3914
  oldestOffset: -1, // -1 = unknown, set on first history response
3843
3915
  model: 'claude', // default model
3916
+ // Activity chip (task 070) — accumulates segments during in-flight turn,
3917
+ // moves onto the assistant message at `done` time
3918
+ currentSegments: [],
3919
+ expandedChips: {}, // msgKey → true if chip expanded
3844
3920
  };
3845
3921
  }
3846
3922
  return threadStates[threadName];
@@ -5542,7 +5618,140 @@
5542
5618
  return el;
5543
5619
  }
5544
5620
 
5545
- function buildAssistantMsgEl(content, isStreaming, msgKey) {
5621
+ // ── Activity chip helpers (task 070) ──
5622
+ function truncateForChip(s, n) {
5623
+ s = String(s == null ? '' : s);
5624
+ return s.length > n ? s.slice(0, n - 1) + '…' : s;
5625
+ }
5626
+ function iconForSegment(s) {
5627
+ if (!s) return '';
5628
+ switch (s.type) {
5629
+ case 'thinking':
5630
+ return '💭';
5631
+ case 'tool_use':
5632
+ return '⚙';
5633
+ case 'tool_result':
5634
+ return s.isError ? '✗' : '✓';
5635
+ case 'system':
5636
+ return '⚙';
5637
+ default:
5638
+ return '';
5639
+ }
5640
+ }
5641
+ function labelForSegment(s, expanded) {
5642
+ if (!s) return '';
5643
+ var maxLen = expanded ? 400 : 80;
5644
+ switch (s.type) {
5645
+ case 'thinking': {
5646
+ var t = String(s.content || '')
5647
+ .replace(/\s+/g, ' ')
5648
+ .trim();
5649
+ return 'Thinking — ' + truncateForChip(t, maxLen);
5650
+ }
5651
+ case 'tool_use': {
5652
+ var tool = s.tool || 'tool';
5653
+ var argStr = '';
5654
+ try {
5655
+ var keys = Object.keys(s.input || {});
5656
+ if (keys.length > 0) {
5657
+ var v = s.input[keys[0]];
5658
+ argStr = typeof v === 'string' ? JSON.stringify(v) : JSON.stringify(v);
5659
+ }
5660
+ } catch (e) {
5661
+ argStr = '';
5662
+ }
5663
+ var headroom = Math.max(8, maxLen - tool.length - 2);
5664
+ return tool + '(' + (argStr ? truncateForChip(argStr, headroom) : '') + ')';
5665
+ }
5666
+ case 'tool_result': {
5667
+ var c = String(s.content || '').split('\n')[0] || '';
5668
+ return truncateForChip(c, maxLen);
5669
+ }
5670
+ case 'system': {
5671
+ var c2 = String(s.content || '')
5672
+ .replace(/\s+/g, ' ')
5673
+ .trim();
5674
+ return 'system: ' + truncateForChip(c2, maxLen);
5675
+ }
5676
+ default:
5677
+ return '';
5678
+ }
5679
+ }
5680
+ function buildActivityChip(segments, msgKey, st) {
5681
+ if (!segments || segments.length === 0) return null;
5682
+ var meaningful = [];
5683
+ for (var i = 0; i < segments.length; i++) {
5684
+ var seg = segments[i];
5685
+ if (seg && seg.type !== 'text' && seg.type !== 'result') meaningful.push(seg);
5686
+ }
5687
+ if (meaningful.length === 0) return null;
5688
+
5689
+ var key = msgKey || '__streaming__';
5690
+ var expanded = !!(st && st.expandedChips && st.expandedChips[key]);
5691
+
5692
+ var chip = document.createElement('div');
5693
+ chip.className = 'cumulus-activity-chip' + (expanded ? ' expanded' : '');
5694
+ chip.setAttribute('data-testid', 'webchat-activity-chip');
5695
+
5696
+ var header = document.createElement('div');
5697
+ header.className = 'cumulus-activity-chip-header';
5698
+
5699
+ var latest = meaningful[meaningful.length - 1];
5700
+ var headerIcon = document.createElement('span');
5701
+ headerIcon.className = 'cumulus-activity-chip-icon';
5702
+ headerIcon.textContent = iconForSegment(latest);
5703
+
5704
+ var headerText = document.createElement('span');
5705
+ headerText.className = 'cumulus-activity-chip-text';
5706
+ if (expanded) {
5707
+ headerText.textContent =
5708
+ 'Activity (' + meaningful.length + ' step' + (meaningful.length === 1 ? '' : 's') + ')';
5709
+ } else {
5710
+ headerText.textContent = labelForSegment(latest, false);
5711
+ }
5712
+
5713
+ var chevron = document.createElement('span');
5714
+ chevron.className = 'cumulus-activity-chip-chevron';
5715
+ chevron.textContent = '▸';
5716
+
5717
+ header.appendChild(headerIcon);
5718
+ header.appendChild(headerText);
5719
+ header.appendChild(chevron);
5720
+ chip.appendChild(header);
5721
+
5722
+ if (expanded) {
5723
+ var body = document.createElement('div');
5724
+ body.className = 'cumulus-activity-chip-body';
5725
+ for (var j = 0; j < meaningful.length; j++) {
5726
+ var s2 = meaningful[j];
5727
+ var row = document.createElement('div');
5728
+ var rowClass = 'cumulus-activity-row ' + s2.type;
5729
+ if (s2.type === 'tool_result' && s2.isError) rowClass += ' error';
5730
+ row.className = rowClass;
5731
+ var rowIcon = document.createElement('span');
5732
+ rowIcon.className = 'cumulus-activity-row-icon';
5733
+ rowIcon.textContent = iconForSegment(s2);
5734
+ var rowText = document.createElement('span');
5735
+ rowText.className = 'cumulus-activity-row-text';
5736
+ rowText.textContent = labelForSegment(s2, true);
5737
+ row.appendChild(rowIcon);
5738
+ row.appendChild(rowText);
5739
+ body.appendChild(row);
5740
+ }
5741
+ chip.appendChild(body);
5742
+ }
5743
+
5744
+ if (st) {
5745
+ header.addEventListener('click', function () {
5746
+ st.expandedChips[key] = !st.expandedChips[key];
5747
+ refreshThreadPanel(threadName);
5748
+ });
5749
+ }
5750
+
5751
+ return chip;
5752
+ }
5753
+
5754
+ function buildAssistantMsgEl(content, isStreaming, msgKey, segments) {
5546
5755
  content = stripThinkingBlocks(content);
5547
5756
  var el = document.createElement('div');
5548
5757
  el.className = 'cumulus-msg assistant';
@@ -5563,6 +5772,11 @@
5563
5772
  el.innerHTML =
5564
5773
  '<span class="cumulus-typing-dots"><span></span><span></span><span></span></span>';
5565
5774
  }
5775
+ // Prepend activity chip if we have segments
5776
+ var chipEl = buildActivityChip(segments, msgKey, state);
5777
+ if (chipEl) {
5778
+ el.insertBefore(chipEl, el.firstChild);
5779
+ }
5566
5780
  return el;
5567
5781
  }
5568
5782
 
@@ -5629,7 +5843,9 @@
5629
5843
  row.appendChild(buildUserMsgEl(msg));
5630
5844
  }
5631
5845
  } else {
5632
- row.appendChild(buildAssistantMsgEl(msg.content, false, String(msg.timestamp)));
5846
+ row.appendChild(
5847
+ buildAssistantMsgEl(msg.content, false, String(msg.timestamp), msg.segments)
5848
+ );
5633
5849
  }
5634
5850
  appendTimestamp(row, msg.timestamp);
5635
5851
  messagesEl.appendChild(row);
@@ -5637,7 +5853,9 @@
5637
5853
  if (state.streaming) {
5638
5854
  var row = document.createElement('div');
5639
5855
  row.className = 'cumulus-msg-row';
5640
- row.appendChild(buildAssistantMsgEl(state.streamBuffer, true));
5856
+ row.appendChild(
5857
+ buildAssistantMsgEl(state.streamBuffer, true, null, state.currentSegments)
5858
+ );
5641
5859
  messagesEl.appendChild(row);
5642
5860
  }
5643
5861
  scrollToBottom();
@@ -5920,14 +6138,16 @@
5920
6138
  if (streamRow) {
5921
6139
  var parentRow = streamRow.closest('.cumulus-msg-row') || streamRow.parentElement;
5922
6140
  if (parentRow) {
5923
- var newEl = buildAssistantMsgEl(state.streamBuffer, true);
6141
+ var newEl = buildAssistantMsgEl(state.streamBuffer, true, null, state.currentSegments);
5924
6142
  parentRow.replaceChild(newEl, streamRow);
5925
6143
  }
5926
6144
  } else if (state.streaming) {
5927
6145
  // No streaming element yet — append one
5928
6146
  var row = document.createElement('div');
5929
6147
  row.className = 'cumulus-msg-row';
5930
- row.appendChild(buildAssistantMsgEl(state.streamBuffer, true));
6148
+ row.appendChild(
6149
+ buildAssistantMsgEl(state.streamBuffer, true, null, state.currentSegments)
6150
+ );
5931
6151
  messagesEl.appendChild(row);
5932
6152
  }
5933
6153
  scrollToBottom();
@@ -5961,9 +6181,14 @@
5961
6181
  role: 'assistant',
5962
6182
  content: state.streamBuffer,
5963
6183
  timestamp: Date.now(),
6184
+ segments:
6185
+ state.currentSegments && state.currentSegments.length
6186
+ ? state.currentSegments
6187
+ : undefined,
5964
6188
  });
5965
6189
  state.streamBuffer = '';
5966
6190
  }
6191
+ state.currentSegments = [];
5967
6192
  renderPanelMessages();
5968
6193
  return;
5969
6194
  }
@@ -5975,10 +6200,15 @@
5975
6200
  role: 'assistant',
5976
6201
  content: state.streamBuffer,
5977
6202
  timestamp: Date.now(),
6203
+ segments:
6204
+ state.currentSegments && state.currentSegments.length
6205
+ ? state.currentSegments
6206
+ : undefined,
5978
6207
  });
5979
6208
  }
5980
6209
  // Reset streaming state — the server will send 'interjected' for the old stream
5981
6210
  state.streamBuffer = '';
6211
+ state.currentSegments = [];
5982
6212
  state.interjecting = true;
5983
6213
  state.interjectionStreamId = (state.interjectionStreamId || 0) + 1;
5984
6214
  // Don't set streaming=false — the new message will keep streaming
@@ -6516,9 +6746,12 @@
6516
6746
  role: 'assistant',
6517
6747
  content: s.streamBuffer,
6518
6748
  timestamp: Date.now(),
6749
+ segments:
6750
+ s.currentSegments && s.currentSegments.length ? s.currentSegments : undefined,
6519
6751
  });
6520
6752
  s.streamBuffer = '';
6521
6753
  }
6754
+ s.currentSegments = [];
6522
6755
  s.streaming = false;
6523
6756
  s.stopRequested = false;
6524
6757
  s.interjecting = false;
@@ -6717,7 +6950,14 @@
6717
6950
  break;
6718
6951
 
6719
6952
  case 'segment':
6720
- // Reserved for future verbose display
6953
+ // Activity chip (task 070): accumulate segment for the in-flight turn
6954
+ if (data.threadName && data.segment) {
6955
+ var segState = getThreadState(data.threadName);
6956
+ if (!segState.currentSegments) segState.currentSegments = [];
6957
+ segState.currentSegments.push(data.segment);
6958
+ // Re-render the streaming row so the chip reflects the latest activity
6959
+ refreshThreadPanel(data.threadName, true);
6960
+ }
6721
6961
  break;
6722
6962
 
6723
6963
  case 'voice_info':
@@ -6752,9 +6992,14 @@
6752
6992
  role: 'assistant',
6753
6993
  content: state.streamBuffer,
6754
6994
  timestamp: Date.now(),
6995
+ segments:
6996
+ state.currentSegments && state.currentSegments.length
6997
+ ? state.currentSegments
6998
+ : undefined,
6755
6999
  });
6756
7000
  }
6757
7001
  state.streamBuffer = '';
7002
+ state.currentSegments = [];
6758
7003
  updateThreadActivity(data.threadName);
6759
7004
  refreshThreadPanel(data.threadName);
6760
7005
  break;
@@ -6765,8 +7010,13 @@
6765
7010
  role: 'assistant',
6766
7011
  content: responseContent,
6767
7012
  timestamp: Date.now(),
7013
+ segments:
7014
+ state.currentSegments && state.currentSegments.length
7015
+ ? state.currentSegments
7016
+ : undefined,
6768
7017
  });
6769
7018
  state.streamBuffer = '';
7019
+ state.currentSegments = [];
6770
7020
  updateThreadActivity(data.threadName);
6771
7021
  refreshThreadPanel(data.threadName);
6772
7022
  // Voice mode: speak the assistant response
@@ -6788,21 +7038,28 @@
6788
7038
  var state = getThreadState(data.threadName);
6789
7039
  state.stopRequested = false;
6790
7040
  state.streaming = false;
7041
+ var hadSegments =
7042
+ state.currentSegments && state.currentSegments.length
7043
+ ? state.currentSegments
7044
+ : undefined;
6791
7045
  if (state.streamBuffer) {
6792
7046
  state.messages.push({
6793
7047
  role: 'assistant',
6794
7048
  content:
6795
7049
  state.streamBuffer + '\n\n[Error: ' + (data.error || 'Unknown error') + ']',
6796
7050
  timestamp: Date.now(),
7051
+ segments: hadSegments,
6797
7052
  });
6798
7053
  } else {
6799
7054
  state.messages.push({
6800
7055
  role: 'assistant',
6801
7056
  content: '[Error: ' + (data.error || 'Unknown error') + ']',
6802
7057
  timestamp: Date.now(),
7058
+ segments: hadSegments,
6803
7059
  });
6804
7060
  }
6805
7061
  state.streamBuffer = '';
7062
+ state.currentSegments = [];
6806
7063
  refreshThreadPanel(data.threadName);
6807
7064
  }
6808
7065
  break;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/lib/projects.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AA4BD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC,CAkE3F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA4BlF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAUjC;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,eAAe,GAAG,WAAW,CAAC,CAAC,EAClF,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAoC1B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,YAAY,UAAQ,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luckydraw/cumulus",
3
- "version": "0.30.30",
3
+ "version": "0.30.31",
4
4
  "description": "RLM-based CLI chat wrapper for Claude with external history context management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,103 +0,0 @@
1
- /**
2
- * Intent Reviewer — adversarial quality gate for Write/Edit tool calls.
3
- *
4
- * Intercepts Write/Edit results, compares stated intent vs actual execution
5
- * using GLM-5 via HuggingFace, and either passes or rejects with actionable feedback.
6
- * After 3 failures on the same task+file, escalates to the user.
7
- */
8
- export interface ReviewVerdict {
9
- verdict: 'pass' | 'provisional_pass' | 'fail';
10
- score: number;
11
- claims: Array<{
12
- claim: string;
13
- finding: string;
14
- result: 'true' | 'false' | 'partially_false';
15
- }>;
16
- limitations: string;
17
- feedback: string;
18
- }
19
- export interface ReviewInput {
20
- intent: string;
21
- execution: {
22
- type: 'edit' | 'write';
23
- file: string;
24
- old?: string;
25
- new_content: string;
26
- };
27
- taskContext?: string;
28
- }
29
- export interface ReviewLog {
30
- threadId: string;
31
- model: string;
32
- toolName: string;
33
- filePath: string;
34
- verdict: 'pass' | 'provisional_pass' | 'fail' | 'skipped' | 'timeout' | 'error';
35
- score: number;
36
- attempt: number;
37
- latencyMs: number;
38
- timestamp: number;
39
- }
40
- export declare function shouldReview(toolName: string, params: Record<string, unknown>): boolean;
41
- interface MessageLike {
42
- role: string;
43
- content: string | Array<{
44
- type: string;
45
- text?: string;
46
- }>;
47
- }
48
- /**
49
- * Extract intent from the last assistant message.
50
- * Priority: <thinking> > active <todo> item > plain text.
51
- */
52
- export declare function extractIntent(messages: MessageLike[]): string | null;
53
- /**
54
- * Get the currently-active todo text (first [ ] item in last <todo> block).
55
- * Used for failure counter keys and reset detection.
56
- */
57
- export declare function getActiveTodoText(messages: MessageLike[]): string | null;
58
- export declare class IntentReviewer {
59
- private hfApiKey;
60
- private states;
61
- private reviewLogs;
62
- constructor(hfApiKey: string);
63
- /**
64
- * Get or create per-thread review state.
65
- */
66
- private getState;
67
- /**
68
- * Reset failure counters when user sends a new message.
69
- */
70
- resetOnNewUserMessage(threadId: string): void;
71
- /**
72
- * Check if active todo changed (reset counters for affected files).
73
- */
74
- private checkTodoReset;
75
- /**
76
- * Evaluate a Write/Edit execution against stated intent.
77
- * Returns the modified tool result (pass-through, annotated, or error).
78
- */
79
- evaluate(threadId: string, model: string, toolName: string, params: Record<string, unknown>, toolResult: string, messages: MessageLike[]): Promise<{
80
- output: string;
81
- isError: boolean;
82
- }>;
83
- /**
84
- * Call GLM-5 via HuggingFace to evaluate intent vs execution.
85
- */
86
- private callReviewModel;
87
- /**
88
- * Log a review for analytics.
89
- */
90
- private logReview;
91
- /**
92
- * Get review statistics for analytics.
93
- */
94
- getStats(): {
95
- total: number;
96
- byVerdict: Record<string, number>;
97
- avgLatencyMs: number;
98
- p95LatencyMs: number;
99
- p99LatencyMs: number;
100
- };
101
- }
102
- export {};
103
- //# sourceMappingURL=intent-reviewer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"intent-reviewer.d.ts","sourceRoot":"","sources":["../../src/lib/intent-reviewer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,MAAM,CAAC;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,iBAAiB,CAAA;KAAE,CAAC,CAAC;IAChG,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AA2CD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAmBT;AAID,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAmDpE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAyBxE;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,UAAU,CAAmB;gBAEzB,QAAQ,EAAE,MAAM;IAI5B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAWhB;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQ7C;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;;OAGG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAiHhD;;OAEG;YACW,eAAe;IA8D7B;;OAEG;IACH,OAAO,CAAC,SAAS;IAmCjB;;OAEG;IACH,QAAQ,IAAI;QACV,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB;CAiBF"}
@@ -1,363 +0,0 @@
1
- /**
2
- * Intent Reviewer — adversarial quality gate for Write/Edit tool calls.
3
- *
4
- * Intercepts Write/Edit results, compares stated intent vs actual execution
5
- * using GLM-5 via HuggingFace, and either passes or rejects with actionable feedback.
6
- * After 3 failures on the same task+file, escalates to the user.
7
- */
8
- // ─── Constants ───────────────────────────────────────────────────────────────
9
- const REVIEW_MODEL = 'zai-org/GLM-5';
10
- const REVIEW_TIMEOUT_MS = 5_000; // GLM-5 via HF is slower than Haiku
11
- const MAX_STRIKES = 3;
12
- const HF_API_URL = 'https://router.huggingface.co/v1/chat/completions';
13
- const REVIEWER_SYSTEM_PROMPT = `You are an Intent Reviewer. Your job is to DISPROVE that the output matches the stated intent. Assume the output is wrong until proven otherwise.
14
-
15
- ## What You Receive
16
- - INTENT: What was planned (from <thinking>, <todo>, or surrounding text)
17
- - EXECUTION: What was actually written (the diff or file content)
18
- - TASK CONTEXT: The user's original request (if available)
19
-
20
- For each claim in the intent, challenge it against the literal code. Does the implementation match both the letter and spirit of the claim?
21
-
22
- ## What You Cannot Evaluate
23
- Subjective quality (fun, beautiful, engaging) is beyond your scope. State this limitation explicitly. Give a provisional pass when all verifiable claims check out but subjective assessment is needed.
24
-
25
- ## Response Format
26
- Respond with ONLY valid JSON (no markdown fencing, no extra text):
27
- {
28
- "verdict": "pass" | "provisional_pass" | "fail",
29
- "score": 0-10,
30
- "claims": [
31
- { "claim": "description of what was intended", "finding": "what was actually done", "result": "true" | "false" | "partially_false" }
32
- ],
33
- "limitations": "any aspects you cannot evaluate",
34
- "feedback": "specific actionable feedback if failing, empty string if passing"
35
- }`;
36
- // ─── Skip Logic ──────────────────────────────────────────────────────────────
37
- const SKIP_EXTENSIONS = /\.(json|yml|yaml|toml|env|lock|md|txt|csv|log)$/i;
38
- export function shouldReview(toolName, params) {
39
- if (toolName !== 'Write' && toolName !== 'Edit')
40
- return false;
41
- const file = params.file_path || '';
42
- if (SKIP_EXTENSIONS.test(file))
43
- return false;
44
- // Skip tiny edits (< 5 lines changed)
45
- if (params.old_string && params.new_string) {
46
- const oldLines = params.old_string.split('\n').length;
47
- const newLines = params.new_string.split('\n').length;
48
- if (Math.max(oldLines, newLines) < 5)
49
- return false;
50
- }
51
- // Skip tiny new files (< 20 lines)
52
- if (toolName === 'Write' && params.content) {
53
- if (params.content.split('\n').length < 20)
54
- return false;
55
- }
56
- return true;
57
- }
58
- /**
59
- * Extract intent from the last assistant message.
60
- * Priority: <thinking> > active <todo> item > plain text.
61
- */
62
- export function extractIntent(messages) {
63
- // Walk backwards to find last assistant message
64
- for (let i = messages.length - 1; i >= 0; i--) {
65
- const msg = messages[i];
66
- if (msg.role !== 'assistant')
67
- continue;
68
- const text = typeof msg.content === 'string'
69
- ? msg.content
70
- : msg.content
71
- .filter(b => b.type === 'text' && b.text)
72
- .map(b => b.text)
73
- .join('\n');
74
- if (!text)
75
- continue;
76
- const parts = [];
77
- // Extract <thinking> block
78
- const thinkingMatch = text.match(/<thinking>([\s\S]*?)<\/thinking>/);
79
- if (thinkingMatch) {
80
- parts.push(`THINKING: ${thinkingMatch[1].trim()}`);
81
- }
82
- // Extract active <todo> item (first [ ] in last <todo> block)
83
- const todoBlocks = [...text.matchAll(/<todo>([\s\S]*?)<\/todo>/g)];
84
- if (todoBlocks.length > 0) {
85
- const lastTodo = todoBlocks[todoBlocks.length - 1][1];
86
- const activeItem = lastTodo
87
- .split('\n')
88
- .find(line => line.match(/^[-\s]*\[ \]/));
89
- if (activeItem) {
90
- parts.push(`ACTIVE TODO: ${activeItem.replace(/^[-\s]*\[ \]\s*/, '').trim()}`);
91
- }
92
- }
93
- // Extract plain text (non-tag content)
94
- const plainText = text
95
- .replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
96
- .replace(/<todo>[\s\S]*?<\/todo>/g, '')
97
- .trim();
98
- if (plainText) {
99
- parts.push(`TEXT: ${plainText.substring(0, 500)}`);
100
- }
101
- if (parts.length > 0) {
102
- return parts.join('\n\n');
103
- }
104
- }
105
- return null;
106
- }
107
- /**
108
- * Get the currently-active todo text (first [ ] item in last <todo> block).
109
- * Used for failure counter keys and reset detection.
110
- */
111
- export function getActiveTodoText(messages) {
112
- for (let i = messages.length - 1; i >= 0; i--) {
113
- const msg = messages[i];
114
- if (msg.role !== 'assistant')
115
- continue;
116
- const text = typeof msg.content === 'string'
117
- ? msg.content
118
- : msg.content
119
- .filter(b => b.type === 'text' && b.text)
120
- .map(b => b.text)
121
- .join('\n');
122
- const todoBlocks = [...text.matchAll(/<todo>([\s\S]*?)<\/todo>/g)];
123
- if (todoBlocks.length > 0) {
124
- const lastTodo = todoBlocks[todoBlocks.length - 1][1];
125
- const activeItem = lastTodo
126
- .split('\n')
127
- .find(line => line.match(/^[-\s]*\[ \]/));
128
- if (activeItem) {
129
- return activeItem.replace(/^[-\s]*\[ \]\s*/, '').trim();
130
- }
131
- }
132
- }
133
- return null;
134
- }
135
- // ─── Intent Reviewer ─────────────────────────────────────────────────────────
136
- export class IntentReviewer {
137
- hfApiKey;
138
- states = new Map();
139
- reviewLogs = [];
140
- constructor(hfApiKey) {
141
- this.hfApiKey = hfApiKey;
142
- }
143
- /**
144
- * Get or create per-thread review state.
145
- */
146
- getState(threadId) {
147
- if (!this.states.has(threadId)) {
148
- this.states.set(threadId, {
149
- failureCounts: new Map(),
150
- feedbackHistory: new Map(),
151
- lastActiveTodo: null,
152
- });
153
- }
154
- return this.states.get(threadId);
155
- }
156
- /**
157
- * Reset failure counters when user sends a new message.
158
- */
159
- resetOnNewUserMessage(threadId) {
160
- const state = this.states.get(threadId);
161
- if (state) {
162
- state.failureCounts.clear();
163
- state.feedbackHistory.clear();
164
- }
165
- }
166
- /**
167
- * Check if active todo changed (reset counters for affected files).
168
- */
169
- checkTodoReset(threadId, currentTodo) {
170
- const state = this.getState(threadId);
171
- if (currentTodo && state.lastActiveTodo && currentTodo !== state.lastActiveTodo) {
172
- // Active todo changed — reset all counters
173
- state.failureCounts.clear();
174
- state.feedbackHistory.clear();
175
- }
176
- state.lastActiveTodo = currentTodo;
177
- }
178
- /**
179
- * Evaluate a Write/Edit execution against stated intent.
180
- * Returns the modified tool result (pass-through, annotated, or error).
181
- */
182
- async evaluate(threadId, model, toolName, params, toolResult, messages) {
183
- const filePath = params.file_path || 'unknown';
184
- const activeTodo = getActiveTodoText(messages);
185
- this.checkTodoReset(threadId, activeTodo);
186
- // Extract intent
187
- const intent = extractIntent(messages);
188
- if (!intent) {
189
- this.logReview(threadId, model, toolName, filePath, 'skipped', 0, 0, 0);
190
- return { output: toolResult, isError: false };
191
- }
192
- // Build execution description
193
- const execution = toolName === 'Edit'
194
- ? {
195
- type: 'edit',
196
- file: filePath,
197
- old: params.old_string,
198
- new_content: params.new_string,
199
- }
200
- : {
201
- type: 'write',
202
- file: filePath,
203
- new_content: params.content,
204
- };
205
- // Truncate large content for the review (keep it fast)
206
- const maxContentChars = 3000;
207
- const executionDesc = execution.type === 'edit'
208
- ? `FILE: ${execution.file}\nOLD:\n${(execution.old || '').slice(0, maxContentChars)}\nNEW:\n${execution.new_content.slice(0, maxContentChars)}`
209
- : `FILE: ${execution.file}\nCONTENT:\n${execution.new_content.slice(0, maxContentChars)}`;
210
- // Call Haiku with timeout
211
- const startTime = Date.now();
212
- let verdict;
213
- try {
214
- verdict = await this.callReviewModel(intent, executionDesc, REVIEW_TIMEOUT_MS);
215
- }
216
- catch (err) {
217
- const latency = Date.now() - startTime;
218
- const isTimeout = err.message?.includes('timeout');
219
- this.logReview(threadId, model, toolName, filePath, isTimeout ? 'timeout' : 'error', 0, 0, latency);
220
- console.warn(`[IntentReviewer] ${isTimeout ? 'TIMEOUT' : 'ERROR'} thread=${threadId} ` +
221
- `latency=${latency}ms: ${err.message}`);
222
- // Default to pass on infrastructure failure
223
- return { output: toolResult, isError: false };
224
- }
225
- const latency = Date.now() - startTime;
226
- const state = this.getState(threadId);
227
- const key = `${activeTodo || 'no-todo'}:${filePath}`;
228
- if (verdict.verdict === 'pass') {
229
- this.logReview(threadId, model, toolName, filePath, 'pass', verdict.score, 0, latency);
230
- return { output: toolResult, isError: false };
231
- }
232
- if (verdict.verdict === 'provisional_pass') {
233
- this.logReview(threadId, model, toolName, filePath, 'provisional_pass', verdict.score, 0, latency);
234
- const annotation = `\n\n[Intent Review: PROVISIONAL PASS — Score ${verdict.score}/10]\n` +
235
- `Verified: ${verdict.claims.filter(c => c.result === 'true').map(c => c.claim).join(', ')}\n` +
236
- `Unverifiable: ${verdict.limitations}`;
237
- return { output: toolResult + annotation, isError: false };
238
- }
239
- // FAIL
240
- const count = (state.failureCounts.get(key) || 0) + 1;
241
- state.failureCounts.set(key, count);
242
- if (!state.feedbackHistory.has(key)) {
243
- state.feedbackHistory.set(key, []);
244
- }
245
- state.feedbackHistory.get(key).push(verdict.feedback);
246
- this.logReview(threadId, model, toolName, filePath, 'fail', verdict.score, count, latency);
247
- if (count >= MAX_STRIKES) {
248
- const allFeedback = state.feedbackHistory.get(key) || [];
249
- return {
250
- output: `ESCALATION REQUIRED: You have failed this task ${MAX_STRIKES} times.\n\n` +
251
- `Previous feedback:\n${allFeedback.map((f, i) => ` Attempt ${i + 1}: ${f}`).join('\n')}\n\n` +
252
- `You MUST now:\n` +
253
- `1. Stop attempting this task\n` +
254
- `2. Explain the core difficulty to the user\n` +
255
- `3. Suggest 2-3 ways to proceed\n\n` +
256
- `Do NOT attempt another revision.`,
257
- isError: true,
258
- };
259
- }
260
- const failedClaims = verdict.claims
261
- .filter(c => c.result !== 'true')
262
- .map(c => `- "${c.claim}" → ${c.finding}`)
263
- .join('\n');
264
- return {
265
- output: `REVISION REQUIRED (attempt ${count}/${MAX_STRIKES}): ${verdict.feedback}\n\n` +
266
- `Claims that failed:\n${failedClaims}`,
267
- isError: true,
268
- };
269
- }
270
- /**
271
- * Call GLM-5 via HuggingFace to evaluate intent vs execution.
272
- */
273
- async callReviewModel(intent, execution, timeoutMs) {
274
- const userMessage = `## INTENT\n${intent}\n\n## EXECUTION\n${execution}`;
275
- const controller = new AbortController();
276
- const timer = setTimeout(() => controller.abort(), timeoutMs);
277
- try {
278
- const response = await fetch(HF_API_URL, {
279
- method: 'POST',
280
- headers: {
281
- 'Content-Type': 'application/json',
282
- Authorization: `Bearer ${this.hfApiKey}`,
283
- },
284
- body: JSON.stringify({
285
- model: REVIEW_MODEL,
286
- max_tokens: 1024,
287
- stream: false,
288
- messages: [
289
- { role: 'system', content: REVIEWER_SYSTEM_PROMPT },
290
- { role: 'user', content: userMessage },
291
- ],
292
- }),
293
- signal: controller.signal,
294
- });
295
- clearTimeout(timer);
296
- if (!response.ok) {
297
- const body = await response.text().catch(() => '');
298
- throw Object.assign(new Error(`HF API ${response.status}: ${body.slice(0, 200)}`), {
299
- status: response.status,
300
- });
301
- }
302
- const json = (await response.json());
303
- const text = json.choices?.[0]?.message?.content || '';
304
- // Parse JSON — strip markdown fencing if present
305
- const cleaned = text.replace(/^```(?:json)?\s*\n?/m, '').replace(/\n?```\s*$/m, '').trim();
306
- const parsed = JSON.parse(cleaned);
307
- // Validate required fields
308
- if (!parsed.verdict || !['pass', 'provisional_pass', 'fail'].includes(parsed.verdict)) {
309
- throw new Error(`Invalid verdict: ${parsed.verdict}`);
310
- }
311
- return parsed;
312
- }
313
- catch (err) {
314
- clearTimeout(timer);
315
- if (err.name === 'AbortError') {
316
- throw new Error('Review timeout exceeded');
317
- }
318
- throw err;
319
- }
320
- }
321
- /**
322
- * Log a review for analytics.
323
- */
324
- logReview(threadId, model, toolName, filePath, verdict, score, attempt, latencyMs) {
325
- const entry = {
326
- threadId,
327
- model,
328
- toolName,
329
- filePath,
330
- verdict,
331
- score,
332
- attempt,
333
- latencyMs,
334
- timestamp: Date.now(),
335
- };
336
- this.reviewLogs.push(entry);
337
- // Keep only last 1000 entries in memory
338
- if (this.reviewLogs.length > 1000) {
339
- this.reviewLogs = this.reviewLogs.slice(-500);
340
- }
341
- console.log(`[IntentReviewer] thread=${threadId} tool=${toolName} file=${filePath.split('/').pop()} ` +
342
- `verdict=${verdict} score=${score} attempt=${attempt} latency=${latencyMs}ms`);
343
- }
344
- /**
345
- * Get review statistics for analytics.
346
- */
347
- getStats() {
348
- const total = this.reviewLogs.length;
349
- const byVerdict = {};
350
- const latencies = [];
351
- for (const log of this.reviewLogs) {
352
- byVerdict[log.verdict] = (byVerdict[log.verdict] || 0) + 1;
353
- if (log.latencyMs > 0)
354
- latencies.push(log.latencyMs);
355
- }
356
- latencies.sort((a, b) => a - b);
357
- const avg = latencies.length > 0 ? latencies.reduce((a, b) => a + b, 0) / latencies.length : 0;
358
- const p95 = latencies.length > 0 ? latencies[Math.floor(latencies.length * 0.95)] : 0;
359
- const p99 = latencies.length > 0 ? latencies[Math.floor(latencies.length * 0.99)] : 0;
360
- return { total, byVerdict, avgLatencyMs: Math.round(avg), p95LatencyMs: p95 ?? 0, p99LatencyMs: p99 ?? 0 };
361
- }
362
- }
363
- //# sourceMappingURL=intent-reviewer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"intent-reviewer.js","sourceRoot":"","sources":["../../src/lib/intent-reviewer.ts"],"names":[],"mappings":"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"}