mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
fix(control-ui): preserve loopback client version labels
This commit is contained in:
@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Control UI/Gateway: preserve WebChat client version labels across localhost, 127.0.0.1, and IPv6 loopback aliases on the same port, avoiding misleading `vcontrol-ui` connection logs while investigating duplicate-message reports. Refs #72753 and #72742. Thanks @LumenFromTheFuture and @allesgutefy.
|
||||
- Memory-core: run one-shot memory CLI commands through transient builtin and QMD managers so `memory index`, `memory status --index`, and `memory search` no longer start long-lived file watchers that can hit macOS `EMFILE` limits. Fixes #59101; carries forward #49851. Thanks @mbear469210-coder and @maoyuanxue.
|
||||
- Memory-core: re-resolve the active runtime config whenever `memory_search` or `memory_get` executes, so provider changes made by `config.patch` stop leaving stale embedding backends behind in existing tool instances. Fixes #61098. Thanks @BradGroux and @Linux2010.
|
||||
- WebChat: keep bare `/new` and `/reset` startup instructions out of visible chat history while preserving `/reset <note>` as user-visible transcript text. Fixes #72369. Thanks @collynes and @haishmg.
|
||||
|
||||
@@ -1025,6 +1025,33 @@ describe("resolveControlUiClientVersion", () => {
|
||||
).toBe("2026.3.7");
|
||||
});
|
||||
|
||||
it("returns serverVersion for loopback aliases on the same port", () => {
|
||||
expect(
|
||||
resolveControlUiClientVersion({
|
||||
gatewayUrl: "ws://127.0.0.1:18789",
|
||||
serverVersion: "2026.4.24",
|
||||
pageUrl: "http://localhost:18789/chat",
|
||||
}),
|
||||
).toBe("2026.4.24");
|
||||
expect(
|
||||
resolveControlUiClientVersion({
|
||||
gatewayUrl: "ws://[::1]:18789",
|
||||
serverVersion: "2026.4.24",
|
||||
pageUrl: "http://127.0.0.1:18789/chat",
|
||||
}),
|
||||
).toBe("2026.4.24");
|
||||
});
|
||||
|
||||
it("omits serverVersion for loopback aliases on different ports", () => {
|
||||
expect(
|
||||
resolveControlUiClientVersion({
|
||||
gatewayUrl: "ws://127.0.0.1:18789",
|
||||
serverVersion: "2026.4.24",
|
||||
pageUrl: "http://localhost:19889/chat",
|
||||
}),
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it("omits serverVersion for cross-origin targets", () => {
|
||||
expect(
|
||||
resolveControlUiClientVersion({
|
||||
|
||||
@@ -265,7 +265,7 @@ export function resolveControlUiClientVersion(params: {
|
||||
const page = new URL(pageUrl);
|
||||
const gateway = new URL(params.gatewayUrl, page);
|
||||
const allowedProtocols = new Set(["ws:", "wss:", "http:", "https:"]);
|
||||
if (!allowedProtocols.has(gateway.protocol) || gateway.host !== page.host) {
|
||||
if (!allowedProtocols.has(gateway.protocol) || !isSameControlUiVersionEndpoint(page, gateway)) {
|
||||
return undefined;
|
||||
}
|
||||
return serverVersion;
|
||||
@@ -274,6 +274,44 @@ export function resolveControlUiClientVersion(params: {
|
||||
}
|
||||
}
|
||||
|
||||
function isSameControlUiVersionEndpoint(page: URL, gateway: URL): boolean {
|
||||
if (gateway.host === page.host) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
isLoopbackHostname(page.hostname) &&
|
||||
isLoopbackHostname(gateway.hostname) &&
|
||||
resolveUrlEffectivePort(page) === resolveUrlEffectivePort(gateway)
|
||||
);
|
||||
}
|
||||
|
||||
function isLoopbackHostname(hostname: string): boolean {
|
||||
const normalized = hostname.trim().toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
|
||||
return (
|
||||
normalized === "localhost" ||
|
||||
normalized === "::1" ||
|
||||
normalized === "0:0:0:0:0:0:0:1" ||
|
||||
normalized === "127.0.0.1" ||
|
||||
normalized.startsWith("127.")
|
||||
);
|
||||
}
|
||||
|
||||
function resolveUrlEffectivePort(url: URL): string {
|
||||
if (url.port) {
|
||||
return url.port;
|
||||
}
|
||||
switch (url.protocol) {
|
||||
case "http:":
|
||||
case "ws:":
|
||||
return "80";
|
||||
case "https:":
|
||||
case "wss:":
|
||||
return "443";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeSessionKeyForDefaults(
|
||||
value: string | undefined,
|
||||
defaults: SessionDefaultsSnapshot,
|
||||
|
||||
Reference in New Issue
Block a user