agentgui 1.0.739 → 1.0.741

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.
@@ -96,10 +96,17 @@ export function register(router, deps) {
96
96
  router.handle('conv.chunks', (p) => {
97
97
  if (!queries.getConversation(p.id)) notFound('Conversation not found');
98
98
  const since = parseInt(p.since || '0');
99
- const chunks = since > 0
100
- ? queries.getConversationChunksSince(p.id, since)
101
- : queries.getConversationChunks(p.id);
102
- return { ok: true, chunks };
99
+ const all = p.all === true || p.all === 'true';
100
+ const totalChunks = queries.getConversationChunkCount(p.id);
101
+ let chunks;
102
+ if (since > 0) {
103
+ chunks = queries.getConversationChunksSince(p.id, since);
104
+ } else if (all) {
105
+ chunks = queries.getConversationChunks(p.id);
106
+ } else {
107
+ chunks = queries.getRecentConversationChunks(p.id, 500);
108
+ }
109
+ return { ok: true, chunks, totalChunks };
103
110
  });
104
111
 
105
112
  router.handle('conv.chunks.earlier', (p) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.739",
3
+ "version": "1.0.741",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "electron/main.js",
@@ -956,6 +956,52 @@ class AgentGUIClient {
956
956
  const blocksEl = streamingEl.querySelector('.streaming-blocks');
957
957
  if (!blocksEl) return;
958
958
 
959
+ if (block.type === 'tool_result') {
960
+ const tid = block.tool_use_id;
961
+ const toolUseEl = (tid && blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${tid}"]`))
962
+ || (blocksEl.lastElementChild?.classList?.contains('block-tool-use') ? blocksEl.lastElementChild : null);
963
+ if (toolUseEl) {
964
+ this.renderer.mergeResultIntoToolUse(toolUseEl, block);
965
+ this.scrollToBottom();
966
+ return;
967
+ }
968
+ }
969
+
970
+ if (block.type === 'tool_status') {
971
+ const tid = block.tool_use_id;
972
+ const toolUseEl = tid && blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${tid}"]`);
973
+ if (toolUseEl) {
974
+ const summary = toolUseEl.querySelector(':scope > summary');
975
+ if (summary) {
976
+ let badge = summary.querySelector('.folded-tool-status-live');
977
+ if (!badge) { badge = document.createElement('span'); badge.className = 'folded-tool-status-live'; summary.appendChild(badge); }
978
+ const isRunning = block.status === 'in_progress';
979
+ badge.style.cssText = 'margin-left:auto;font-size:0.65rem;opacity:0.7;display:inline-flex;align-items:center;gap:0.25rem';
980
+ badge.innerHTML = (isRunning ? '<span class="animate-spin" style="display:inline-block;width:0.6rem;height:0.6rem;border:1.5px solid var(--color-border);border-top-color:var(--color-info);border-radius:50%"></span>' : '')
981
+ + '<span>' + (isRunning ? 'Running' : (block.status || '')) + '</span>';
982
+ }
983
+ this.scrollToBottom();
984
+ return;
985
+ }
986
+ }
987
+
988
+ if (block.type === 'hook_progress') {
989
+ const hookEvent = (block.hookEvent || '').split(':')[0];
990
+ if (hookEvent === 'PreToolUse' || hookEvent === 'PostToolUse') {
991
+ const lastTool = blocksEl.querySelector('.block-tool-use:last-of-type') || blocksEl.lastElementChild;
992
+ if (lastTool?.classList?.contains('block-tool-use')) {
993
+ const summary = lastTool.querySelector(':scope > summary');
994
+ if (summary) {
995
+ let hookBadge = summary.querySelector('.folded-tool-hook');
996
+ if (!hookBadge) { hookBadge = document.createElement('span'); hookBadge.className = 'folded-tool-hook'; hookBadge.style.cssText = 'margin-left:0.375rem;font-size:0.6rem;opacity:0.4;font-weight:400'; summary.appendChild(hookBadge); }
997
+ hookBadge.textContent = block.hookEvent?.split(':').pop() || hookEvent;
998
+ }
999
+ return;
1000
+ }
1001
+ }
1002
+ return;
1003
+ }
1004
+
959
1005
  const el = this.renderer.renderBlock(block, data, blocksEl);
960
1006
  if (el) {
961
1007
  blocksEl.appendChild(el);
@@ -2083,7 +2129,8 @@ class AgentGUIClient {
2083
2129
  const deferred = [];
2084
2130
  for (const chunk of list) {
2085
2131
  if (!chunk.block?.type) continue;
2086
- if (chunk.block.type === 'tool_result') { deferred.push(chunk); continue; }
2132
+ const bt = chunk.block.type;
2133
+ if (bt === 'tool_result' || bt === 'tool_status' || bt === 'hook_progress') { deferred.push(chunk); continue; }
2087
2134
  const el = this.renderer.renderBlock(chunk.block, chunk, blockFrag);
2088
2135
  if (!el) continue;
2089
2136
  el.classList.add('block-loaded');
@@ -2091,10 +2138,23 @@ class AgentGUIClient {
2091
2138
  }
2092
2139
  blocksEl.appendChild(blockFrag);
2093
2140
  for (const chunk of deferred) {
2094
- const tid = chunk.block.tool_use_id;
2095
- const toolUseEl = (tid ? blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${tid}"]`) : null)
2096
- || (blocksEl.lastElementChild?.classList.contains('block-tool-use') ? blocksEl.lastElementChild : null);
2097
- if (toolUseEl) this.renderer.mergeResultIntoToolUse(toolUseEl, chunk.block);
2141
+ const b = chunk.block;
2142
+ if (b.type === 'tool_result') {
2143
+ const tid = b.tool_use_id;
2144
+ const toolUseEl = (tid ? blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${tid}"]`) : null)
2145
+ || (blocksEl.lastElementChild?.classList.contains('block-tool-use') ? blocksEl.lastElementChild : null);
2146
+ if (toolUseEl) this.renderer.mergeResultIntoToolUse(toolUseEl, b);
2147
+ } else if (b.type === 'tool_status') {
2148
+ const tid = b.tool_use_id;
2149
+ const toolUseEl = tid && blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${tid}"]`);
2150
+ if (toolUseEl) {
2151
+ const isError = b.status === 'failed';
2152
+ const isDone = b.status === 'completed';
2153
+ if (isDone || isError) {
2154
+ toolUseEl.classList.add(isError ? 'tool-result-error' : 'tool-result-success');
2155
+ }
2156
+ }
2157
+ }
2098
2158
  }
2099
2159
  if (isActive) {
2100
2160
  const ind = document.createElement('div');
@@ -2143,6 +2203,7 @@ class AgentGUIClient {
2143
2203
  return;
2144
2204
  }
2145
2205
  }
2206
+ if (chunk.block.type === 'tool_status' || chunk.block.type === 'hook_progress') return;
2146
2207
  const element = this.renderer.renderBlock(chunk.block, chunk, blocksEl);
2147
2208
  if (!element) { this.scrollToBottom(); return; }
2148
2209
  blocksEl.appendChild(element);
@@ -403,6 +403,8 @@ class StreamingRenderer {
403
403
  return this.renderBlockPlan(block, context);
404
404
  case 'premature':
405
405
  return this.renderBlockPremature(block, context);
406
+ case 'hook_progress':
407
+ return this.renderBlockHookProgress(block, context);
406
408
  default:
407
409
  return this.renderBlockGeneric(block, context);
408
410
  }
@@ -540,23 +542,28 @@ class StreamingRenderer {
540
542
  * Render thinking block (expandable), signature-aware
541
543
  */
542
544
  renderBlockThinking(block, context) {
545
+ const thinking = block.thinking || '';
546
+ const hasSignature = !!block.signature;
543
547
  const div = document.createElement('div');
544
548
  div.className = 'block-thinking';
545
549
  div.classList.add(this._getBlockTypeClass('thinking'));
546
550
 
547
- const thinking = block.thinking || '';
548
- const hasSignature = !!block.signature;
549
- div.innerHTML = `
550
- <details>
551
- <summary>
552
- <svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg>
553
- <span>Thinking Process</span>
554
- ${hasSignature ? '<span style="margin-left:0.5rem;font-size:0.65rem;opacity:0.5;font-weight:400">verified</span>' : ''}
555
- </summary>
556
- <div class="thinking-content">${this.escapeHtml(thinking)}</div>
557
- </details>
558
- `;
559
-
551
+ if (!thinking) {
552
+ div.style.cssText = 'display:flex;align-items:center;gap:0.375rem;padding:0.25rem 0;font-size:0.7rem;color:var(--color-text-secondary);opacity:0.6';
553
+ div.innerHTML = '<svg viewBox="0 0 20 20" fill="currentColor" style="width:0.875rem;height:0.875rem"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/></svg>'
554
+ + '<span>Thinking</span>'
555
+ + (hasSignature ? '<svg viewBox="0 0 20 20" fill="currentColor" style="width:0.75rem;height:0.75rem;color:#3b82f6"><path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>' : '');
556
+ return div;
557
+ }
558
+
559
+ div.innerHTML = '<details>'
560
+ + '<summary>'
561
+ + '<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg>'
562
+ + '<span>Thinking Process</span>'
563
+ + (hasSignature ? '<span style="margin-left:0.5rem;font-size:0.65rem;opacity:0.5;font-weight:400">verified</span>' : '')
564
+ + '</summary>'
565
+ + '<div class="thinking-content">' + this.escapeHtml(thinking) + '</div>'
566
+ + '</details>';
560
567
  return div;
561
568
  }
562
569
 
@@ -1437,6 +1444,23 @@ class StreamingRenderer {
1437
1444
  return div;
1438
1445
  }
1439
1446
 
1447
+ renderBlockHookProgress(block, context) {
1448
+ const hookEvent = block.hookEvent || block.hookName || '';
1449
+ const hookIcons = {
1450
+ PreToolUse: '<svg viewBox="0 0 20 20" fill="currentColor" style="width:0.75rem;height:0.75rem"><path fill-rule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10.666a1 1 0 11-1.64-1.118L9.687 10H5a1 1 0 01-.82-1.573l7-10.666a1 1 0 011.12-.373z" clip-rule="evenodd"/></svg>',
1451
+ PostToolUse: '<svg viewBox="0 0 20 20" fill="currentColor" style="width:0.75rem;height:0.75rem"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>',
1452
+ Stop: '<svg viewBox="0 0 20 20" fill="currentColor" style="width:0.75rem;height:0.75rem"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V8a1 1 0 00-1-1H8z" clip-rule="evenodd"/></svg>'
1453
+ };
1454
+ const icon = hookIcons[hookEvent.split(':')[0]] || hookIcons.PreToolUse;
1455
+ const label = hookEvent.includes(':') ? hookEvent.split(':').pop() : hookEvent;
1456
+ const div = document.createElement('div');
1457
+ div.className = 'block-hook-progress';
1458
+ div.dataset.hookEvent = hookEvent;
1459
+ div.style.cssText = 'display:none';
1460
+ div.innerHTML = '<span class="hook-badge" style="display:inline-flex;align-items:center;gap:0.25rem;padding:0.125rem 0.5rem;font-size:0.65rem;color:var(--color-text-secondary);opacity:0.5">' + icon + '<span>' + this.escapeHtml(label) + '</span></span>';
1461
+ return div;
1462
+ }
1463
+
1440
1464
  /**
1441
1465
  * Render usage block (ACP usage updates)
1442
1466
  */