@wendongfly/myhi 1.0.38 → 1.0.40

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/dist/chat.html CHANGED
@@ -543,6 +543,37 @@
543
543
  setWorkState('working');
544
544
  }
545
545
 
546
+ // 流式增量追加(content_block_delta)
547
+ function appendStream(text) {
548
+ endToolGroup();
549
+ if (_streamEl && chatArea.contains(_streamEl)) {
550
+ _streamText += text;
551
+ const content = _streamEl.querySelector('.content');
552
+ if (content) content.innerHTML = renderMarkdown(_streamText);
553
+ scrollToBottom();
554
+ } else {
555
+ // 还没有流式容器,新建一个
556
+ _streamText = text;
557
+ const msg = document.createElement('div');
558
+ msg.className = 'msg msg-assistant';
559
+ const content = document.createElement('div');
560
+ content.className = 'content';
561
+ content.innerHTML = renderMarkdown(text);
562
+ msg.appendChild(content);
563
+ chatArea.appendChild(msg);
564
+ _streamEl = msg;
565
+ trimMessages();
566
+ scrollToBottom();
567
+ }
568
+ setWorkState('working');
569
+ }
570
+
571
+ function appendThinking(text) {
572
+ if (!thinkingEl) { showThinking(text); return; }
573
+ const content = thinkingEl.querySelector('.thinking-content');
574
+ if (content) { content.textContent += text; scrollToBottom(); }
575
+ }
576
+
546
577
  // 当收到非 assistant 类型的消息时,结束流式追加
547
578
  function endStream() { _streamEl = null; _streamText = ''; }
548
579
 
@@ -760,6 +791,14 @@
760
791
  if (actions) actions.innerHTML = answer === 'y' ? '<span style="color:#3fb950">已允许</span>' : '<span style="color:#f85149">已拒绝</span>';
761
792
  };
762
793
 
794
+ window.respondAgentPermission = function(requestId, allow, btn) {
795
+ if (!isController) { addStatusMessage('你没有控制权,无法操作'); return; }
796
+ socket.emit('agent:permission', { requestId, allow });
797
+ const actions = btn.closest('.perm-actions');
798
+ if (actions) actions.innerHTML = allow ? '<span style="color:#3fb950">已允许</span>' : '<span style="color:#f85149">已拒绝</span>';
799
+ setWorkState('working');
800
+ };
801
+
763
802
  // ── 输出处理 ──────────────────────────────────
764
803
  function flushOutput() {
765
804
  if (!outputBuffer) return;
@@ -962,18 +1001,87 @@
962
1001
  }
963
1002
  setWorkState('working');
964
1003
  break;
1004
+ case 'control_request':
1005
+ removeThinking();
1006
+ if (msg.request?.subtype === 'can_use_tool') {
1007
+ const toolName = msg.request.tool_name || '未知工具';
1008
+ const input = msg.request.input || {};
1009
+ const detail = toolName === 'Bash' ? (input.command || JSON.stringify(input))
1010
+ : toolName === 'Edit' ? `${input.file_path || ''}`
1011
+ : toolName === 'Write' ? `${input.file_path || ''}`
1012
+ : JSON.stringify(input, null, 2);
1013
+ const reqId = msg.request_id;
1014
+ const el = document.createElement('div');
1015
+ el.className = 'msg msg-permission';
1016
+ el.innerHTML = `<div class="perm-title">${escHtml(toolName)} 请求权限</div><div class="perm-detail">${escHtml(detail)}</div>
1017
+ <div class="perm-actions" data-reqid="${escHtml(reqId)}">
1018
+ <button class="btn-allow" onclick="respondAgentPermission('${escHtml(reqId)}', true, this)">允许</button>
1019
+ <button class="btn-deny" onclick="respondAgentPermission('${escHtml(reqId)}', false, this)">拒绝</button>
1020
+ </div>`;
1021
+ chatArea.appendChild(el);
1022
+ trimMessages();
1023
+ scrollToBottom();
1024
+ setWorkState('waiting');
1025
+ }
1026
+ break;
965
1027
  case 'result':
966
1028
  removeThinking();
967
1029
  setWorkState('idle');
968
1030
  const cost = msg.total_cost_usd ? ` ($${msg.total_cost_usd.toFixed(4)})` : '';
969
1031
  addStatusMessage(`完成${cost}`);
970
1032
  break;
1033
+ case 'content_block_start':
1034
+ // 流式内容块开始(tool_use 时显示工具名)
1035
+ if (msg.content_block?.type === 'tool_use') {
1036
+ addToolMessage('', msg.content_block.name || '工具');
1037
+ } else if (msg.content_block?.type === 'thinking') {
1038
+ showThinking('');
1039
+ }
1040
+ setWorkState('working');
1041
+ break;
1042
+ case 'content_block_delta':
1043
+ // 流式内容增量
1044
+ if (msg.delta?.type === 'text_delta' && msg.delta.text) {
1045
+ appendStream(msg.delta.text);
1046
+ } else if (msg.delta?.type === 'thinking_delta' && msg.delta.thinking) {
1047
+ appendThinking(msg.delta.thinking);
1048
+ } else if (msg.delta?.type === 'input_json_delta' && msg.delta.partial_json) {
1049
+ // 工具参数流式增量,暂不显示
1050
+ }
1051
+ break;
1052
+ case 'content_block_stop':
1053
+ endStream();
1054
+ break;
1055
+ case 'message_start':
1056
+ setWorkState('working');
1057
+ break;
1058
+ case 'message_delta':
1059
+ // 消息结束原因等
1060
+ break;
1061
+ case 'message_stop':
1062
+ break;
1063
+ case 'tool_use':
1064
+ // 独立工具调用消息
1065
+ addToolMessage(JSON.stringify(msg.input || {}, null, 2), msg.name || '工具');
1066
+ setWorkState('working');
1067
+ break;
1068
+ case 'tool_result':
1069
+ // 独立工具结果消息
1070
+ if (msg.content) {
1071
+ const text = typeof msg.content === 'string' ? msg.content
1072
+ : Array.isArray(msg.content) ? msg.content.map(b => b.text || '').join('\n')
1073
+ : JSON.stringify(msg.content);
1074
+ if (text.trim()) addRawOutput(text);
1075
+ }
1076
+ setWorkState('working');
1077
+ break;
971
1078
  case 'rate_limit_event':
1079
+ case 'control_response':
972
1080
  break; // 忽略
973
1081
  default:
974
- // 未知消息类型,显示为原始 JSON
1082
+ // 未知消息类型,仅在有实质内容时显示
975
1083
  if (msg.type !== 'user') {
976
- addRawOutput(JSON.stringify(msg, null, 2));
1084
+ // 静默忽略常见的生命周期消息
977
1085
  }
978
1086
  }
979
1087
  });