Files
AgentHub/client/src/lib/__tests__/newBuildReload.test.ts
T
nntrivi2001 5fe5d51b1b 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
2026-10-06 22:48:09 +07:00

59 lines
1.8 KiB
TypeScript

/**
* @file Tests for newBuildReload: after a reconnect the tab reloads once when
* the server's version is not this bundle's, never on the first connect,
* never for the same version, and not twice for one version.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
import { afterEach, describe, expect, it, vi } from "vitest";
import { eventBus } from "../eventBus";
import { reloadOnNewBuild } from "../newBuildReload";
const flush = () => new Promise((r) => setTimeout(r, 0));
function setup(serverVersion: string) {
const reload = vi.fn();
const store = new Map<string, string>();
const storage = {
getItem: (k: string) => store.get(k) ?? null,
setItem: (k: string, v: string) => void store.set(k, v),
};
const off = reloadOnNewBuild({
bundle: "2.5.4",
health: () => Promise.resolve({ version: serverVersion }),
reload,
storage,
});
return { reload, off };
}
let off: (() => void) | undefined;
afterEach(() => off?.());
describe("reloadOnNewBuild", () => {
it("reloads once after a reconnect onto a new version", async () => {
const s = setup("2.5.5");
off = s.off;
eventBus.setConnected(true); // first connect: nothing to compare against yet
await flush();
expect(s.reload).not.toHaveBeenCalled();
eventBus.setConnected(false);
eventBus.setConnected(true);
await flush();
expect(s.reload).toHaveBeenCalledTimes(1);
eventBus.setConnected(false); // same version again: a failed UI build must not loop
eventBus.setConnected(true);
await flush();
expect(s.reload).toHaveBeenCalledTimes(1);
});
it("stays put when the server is this bundle's version", async () => {
const s = setup("2.5.4");
off = s.off;
eventBus.setConnected(false);
eventBus.setConnected(true);
await flush();
expect(s.reload).not.toHaveBeenCalled();
});
});