oclaw/openclaw/test/helpers/channels/session-binding-registry-backed-contract.ts
oliver dbbe3add6a 重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。

Made-with: Cursor
2026-04-26 08:34:33 +08:00

88 lines
3.4 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
clearRuntimeConfigSnapshot,
setRuntimeConfigSnapshot,
} from "../../../src/config/config.js";
import {
__testing as sessionBindingTesting,
type SessionBindingCapabilities,
type SessionBindingRecord,
} from "../../../src/infra/outbound/session-binding-service.js";
import { resetPluginRuntimeStateForTest } from "../../../src/plugins/runtime.js";
import { getSessionBindingContractRegistry } from "./registry-session-binding.js";
function resolveSessionBindingContractRuntimeConfig(id: string) {
if (id !== "discord" && id !== "matrix") {
return {};
}
return {
plugins: {
entries: {
[id]: {
enabled: true,
},
},
},
};
}
function installSessionBindingContractSuite(params: {
getCapabilities: () => SessionBindingCapabilities | Promise<SessionBindingCapabilities>;
bindAndResolve: () => Promise<SessionBindingRecord>;
unbindAndVerify: (binding: SessionBindingRecord) => Promise<void>;
cleanup: () => Promise<void> | void;
expectedCapabilities: SessionBindingCapabilities;
}) {
it("registers, binds, unbinds, and cleans up session bindings", async () => {
expect(await Promise.resolve(params.getCapabilities())).toEqual(params.expectedCapabilities);
const binding = await params.bindAndResolve();
try {
expect(typeof binding.bindingId).toBe("string");
expect(binding.bindingId.trim()).not.toBe("");
expect(typeof binding.targetSessionKey).toBe("string");
expect(binding.targetSessionKey.trim()).not.toBe("");
expect(["session", "subagent"]).toContain(binding.targetKind);
expect(typeof binding.conversation.channel).toBe("string");
expect(typeof binding.conversation.accountId).toBe("string");
expect(typeof binding.conversation.conversationId).toBe("string");
expect(["active", "ending", "ended"]).toContain(binding.status);
expect(typeof binding.boundAt).toBe("number");
await params.unbindAndVerify(binding);
} finally {
await params.cleanup();
}
});
}
export function describeSessionBindingRegistryBackedContract(id: string) {
const entry = getSessionBindingContractRegistry().find((item) => item.id === id);
if (!entry) {
throw new Error(`missing session binding contract entry for ${id}`);
}
describe(`${entry.id} session binding contract`, () => {
beforeEach(async () => {
resetPluginRuntimeStateForTest();
clearRuntimeConfigSnapshot();
// Keep the suite hermetic; some contract helpers resolve runtime artifacts through config-aware
// plugin boundaries, so never fall back to the developer's real ~/.openclaw/openclaw.json here.
const runtimeConfig = resolveSessionBindingContractRuntimeConfig(entry.id);
// These registry-backed contract suites intentionally exercise bundled runtime facades.
// Opt the bundled-runtime cases in so the activation boundary behaves like real runtime usage.
setRuntimeConfigSnapshot(runtimeConfig);
sessionBindingTesting.resetSessionBindingAdaptersForTests();
await entry.beforeEach?.();
});
afterEach(() => {
clearRuntimeConfigSnapshot();
});
installSessionBindingContractSuite({
expectedCapabilities: entry.expectedCapabilities,
getCapabilities: entry.getCapabilities,
bindAndResolve: entry.bindAndResolve,
unbindAndVerify: entry.unbindAndVerify,
cleanup: entry.cleanup,
});
});
}