@wendongfly/myhi 1.3.152 → 1.3.154
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 +65 -3
- package/dist/grid.html +1 -1
- package/dist/index.html +2 -2
- package/dist/index.js +1 -1
- package/dist/index.min.js +3 -3
- package/package.json +1 -1
package/dist/chat.html
CHANGED
|
@@ -402,6 +402,7 @@
|
|
|
402
402
|
<button class="top-btn" onclick="openSettings()" title="设置">
|
|
403
403
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
|
404
404
|
</button>
|
|
405
|
+
<button class="top-btn" id="ctx-chip" onclick="doCompact()" title="上下文水位(点击压缩释放空间)" style="display:none;font-size:0.7rem;color:var(--muted)">上下文</button>
|
|
405
406
|
<button class="top-btn" onclick="showUsage()" title="用量" style="font-size:0.7rem;color:var(--muted)">用量</button>
|
|
406
407
|
<button class="top-btn" onclick="openFilePanel()" title="文件" style="font-size:0.7rem;color:var(--muted)">文件</button>
|
|
407
408
|
<button class="top-btn" onclick="openSwitchSheet()" title="切换会话" style="font-size:0.7rem;color:var(--muted)">切换</button>
|
|
@@ -2167,6 +2168,7 @@
|
|
|
2167
2168
|
claudeSession = isClaudeSession(session) || session.mode === 'agent';
|
|
2168
2169
|
updateShortcutBar();
|
|
2169
2170
|
updatePlanButton();
|
|
2171
|
+
ctxUpdate(session.contextTokens || 0);
|
|
2170
2172
|
|
|
2171
2173
|
// 更新输入框占位符
|
|
2172
2174
|
cmdInput.placeholder = session.mode === 'agent' ? '输入消息...' : '输入命令...';
|
|
@@ -2242,6 +2244,11 @@
|
|
|
2242
2244
|
break;
|
|
2243
2245
|
case 'assistant':
|
|
2244
2246
|
removeThinking();
|
|
2247
|
+
if (msg.message?.usage) {
|
|
2248
|
+
const cu = msg.message.usage;
|
|
2249
|
+
const ct = (cu.input_tokens || 0) + (cu.cache_read_input_tokens || 0) + (cu.cache_creation_input_tokens || 0);
|
|
2250
|
+
if (ct > 0) ctxUpdate(ct);
|
|
2251
|
+
}
|
|
2245
2252
|
if (msg.message?.content) {
|
|
2246
2253
|
// 进入 loop 前快照:同一 assistant 事件里所有 text 块统一按入口时刻的 call 标志决定,
|
|
2247
2254
|
// 避免渲染完第一段 text 后置位标志,导致同事件内 [text, tool_use, text] 的第二段被跳过
|
|
@@ -2286,6 +2293,12 @@
|
|
|
2286
2293
|
// 关键:idle 放最后——渲染最终答复的 addAssistantMessage 会把状态置回 'working',
|
|
2287
2294
|
// 若在其之前置 idle 会被顶回「执行中」+ 取消按钮不复位。渲染全部完成后再回 idle。
|
|
2288
2295
|
setWorkState('idle');
|
|
2296
|
+
// 收尾水位提示:assistant 流中已实时更新 chip,这里按最终 usage 补一次提示(80/90 档各一次)
|
|
2297
|
+
{
|
|
2298
|
+
const ru = msg.usage;
|
|
2299
|
+
const ct = ru ? (ru.input_tokens || 0) + (ru.cache_read_input_tokens || 0) + (ru.cache_creation_input_tokens || 0) : 0;
|
|
2300
|
+
if (ct > 0) { ctxUpdate(ct); ctxMaybeNudge(ct); }
|
|
2301
|
+
}
|
|
2289
2302
|
break;
|
|
2290
2303
|
case 'content_block_start':
|
|
2291
2304
|
// 流式内容块开始:thinking 时创建占位,由 thinking_delta 增量填充;
|
|
@@ -2608,6 +2621,51 @@
|
|
|
2608
2621
|
|
|
2609
2622
|
// ── 输入处理 ──────────────────────────────────
|
|
2610
2623
|
window.sendCommand = sendCommand;
|
|
2624
|
+
// ── 上下文水位指示 ──────────────────────────────
|
|
2625
|
+
// 数据源:claude 每条 assistant/result 消息的 usage(input + cache 读/写)≈ 当前上下文 token 总量。
|
|
2626
|
+
// claude 满 ~90% 会 auto-compact;myhi 显示水位 + 过阈值提示,让用户在任务节点**主动**压缩更可控。
|
|
2627
|
+
const CTX_WARN = 0.75, CTX_URGENT = 0.9;
|
|
2628
|
+
function ctxLimit(tokens) {
|
|
2629
|
+
// 200k 窗口装不下 >200k,超过即证明是 1M 上下文模型
|
|
2630
|
+
return tokens > 200_000 ? 1_000_000 : 200_000;
|
|
2631
|
+
}
|
|
2632
|
+
function ctxUpdate(tokens) {
|
|
2633
|
+
const chip = document.getElementById('ctx-chip');
|
|
2634
|
+
if (!chip) return;
|
|
2635
|
+
if (!tokens || tokens <= 0) { chip.style.display = 'none'; return; }
|
|
2636
|
+
const limit = ctxLimit(tokens);
|
|
2637
|
+
const pct = Math.min(100, Math.round(tokens / limit * 100));
|
|
2638
|
+
chip.style.display = '';
|
|
2639
|
+
chip.textContent = `上下文 ${pct}%`;
|
|
2640
|
+
chip.style.color = pct >= 90 ? 'var(--red)' : pct >= 75 ? 'var(--yellow)' : 'var(--muted)';
|
|
2641
|
+
// 压缩快捷按钮同步高亮(agent 栏是 doSlashCmd('/compact'),PTY 栏是 doCompact())
|
|
2642
|
+
for (const sel of [
|
|
2643
|
+
'#sk-claude-agent button[onclick*="/compact"]',
|
|
2644
|
+
'#sk-claude-pty button[onclick*="compact"]',
|
|
2645
|
+
]) {
|
|
2646
|
+
const cbtn = document.querySelector(sel);
|
|
2647
|
+
if (cbtn) cbtn.style.color = pct >= 75 ? (pct >= 90 ? 'var(--red)' : 'var(--yellow)') : '';
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
let _ctxNudgeLevel = 0; // 已提示过的档位:0 无 / 1 警告 / 2 紧急
|
|
2651
|
+
function ctxMaybeNudge(tokens) {
|
|
2652
|
+
const pct = tokens / ctxLimit(tokens) * 100;
|
|
2653
|
+
const level = pct >= 90 ? 2 : pct >= 75 ? 1 : 0;
|
|
2654
|
+
if (level <= _ctxNudgeLevel) return;
|
|
2655
|
+
_ctxNudgeLevel = level;
|
|
2656
|
+
const msg = level === 2
|
|
2657
|
+
? `⚠️ 上下文已用约 ${Math.round(pct)}%,快满了——claude 即将自动压缩(可能丢细节)。建议现在就在任务节点点「压缩」主动收尾,或 /clear 重开干净会话。`
|
|
2658
|
+
: `💡 上下文已用约 ${Math.round(pct)}%。建议在当前任务收尾后点「压缩」(/compact)释放空间,长对话越往后越慢越贵。`;
|
|
2659
|
+
addStatusMessage(msg);
|
|
2660
|
+
}
|
|
2661
|
+
window.ctxUpdate = ctxUpdate; // 惯例挂 window(同 doClear/doCompact),便于外部/测试驱动
|
|
2662
|
+
window.ctxMaybeNudge = ctxMaybeNudge;
|
|
2663
|
+
|
|
2664
|
+
// 服务端本地处理的 slash 命令(agent.js 拦截后只回一条 system/info、不 spawn claude、
|
|
2665
|
+
// 永远等不到 result)—— 这些不能进 thinking/working 态,否则没人把它清回来:
|
|
2666
|
+
// 切模型后输入框永远「运行中」(1.3.152 用户实测)。
|
|
2667
|
+
const LOCAL_SLASH_RE = /^\/(clear|rename|model\s|resume\s|plan(\s|$))/;
|
|
2668
|
+
|
|
2611
2669
|
function sendCommand() {
|
|
2612
2670
|
const text = cmdInput.value.trim();
|
|
2613
2671
|
if (!text && !_pendingImage && !_pendingFile) return;
|
|
@@ -2643,7 +2701,8 @@
|
|
|
2643
2701
|
? `用户上传了一个临时文件用于本次分析(不在项目文件树里),路径是 ${filePath}(原文件名 ${fileName}),请用合适的工具(如 Read)读取并分析它。用户的要求是:${userText || '分析这个文件'}`
|
|
2644
2702
|
: text;
|
|
2645
2703
|
socket.emit('agent:query', { prompt });
|
|
2646
|
-
|
|
2704
|
+
// 本地 slash(/model /clear /plan /resume /rename)只回一条 info、无 result,不进 thinking 态
|
|
2705
|
+
if (!LOCAL_SLASH_RE.test(text)) showThinking();
|
|
2647
2706
|
} else {
|
|
2648
2707
|
const attach = imgPath || filePath;
|
|
2649
2708
|
const input = attach
|
|
@@ -3402,7 +3461,7 @@
|
|
|
3402
3461
|
// 用【别名】而非硬编码全名:/model sonnet 永远指向该家族最新版,claude 升级不用改这里。
|
|
3403
3462
|
// 精确版本/冷门模型用面板底部「自定义模型」输入框指定全名(如 claude-sonnet-4-6)。
|
|
3404
3463
|
const MODELS = [
|
|
3405
|
-
{ id: 'default', label: '默认', desc: '
|
|
3464
|
+
{ id: 'default', label: '默认', desc: '跟随账户/订阅设置' },
|
|
3406
3465
|
{ id: 'sonnet', label: 'Sonnet', desc: '速度+智能平衡 · 跟随最新版' },
|
|
3407
3466
|
{ id: 'opus', label: 'Opus', desc: '最强推理 · agentic coding · 跟随最新版' },
|
|
3408
3467
|
{ id: 'haiku', label: 'Haiku', desc: '最快最便宜 · 跟随最新版' },
|
|
@@ -3704,6 +3763,8 @@
|
|
|
3704
3763
|
if (!isController && canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID });
|
|
3705
3764
|
socket.emit('agent:query', { prompt: '/clear' });
|
|
3706
3765
|
addStatusMessage('已清除对话和 Claude 上下文');
|
|
3766
|
+
_ctxNudgeLevel = 0;
|
|
3767
|
+
ctxUpdate(0); // 上下文已清空,水位指示复位
|
|
3707
3768
|
} else {
|
|
3708
3769
|
addStatusMessage('聊天记录已清除');
|
|
3709
3770
|
}
|
|
@@ -4323,7 +4384,8 @@
|
|
|
4323
4384
|
if (!isController && canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID });
|
|
4324
4385
|
socket.emit('agent:query', { prompt: prompt_text });
|
|
4325
4386
|
addInputMessage(prompt_text);
|
|
4326
|
-
|
|
4387
|
+
// 本地 slash(/plan /resume /rename)只回一条 info、无 result,不进 thinking 态
|
|
4388
|
+
if (!LOCAL_SLASH_RE.test(prompt_text)) showThinking();
|
|
4327
4389
|
};
|
|
4328
4390
|
// Enter 键提交
|
|
4329
4391
|
document.getElementById('slash-input')?.addEventListener('keydown', (e) => {
|
package/dist/grid.html
CHANGED
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
// ── 新建任务(和首页「新建终端会话」一致:预设 + 名称 + 命令 + 目录 + 最近目录)──
|
|
313
313
|
const socket = io();
|
|
314
314
|
const NT_PRESETS = [
|
|
315
|
-
{ icon:'🤖', label:'
|
|
315
|
+
{ icon:'🤖', label:'默认', title:'claude', type:'agent', cmd:'' },
|
|
316
316
|
{ icon:'🐚', label:'Shell', title:'shell', type:'pty', cmd:'' },
|
|
317
317
|
];
|
|
318
318
|
let _ntPreset = 0;
|
package/dist/index.html
CHANGED
|
@@ -650,7 +650,7 @@
|
|
|
650
650
|
const H = 'style="font-size:0.9rem;font-weight:700;margin-bottom:0.5rem;color:var(--text)"';
|
|
651
651
|
const T = 'style="font-size:0.82rem;color:var(--text2);line-height:1.6"';
|
|
652
652
|
let html = '<div style="padding:1.5rem">';
|
|
653
|
-
html += '<h3 style="margin:0 0 1.2rem;font-size:1.1rem;color:#fff;text-align:center"
|
|
653
|
+
html += '<h3 style="margin:0 0 1.2rem;font-size:1.1rem;color:#fff;text-align:center">用量</h3>';
|
|
654
654
|
if (data.rateLimit) {
|
|
655
655
|
const rl = data.rateLimit;
|
|
656
656
|
const resetTime = new Date(rl.resetsAt * 1000);
|
|
@@ -1184,7 +1184,7 @@
|
|
|
1184
1184
|
// ── Presets ───────────────────────────────────────────────────
|
|
1185
1185
|
const PRESETS = [
|
|
1186
1186
|
// Agent 模式
|
|
1187
|
-
{ icon: '🤖', label: '
|
|
1187
|
+
{ icon: '🤖', label: '默认', title: 'claude', type: 'agent', cmd: 'claude' },
|
|
1188
1188
|
// PTY 模式(终端)
|
|
1189
1189
|
{ icon: '🐚', label: 'Shell', title: 'shell', type: 'pty', cmd: '' },
|
|
1190
1190
|
];
|