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 commit de94126771.

* Revert "Infra: handle win32 unknown inode in file identity checks"

This reverts commit 96fc5ddfb3.

* 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:
Onur Solmaz
2026-02-27 10:02:39 +01:00
committed by GitHub
parent 0fb7add7d6
commit a7929abad8
45 changed files with 1656 additions and 402 deletions

View File

@@ -1,21 +1,39 @@
import {
resolveThreadBindingSessionTtlMs,
resolveThreadBindingIdleTimeoutMs,
resolveThreadBindingMaxAgeMs,
resolveThreadBindingsEnabled,
} from "../../channels/thread-bindings-policy.js";
import type { OpenClawConfig } from "../../config/config.js";
import { normalizeAccountId } from "../../routing/session-key.js";
export { resolveThreadBindingSessionTtlMs, resolveThreadBindingsEnabled };
export {
resolveThreadBindingIdleTimeoutMs,
resolveThreadBindingMaxAgeMs,
resolveThreadBindingsEnabled,
};
export function resolveDiscordThreadBindingSessionTtlMs(params: {
export function resolveDiscordThreadBindingIdleTimeoutMs(params: {
cfg: OpenClawConfig;
accountId?: string;
}): number {
const accountId = normalizeAccountId(params.accountId);
const root = params.cfg.channels?.discord?.threadBindings;
const account = params.cfg.channels?.discord?.accounts?.[accountId]?.threadBindings;
return resolveThreadBindingSessionTtlMs({
channelTtlHoursRaw: account?.ttlHours ?? root?.ttlHours,
sessionTtlHoursRaw: params.cfg.session?.threadBindings?.ttlHours,
return resolveThreadBindingIdleTimeoutMs({
channelIdleHoursRaw: account?.idleHours ?? root?.idleHours,
sessionIdleHoursRaw: params.cfg.session?.threadBindings?.idleHours,
});
}
export function resolveDiscordThreadBindingMaxAgeMs(params: {
cfg: OpenClawConfig;
accountId?: string;
}): number {
const accountId = normalizeAccountId(params.accountId);
const root = params.cfg.channels?.discord?.threadBindings;
const account = params.cfg.channels?.discord?.accounts?.[accountId]?.threadBindings;
return resolveThreadBindingMaxAgeMs({
channelMaxAgeHoursRaw: account?.maxAgeHours ?? root?.maxAgeHours,
sessionMaxAgeHoursRaw: params.cfg.session?.threadBindings?.maxAgeHours,
});
}