@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 +110 -2
- package/dist/index.js +4 -3
- package/package.json +1 -1
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
|
-
//
|
|
1082
|
+
// 未知消息类型,仅在有实质内容时显示
|
|
975
1083
|
if (msg.type !== 'user') {
|
|
976
|
-
|
|
1084
|
+
// 静默忽略常见的生命周期消息
|
|
977
1085
|
}
|
|
978
1086
|
}
|
|
979
1087
|
});
|