diff --git a/lib/host.js b/lib/host.js index b6c249a..015e9f0 100644 --- a/lib/host.js +++ b/lib/host.js @@ -330,7 +330,7 @@ export function apply(ctx, config) { const denom = input + read if (denom > 0) out.cacheHit = read / denom } - let capacity = contextWindows.get(id) || modelContext() + let capacity = contextWindows.get(id) || modelContext() || 1000000 // 兜底:DSH 常用 1M 上下文 const used = m.surfaceTokens ?? m.totalTokens if (capacity && used) out.contextUsed = Math.min(1, used / capacity) } diff --git a/shell/float-window.ps1 b/shell/float-window.ps1 index 022cdf1..ea1877f 100644 --- a/shell/float-window.ps1 +++ b/shell/float-window.ps1 @@ -69,7 +69,11 @@ $commandFile = Join-Path $stateDir 'command.json' $aliveFile = Join-Path $stateDir 'alive.json' # 文件桥:插件每秒写 snapshot.json(桌面壳 HTTP 网关 403,浮窗只能走文件) $snapshotFile = Join-Path $DshHome 'float-window\snapshot.json' +$bridgeSnapshotFile = Join-Path $DshHome 'float-window\snapshot-bridge.json' $outboxFile = Join-Path $DshHome 'float-window\outbox.json' +$watchFile = Join-Path $DshHome 'float-window\watch.json' +# 独立镜像桥:直接读会话日志/投影缓存(DSH 还没重启、插件没在写快照时的兜底数据源) +$bridgeScript = Join-Path (Split-Path $PSScriptRoot -Parent) 'tools\mirror-bridge.mjs' if ($alreadyRunning) { if ($Action) { try { @@ -387,7 +391,13 @@ $onWebMessage = { 'scale' { $script:state.scale = [double]$m.value; $wv.ZoomFactor = [double]$m.value; Save-State; Push-State } 'reload' { $wv.Reload() } 'chat' { Write-Outbox @{ cmd = 'chat'; text = [string]$m.text } } - 'watch' { Write-Outbox @{ cmd = 'watch'; sessionId = [string]$m.sessionId } } + 'watch' { + Write-Outbox @{ cmd = 'watch'; sessionId = [string]$m.sessionId } + # 镜像桥也跟随同一个选择 + try { + [System.IO.File]::WriteAllText($watchFile, (@{ sessionId = [string]$m.sessionId } | ConvertTo-Json -Compress), (New-Object System.Text.UTF8Encoding($false))) + } catch { } + } 'newSession' { Write-Outbox @{ cmd = 'session'; action = 'create' } } 'openExternal' { if ($m.url -match '^https?://') { Start-Process $m.url } } } @@ -427,7 +437,28 @@ $timer.Add_Tick({ $s = [System.IO.File]::ReadAllText($snapshotFile, [System.Text.Encoding]::UTF8) if ($s -and $s -ne $script:lastSnapshotText) { $script:lastSnapshotText = $s - Send-ToPage @{ type = 'snapshot'; data = ($s | ConvertFrom-Json) } + $snap = $s | ConvertFrom-Json + # 用镜像桥的兜底快照补齐插件缺的字段(token/上下文估算、标题) + try { + if (Test-Path $bridgeSnapshotFile) { + $bs = [System.IO.File]::ReadAllText($bridgeSnapshotFile, [System.Text.Encoding]::UTF8) | ConvertFrom-Json + if ($bs -and $bs.sessionId -eq $snap.sessionId) { + if ($null -eq $snap.metrics.contextUsed) { $snap.metrics.contextUsed = $bs.metrics.contextUsed } + if ($null -eq $snap.metrics.tokens) { $snap.metrics.tokens = $bs.metrics.tokens } + if ($null -eq $snap.metrics.cacheHit) { $snap.metrics.cacheHit = $bs.metrics.cacheHit } + if ($null -eq $snap.metrics.tps -and $bs.metrics.tps) { $snap.metrics.tps = $bs.metrics.tps } + if (-not $snap.title -and $bs.title) { $snap.title = $bs.title } + if ($bs.approx) { $snap.approx = $true } + } + } + } catch { } + Send-ToPage @{ type = 'snapshot'; data = $snap } + # 每 ~5 秒记一行,用来确认数据真的到了页面 + $now = Get-Date + if (-not $script:lastSnapLog -or ($now - $script:lastSnapLog).TotalSeconds -gt 5) { + $script:lastSnapLog = $now + Log "snapshot -> page: src=$($snap.source) rows=$(@($snap.messages).Count) turns=$($snap.metrics.turns) steps=$($snap.metrics.steps) tok=$($snap.metrics.tokens) ctx=$($snap.metrics.contextUsed) approx=$($snap.approx)" + } } } } catch { Log "snapshot error: $($_.Exception.Message)" } @@ -471,6 +502,16 @@ $onWvReady = { $wv.add_CoreWebView2InitializationCompleted($onWvReady) $form.Add_Shown({ Log 'form shown' + # 独立镜像桥:以隐藏窗口跑起来(DSH 没重启时也能出镜像与指标) + try { + if (Test-Path $bridgeScript) { + $nodeExe = (Get-Command node -ErrorAction SilentlyContinue).Source + if ($nodeExe) { + $script:bridge = Start-Process -FilePath $nodeExe -ArgumentList @("`"$bridgeScript`"", '--home', "`"$DshHome`"", '--quiet') -WindowStyle Hidden -PassThru + Log "mirror bridge pid=$($script:bridge.Id)" + } else { Log 'node not found; mirror bridge skipped' } + } else { Log "bridge script missing: $bridgeScript" } + } catch { Log "bridge start failed: $($_.Exception.Message)" } $form.AllowResize = -not $script:state.sizeLock try { $udf = Join-Path $stateDir 'webview2' @@ -489,7 +530,10 @@ $form.Add_Shown({ $form.Add_ResizeEnd({ if (-not $script:state.fullscreen) { $script:state.w = $form.Width; $script:state.h = $form.Height; Save-State; Push-State } }) $form.Add_Move({ if (-not $script:state.fullscreen -and $form.WindowState -eq 'Normal') { $script:state.x = $form.Left; $script:state.y = $form.Top } }) -$form.Add_FormClosing({ Save-State }) +$form.Add_FormClosing({ + Save-State + try { if ($script:bridge -and -not $script:bridge.HasExited) { $script:bridge.Kill() } } catch { } + }) $form.Add_KeyDown({ param($s, $e) if ($e.KeyCode -eq [System.Windows.Forms.Keys]::F11) { Toggle-Fullscreen } diff --git a/shell/ui.html b/shell/ui.html index 2dfcec8..6a3a940 100644 --- a/shell/ui.html +++ b/shell/ui.html @@ -539,8 +539,7 @@
-
DSH 悬浮窗未连接
-