refactor(channels): share route format and binding helpers

This commit is contained in:
Vincent Koc
2026-03-20 09:29:58 -07:00
parent faa9faa767
commit 9b6f286ac2
12 changed files with 217 additions and 306 deletions

View File

@@ -1,4 +1,5 @@
import MarkdownIt from "markdown-it";
import { isAutoLinkedFileRef } from "openclaw/plugin-sdk/text-runtime";
const md = new MarkdownIt({
html: false,
@@ -10,38 +11,6 @@ const md = new MarkdownIt({
md.enable("strikethrough");
const { escapeHtml } = md.utils;
/**
* Keep bare file references like README.md from becoming external http:// links.
* Telegram already hardens this path; Matrix should not turn common code/docs
* filenames into clickable registrar-style URLs either.
*/
const FILE_EXTENSIONS_WITH_TLD = new Set(["md", "go", "py", "pl", "sh", "am", "at", "be", "cc"]);
function isAutoLinkedFileRef(href: string, label: string): boolean {
const stripped = href.replace(/^https?:\/\//i, "");
if (stripped !== label) {
return false;
}
const dotIndex = label.lastIndexOf(".");
if (dotIndex < 1) {
return false;
}
const ext = label.slice(dotIndex + 1).toLowerCase();
if (!FILE_EXTENSIONS_WITH_TLD.has(ext)) {
return false;
}
const segments = label.split("/");
if (segments.length > 1) {
for (let i = 0; i < segments.length - 1; i += 1) {
if (segments[i]?.includes(".")) {
return false;
}
}
}
return true;
}
function shouldSuppressAutoLink(
tokens: Parameters<NonNullable<typeof md.renderer.rules.link_open>>[0],
idx: number,

View File

@@ -1,3 +1,4 @@
import { resolveThreadBindingLifecycle } from "openclaw/plugin-sdk/channel-runtime";
import type {
BindingTargetKind,
SessionBindingRecord,
@@ -74,32 +75,7 @@ export function resolveEffectiveBindingExpiry(params: {
expiresAt?: number;
reason?: "idle-expired" | "max-age-expired";
} {
const idleTimeoutMs =
typeof params.record.idleTimeoutMs === "number"
? Math.max(0, Math.floor(params.record.idleTimeoutMs))
: params.defaultIdleTimeoutMs;
const maxAgeMs =
typeof params.record.maxAgeMs === "number"
? Math.max(0, Math.floor(params.record.maxAgeMs))
: params.defaultMaxAgeMs;
const inactivityExpiresAt =
idleTimeoutMs > 0
? Math.max(params.record.lastActivityAt, params.record.boundAt) + idleTimeoutMs
: undefined;
const maxAgeExpiresAt = maxAgeMs > 0 ? params.record.boundAt + maxAgeMs : undefined;
if (inactivityExpiresAt != null && maxAgeExpiresAt != null) {
return inactivityExpiresAt <= maxAgeExpiresAt
? { expiresAt: inactivityExpiresAt, reason: "idle-expired" }
: { expiresAt: maxAgeExpiresAt, reason: "max-age-expired" };
}
if (inactivityExpiresAt != null) {
return { expiresAt: inactivityExpiresAt, reason: "idle-expired" };
}
if (maxAgeExpiresAt != null) {
return { expiresAt: maxAgeExpiresAt, reason: "max-age-expired" };
}
return {};
return resolveThreadBindingLifecycle(params);
}
export function toSessionBindingRecord(