feat: v2.5.5 — AI Router renamed AI Proxy, reload onto new builds, update no longer spins
AI Proxy (was AI Router): - server/lib/ai-proxies.js, proxy-apply.js, routes/ai-proxies.js mounted at /api/ai-proxies and the old /api/ai-routers; `router` still accepted on the start routes; profiles move to <CLAUDE_HOME>/agenthub-proxies/ - dashboard_runs.router renamed in place to proxy: an older build on the same DB fails on that column, so dev and prod sharing one DB update together - a proxy's baseUrl stored as its root (a typed /v1 made /v1/v1/messages); Test probes Claude /v1/messages and Codex /v1/responses - Settings → AI Proxy (/settings/ai-router redirects), ProxyPicker Updates: - every tab reloads onto the new UI build when its WebSocket reconnects to a server of another version (lib/newBuildReload.ts, once per version) - Update now stops waiting on a plugin chain that failed or pulled nothing (the old server never goes down), and reloads as soon as a new version answers Also: - a pane whose command exits at once says so (EPANEEXITED) instead of "Command failed: tmux set-option … mouse on" - the pane drag preview draws where the pane actually lands
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file newBuildReload.ts
|
||||
* @description Reloads the tab onto the new UI build after the server was
|
||||
* updated. Every update — the dashboard's own Update button in any tab,
|
||||
* `/agenthub-update`, a restart onto a newer plugin — drops the WebSocket; when
|
||||
* it comes back, `GET /api/health` names the server's version, and a version
|
||||
* other than this bundle's `__APP_VERSION__` means the page is stale. At most
|
||||
* one reload per version (sessionStorage), so a server whose UI build failed
|
||||
* cannot make the tab reload on every reconnect.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
import { eventBus } from "./eventBus";
|
||||
|
||||
const KEY = "agenthub.reloadedFor";
|
||||
|
||||
export function reloadOnNewBuild({
|
||||
bundle = __APP_VERSION__,
|
||||
health = () => fetch("/api/health").then((r) => r.json() as Promise<{ version?: string }>),
|
||||
reload = () => window.location.reload(),
|
||||
storage = window.sessionStorage,
|
||||
}: {
|
||||
bundle?: string;
|
||||
health?: () => Promise<{ version?: string }>;
|
||||
reload?: () => void;
|
||||
storage?: Pick<Storage, "getItem" | "setItem">;
|
||||
} = {}): () => void {
|
||||
let wasDown = false;
|
||||
return eventBus.onConnection((up) => {
|
||||
if (!up) {
|
||||
wasDown = true;
|
||||
return;
|
||||
}
|
||||
if (!wasDown) return;
|
||||
wasDown = false;
|
||||
health()
|
||||
.then(({ version }) => {
|
||||
if (!version || version === bundle || storage.getItem(KEY) === version) return;
|
||||
storage.setItem(KEY, version);
|
||||
reload();
|
||||
})
|
||||
.catch(() => {
|
||||
/* the next reconnect asks again */
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user