@wendongfly/myhi 1.3.195 → 1.3.197
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 +23 -6
- package/dist/index.js +1 -1
- package/dist/index.min.js +135 -135
- package/package.json +1 -1
package/dist/chat.html
CHANGED
|
@@ -2906,7 +2906,15 @@
|
|
|
2906
2906
|
}
|
|
2907
2907
|
|
|
2908
2908
|
// ── Socket.IO ──────────────────────────────────
|
|
2909
|
+
// 本页所在位置:随握手上报,服务端在「清除」提示/日志里标明是谁、从哪儿点的
|
|
2910
|
+
const CLIENT_WHERE = (() => {
|
|
2911
|
+
const em = new URLSearchParams(location.search).get('embed');
|
|
2912
|
+
if (em === '1') return 'grid';
|
|
2913
|
+
if (em === 'ws') return 'workbench';
|
|
2914
|
+
return matchMedia('(pointer: coarse)').matches ? 'mobile' : 'desktop';
|
|
2915
|
+
})();
|
|
2909
2916
|
const socket = io({
|
|
2917
|
+
query: { where: CLIENT_WHERE },
|
|
2910
2918
|
transports: ['websocket', 'polling'],
|
|
2911
2919
|
reconnection: true,
|
|
2912
2920
|
reconnectionAttempts: Infinity,
|
|
@@ -3043,6 +3051,11 @@
|
|
|
3043
3051
|
document.querySelectorAll(`[data-inject-tag="${CSS.escape(msg.id || '')}"]`).forEach(t => { t.outerHTML = injectTagHtml({ id: msg.id, state: msg.state, reason: msg.reason }); });
|
|
3044
3052
|
if (msg.state === 'dropped' && msg.reason) addStatusMessage('⚡ ' + msg.reason);
|
|
3045
3053
|
} else if (msg.subtype === 'info' && msg.message) {
|
|
3054
|
+
// 别的页面清除了上下文:本页聊天区还留着旧记录,划条线说明上面的 AI 已经不记得了
|
|
3055
|
+
if (msg.cleared && chatArea.querySelector('.msg-input, .msg-assistant, .msg-tool')) {
|
|
3056
|
+
addStatusMessage('⬆ 以上为清除前的旧对话,AI 已不再记得');
|
|
3057
|
+
_ctxNudgeLevel = 0; _lastCtxTokens = 0; ctxUpdate(0);
|
|
3058
|
+
}
|
|
3046
3059
|
addStatusMessage(msg.message);
|
|
3047
3060
|
// 同步计划模式状态到按钮
|
|
3048
3061
|
if (msg.message.includes('进入计划模式')) {
|
|
@@ -5130,7 +5143,7 @@
|
|
|
5130
5143
|
// Agent 模式:发送 /clear 清除 Claude 上下文
|
|
5131
5144
|
if (currentSession?.mode === 'agent') {
|
|
5132
5145
|
if (!isController && canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID });
|
|
5133
|
-
socket.emit('agent:query', { prompt: '/clear' }); //
|
|
5146
|
+
socket.emit('agent:query', { prompt: '/clear', via: 'button' }); // 服务端回一条「已开始新对话」(带操作人/来源),所有在看的人都能看到
|
|
5134
5147
|
_ctxNudgeLevel = 0;
|
|
5135
5148
|
_lastCtxTokens = 0;
|
|
5136
5149
|
ctxUpdate(0); // 上下文已清空,水位指示复位
|
|
@@ -7092,13 +7105,17 @@
|
|
|
7092
7105
|
const img = new Image(); const url = URL.createObjectURL(srcBlob);
|
|
7093
7106
|
const blob = await new Promise((resolve, reject) => {
|
|
7094
7107
|
img.onload = () => { URL.revokeObjectURL(url); let {width:w, height:h} = img;
|
|
7095
|
-
//
|
|
7096
|
-
|
|
7097
|
-
|
|
7108
|
+
// 压缩策略:长边 ≤1568px 且总像素 ≤1.15MP(Claude 视觉的原生上限,再大也会被模型侧缩小),
|
|
7109
|
+
// JPEG 质量 0.85 —— 768px/0.7 时截图里的小字糊到模型认不出
|
|
7110
|
+
const M = 1568, P = 1.15e6;
|
|
7111
|
+
const s = Math.min(1, M / Math.max(w, h), Math.sqrt(P / (w * h)));
|
|
7112
|
+
w = Math.round(w * s); h = Math.round(h * s);
|
|
7098
7113
|
const c=document.createElement('canvas');c.width=w;c.height=h;c.getContext('2d').drawImage(img,0,0,w,h);
|
|
7099
|
-
c.toBlob(b=>b?resolve(b):reject(new Error('toBlob failed')),'image/jpeg',0.
|
|
7114
|
+
c.toBlob(b=>b?resolve(b):reject(new Error('toBlob failed')),'image/jpeg',0.85); };
|
|
7100
7115
|
img.onerror=reject; img.src=url; });
|
|
7101
|
-
|
|
7116
|
+
// 输出恒为 JPEG:扩展名跟着改,免得 paste.png 里装 JPEG 导致按扩展名判类型的下游报错
|
|
7117
|
+
const base = (filename || 'image').replace(/\.[^.]+$/, '');
|
|
7118
|
+
const form = new FormData(); form.append('image', blob, base + '.jpg');
|
|
7102
7119
|
const res = await fetch(`/upload?sessionId=${SESSION_ID}`, { method: 'POST', body: form });
|
|
7103
7120
|
const data = await res.json();
|
|
7104
7121
|
if (!data.path) throw new Error(data.error || '上传失败');
|