mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 03:11:10 +00:00
* ACPX: keep plugin-local runtime installs out of dist * Gateway: harden ACP startup and service PATH * ACP: reinitialize error-state configured bindings * ACP: classify pre-turn runtime failures as session init failures * Plugins: move configured ACP routing behind channel seams * Telegram tests: align startup probe assertions after rebase * Discord: harden ACP configured binding recovery * ACP: recover Discord bindings after stale runtime exits * ACPX: replace dead sessions during ensure * Discord: harden ACP binding recovery * Discord: fix review follow-ups * ACP bindings: load channel snapshots across workspaces * ACP bindings: cache snapshot channel plugin resolution * Experiments: add ACP pluginification holy grail plan * Experiments: rename ACP pluginification plan doc * Experiments: drop old ACP pluginification doc path * ACP: move configured bindings behind plugin services * Experiments: update bindings capability architecture plan * Bindings: isolate configured binding routing and targets * Discord tests: fix runtime env helper path * Tests: fix channel binding CI regressions * Tests: normalize ACP workspace assertion on Windows * Bindings: isolate configured binding registry * Bindings: finish configured binding cleanup * Bindings: finish generic cleanup * Bindings: align runtime approval callbacks * ACP: delete residual bindings barrel * Bindings: restore legacy compatibility * Revert "Bindings: restore legacy compatibility" This reverts commit ac2ed68fa2426ecc874d68278c71c71ad363fcfe. * Tests: drop ACP route legacy helper names * Discord/ACP: fix binding regressions --------- Co-authored-by: Onur <2453968+osolmaz@users.noreply.github.com>
101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { importFreshModule } from "../../test/helpers/import-fresh.js";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
|
|
const managerMocks = vi.hoisted(() => ({
|
|
closeSession: vi.fn(),
|
|
initializeSession: vi.fn(),
|
|
updateSessionRuntimeOptions: vi.fn(),
|
|
}));
|
|
|
|
const sessionMetaMocks = vi.hoisted(() => ({
|
|
readAcpSessionEntry: vi.fn(),
|
|
}));
|
|
|
|
const resolveMocks = vi.hoisted(() => ({
|
|
resolveConfiguredAcpBindingSpecBySessionKey: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("./control-plane/manager.js", () => ({
|
|
getAcpSessionManager: () => ({
|
|
closeSession: managerMocks.closeSession,
|
|
initializeSession: managerMocks.initializeSession,
|
|
updateSessionRuntimeOptions: managerMocks.updateSessionRuntimeOptions,
|
|
}),
|
|
}));
|
|
|
|
vi.mock("./runtime/session-meta.js", () => ({
|
|
readAcpSessionEntry: sessionMetaMocks.readAcpSessionEntry,
|
|
}));
|
|
|
|
vi.mock("./persistent-bindings.resolve.js", () => ({
|
|
resolveConfiguredAcpBindingSpecBySessionKey:
|
|
resolveMocks.resolveConfiguredAcpBindingSpecBySessionKey,
|
|
}));
|
|
type BindingTargetsModule = typeof import("../channels/plugins/binding-targets.js");
|
|
let bindingTargets: BindingTargetsModule;
|
|
let bindingTargetsImportScope = 0;
|
|
|
|
const baseCfg = {
|
|
session: { mainKey: "main", scope: "per-sender" },
|
|
agents: {
|
|
list: [{ id: "codex" }, { id: "claude" }],
|
|
},
|
|
} satisfies OpenClawConfig;
|
|
|
|
beforeEach(async () => {
|
|
vi.resetModules();
|
|
bindingTargetsImportScope += 1;
|
|
bindingTargets = await importFreshModule<BindingTargetsModule>(
|
|
import.meta.url,
|
|
`../channels/plugins/binding-targets.js?scope=${bindingTargetsImportScope}`,
|
|
);
|
|
managerMocks.closeSession.mockReset().mockResolvedValue({
|
|
runtimeClosed: true,
|
|
metaCleared: false,
|
|
});
|
|
managerMocks.initializeSession.mockReset().mockResolvedValue(undefined);
|
|
managerMocks.updateSessionRuntimeOptions.mockReset().mockResolvedValue(undefined);
|
|
sessionMetaMocks.readAcpSessionEntry.mockReset().mockReturnValue(undefined);
|
|
resolveMocks.resolveConfiguredAcpBindingSpecBySessionKey.mockReset().mockReturnValue(null);
|
|
});
|
|
|
|
describe("resetConfiguredBindingTargetInPlace", () => {
|
|
it("does not resolve configured bindings when ACP metadata already exists", async () => {
|
|
const sessionKey = "agent:claude:acp:binding:discord:default:9373ab192b2317f4";
|
|
sessionMetaMocks.readAcpSessionEntry.mockReturnValue({
|
|
acp: {
|
|
agent: "claude",
|
|
mode: "persistent",
|
|
backend: "acpx",
|
|
runtimeOptions: { cwd: "/home/bob/clawd" },
|
|
},
|
|
});
|
|
resolveMocks.resolveConfiguredAcpBindingSpecBySessionKey.mockImplementation(() => {
|
|
throw new Error("configured binding resolution should be skipped");
|
|
});
|
|
|
|
const result = await bindingTargets.resetConfiguredBindingTargetInPlace({
|
|
cfg: baseCfg,
|
|
sessionKey,
|
|
reason: "reset",
|
|
});
|
|
|
|
expect(result).toEqual({ ok: true });
|
|
expect(resolveMocks.resolveConfiguredAcpBindingSpecBySessionKey).not.toHaveBeenCalled();
|
|
expect(managerMocks.closeSession).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
sessionKey,
|
|
clearMeta: false,
|
|
}),
|
|
);
|
|
expect(managerMocks.initializeSession).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
sessionKey,
|
|
agent: "claude",
|
|
backendId: "acpx",
|
|
}),
|
|
);
|
|
});
|
|
});
|