mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 00:19:33 +00:00
Discord: thread bindings idle + max-age lifecycle (#27845) (thanks @osolmaz)
* refactor discord thread bindings to idle and max-age lifecycle * fix: migrate legacy thread binding expiry and reduce hot-path disk writes * refactor: remove remaining thread-binding ttl legacy paths * fix: harden thread-binding lifecycle persistence * Discord: fix thread binding types in message/reply paths * Infra: handle win32 unknown inode in file identity checks * Infra: relax win32 guarded-open identity checks * Config: migrate threadBindings ttlHours to idleHours * Revert "Infra: relax win32 guarded-open identity checks" This reverts commitde94126771. * Revert "Infra: handle win32 unknown inode in file identity checks" This reverts commit96fc5ddfb3. * Discord: re-read live binding state before sweep unbind * fix: add changelog note for thread binding lifecycle update (#27845) (thanks @osolmaz) --------- Co-authored-by: Onur Solmaz <onur@textcortex.com>
This commit is contained in:
146
src/config/thread-bindings-config-keys.test.ts
Normal file
146
src/config/thread-bindings-config-keys.test.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { migrateLegacyConfig } from "./legacy-migrate.js";
|
||||
import { validateConfigObjectRaw } from "./validation.js";
|
||||
|
||||
describe("thread binding config keys", () => {
|
||||
it("rejects legacy session.threadBindings.ttlHours", () => {
|
||||
const result = validateConfigObjectRaw({
|
||||
session: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
if (result.ok) {
|
||||
return;
|
||||
}
|
||||
expect(result.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
path: "session.threadBindings",
|
||||
message: expect.stringContaining("ttlHours"),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects legacy channels.discord.threadBindings.ttlHours", () => {
|
||||
const result = validateConfigObjectRaw({
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
if (result.ok) {
|
||||
return;
|
||||
}
|
||||
expect(result.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
path: "channels.discord.threadBindings",
|
||||
message: expect.stringContaining("ttlHours"),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects legacy channels.discord.accounts.<id>.threadBindings.ttlHours", () => {
|
||||
const result = validateConfigObjectRaw({
|
||||
channels: {
|
||||
discord: {
|
||||
accounts: {
|
||||
alpha: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
if (result.ok) {
|
||||
return;
|
||||
}
|
||||
expect(result.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
path: "channels.discord.accounts",
|
||||
message: expect.stringContaining("ttlHours"),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("migrates session.threadBindings.ttlHours to idleHours", () => {
|
||||
const result = migrateLegacyConfig({
|
||||
session: {
|
||||
threadBindings: {
|
||||
ttlHours: 24,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.config?.session?.threadBindings?.idleHours).toBe(24);
|
||||
const normalized = result.config?.session?.threadBindings as
|
||||
| Record<string, unknown>
|
||||
| undefined;
|
||||
expect(normalized?.ttlHours).toBeUndefined();
|
||||
expect(result.changes).toContain(
|
||||
"Moved session.threadBindings.ttlHours → session.threadBindings.idleHours.",
|
||||
);
|
||||
});
|
||||
|
||||
it("migrates Discord threadBindings.ttlHours for root and account entries", () => {
|
||||
const result = migrateLegacyConfig({
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
ttlHours: 12,
|
||||
},
|
||||
accounts: {
|
||||
alpha: {
|
||||
threadBindings: {
|
||||
ttlHours: 6,
|
||||
},
|
||||
},
|
||||
beta: {
|
||||
threadBindings: {
|
||||
idleHours: 4,
|
||||
ttlHours: 9,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const discord = result.config?.channels?.discord;
|
||||
expect(discord?.threadBindings?.idleHours).toBe(12);
|
||||
expect(
|
||||
(discord?.threadBindings as Record<string, unknown> | undefined)?.ttlHours,
|
||||
).toBeUndefined();
|
||||
|
||||
expect(discord?.accounts?.alpha?.threadBindings?.idleHours).toBe(6);
|
||||
expect(
|
||||
(discord?.accounts?.alpha?.threadBindings as Record<string, unknown> | undefined)?.ttlHours,
|
||||
).toBeUndefined();
|
||||
|
||||
expect(discord?.accounts?.beta?.threadBindings?.idleHours).toBe(4);
|
||||
expect(
|
||||
(discord?.accounts?.beta?.threadBindings as Record<string, unknown> | undefined)?.ttlHours,
|
||||
).toBeUndefined();
|
||||
|
||||
expect(result.changes).toContain(
|
||||
"Moved channels.discord.threadBindings.ttlHours → channels.discord.threadBindings.idleHours.",
|
||||
);
|
||||
expect(result.changes).toContain(
|
||||
"Moved channels.discord.accounts.alpha.threadBindings.ttlHours → channels.discord.accounts.alpha.threadBindings.idleHours.",
|
||||
);
|
||||
expect(result.changes).toContain(
|
||||
"Removed channels.discord.accounts.beta.threadBindings.ttlHours (channels.discord.accounts.beta.threadBindings.idleHours already set).",
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user