mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-23 07:51:33 +00:00
* feat(feishu): add ACP session support * fix(feishu): preserve sender-scoped ACP rebinding * fix(feishu): recover sender scope from bound ACP sessions * fix(feishu): support DM ACP binding placement * feat(feishu): add current-conversation session binding * fix(feishu): avoid DM parent binding fallback * fix(feishu): require canonical topic sender ids * fix(feishu): honor sender-scoped ACP bindings * fix(feishu): allow user-id ACP DM bindings * fix(feishu): recover user-id ACP DM bindings
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
import { beforeEach, describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../../../src/config/config.js";
|
|
import { getSessionBindingService } from "../../../src/infra/outbound/session-binding-service.js";
|
|
import { __testing, createFeishuThreadBindingManager } from "./thread-bindings.js";
|
|
|
|
const baseCfg = {
|
|
session: { mainKey: "main", scope: "per-sender" },
|
|
} satisfies OpenClawConfig;
|
|
|
|
describe("Feishu thread bindings", () => {
|
|
beforeEach(() => {
|
|
__testing.resetFeishuThreadBindingsForTests();
|
|
});
|
|
|
|
it("registers current-placement adapter capabilities for Feishu", () => {
|
|
createFeishuThreadBindingManager({ cfg: baseCfg, accountId: "default" });
|
|
|
|
expect(
|
|
getSessionBindingService().getCapabilities({
|
|
channel: "feishu",
|
|
accountId: "default",
|
|
}),
|
|
).toEqual({
|
|
adapterAvailable: true,
|
|
bindSupported: true,
|
|
unbindSupported: true,
|
|
placements: ["current"],
|
|
});
|
|
});
|
|
|
|
it("binds and resolves a Feishu topic conversation", async () => {
|
|
createFeishuThreadBindingManager({ cfg: baseCfg, accountId: "default" });
|
|
|
|
const binding = await getSessionBindingService().bind({
|
|
targetSessionKey: "agent:codex:acp:binding:feishu:default:abc123",
|
|
targetKind: "session",
|
|
conversation: {
|
|
channel: "feishu",
|
|
accountId: "default",
|
|
conversationId: "oc_group_chat:topic:om_topic_root",
|
|
parentConversationId: "oc_group_chat",
|
|
},
|
|
placement: "current",
|
|
metadata: {
|
|
agentId: "codex",
|
|
label: "codex-main",
|
|
},
|
|
});
|
|
|
|
expect(binding.conversation.conversationId).toBe("oc_group_chat:topic:om_topic_root");
|
|
expect(
|
|
getSessionBindingService().resolveByConversation({
|
|
channel: "feishu",
|
|
accountId: "default",
|
|
conversationId: "oc_group_chat:topic:om_topic_root",
|
|
}),
|
|
)?.toMatchObject({
|
|
targetSessionKey: "agent:codex:acp:binding:feishu:default:abc123",
|
|
metadata: expect.objectContaining({
|
|
agentId: "codex",
|
|
label: "codex-main",
|
|
}),
|
|
});
|
|
});
|
|
|
|
it("clears account-scoped bindings when the manager stops", async () => {
|
|
const manager = createFeishuThreadBindingManager({ cfg: baseCfg, accountId: "default" });
|
|
|
|
await getSessionBindingService().bind({
|
|
targetSessionKey: "agent:codex:acp:binding:feishu:default:abc123",
|
|
targetKind: "session",
|
|
conversation: {
|
|
channel: "feishu",
|
|
accountId: "default",
|
|
conversationId: "oc_group_chat:topic:om_topic_root",
|
|
parentConversationId: "oc_group_chat",
|
|
},
|
|
placement: "current",
|
|
metadata: {
|
|
agentId: "codex",
|
|
},
|
|
});
|
|
|
|
manager.stop();
|
|
|
|
expect(
|
|
getSessionBindingService().resolveByConversation({
|
|
channel: "feishu",
|
|
accountId: "default",
|
|
conversationId: "oc_group_chat:topic:om_topic_root",
|
|
}),
|
|
).toBeNull();
|
|
});
|
|
});
|