Plugins: migrate legacy plugin binding records
This commit is contained in:
parent
54fead1508
commit
a81dbf109d
@ -386,4 +386,61 @@ describe("plugin conversation binding approvals", () => {
|
||||
"This conversation is already bound by core routing and cannot be claimed by a plugin.",
|
||||
});
|
||||
});
|
||||
|
||||
it("migrates a legacy plugin binding record through the new approval flow", async () => {
|
||||
sessionBindingState.setRecord({
|
||||
bindingId: "binding-legacy",
|
||||
targetSessionKey: "plugin-binding:codex:legacy123",
|
||||
targetKind: "session",
|
||||
conversation: {
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "-10099:topic:77",
|
||||
},
|
||||
status: "active",
|
||||
boundAt: Date.now(),
|
||||
metadata: {
|
||||
label: "legacy plugin bind",
|
||||
},
|
||||
});
|
||||
|
||||
const request = await requestPluginConversationBinding({
|
||||
pluginId: "codex",
|
||||
pluginName: "Codex App Server",
|
||||
pluginRoot: "/plugins/codex-a",
|
||||
requestedBySenderId: "user-1",
|
||||
conversation: {
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "-10099:topic:77",
|
||||
parentConversationId: "-10099",
|
||||
threadId: "77",
|
||||
},
|
||||
binding: { summary: "Bind this conversation to Codex thread abc." },
|
||||
});
|
||||
|
||||
expect(["pending", "bound"]).toContain(request.status);
|
||||
const binding =
|
||||
request.status === "pending"
|
||||
? await resolvePluginConversationBindingApproval({
|
||||
approvalId: request.approvalId,
|
||||
decision: "allow-once",
|
||||
senderId: "user-1",
|
||||
}).then((approved) => {
|
||||
expect(approved.status).toBe("approved");
|
||||
if (approved.status !== "approved") {
|
||||
throw new Error("expected approved bind result");
|
||||
}
|
||||
return approved.binding;
|
||||
})
|
||||
: request.binding;
|
||||
|
||||
expect(binding).toEqual(
|
||||
expect.objectContaining({
|
||||
pluginId: "codex",
|
||||
pluginRoot: "/plugins/codex-a",
|
||||
conversationId: "-10099:topic:77",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -196,6 +196,23 @@ function buildPluginBindingSessionKey(params: {
|
||||
return `${PLUGIN_BINDING_SESSION_PREFIX}:${params.pluginId}:${hash}`;
|
||||
}
|
||||
|
||||
function isLegacyPluginBindingRecord(params: {
|
||||
record:
|
||||
| {
|
||||
targetSessionKey: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
| null
|
||||
| undefined;
|
||||
pluginId: string;
|
||||
}): boolean {
|
||||
if (!params.record || isPluginOwnedBindingMetadata(params.record.metadata)) {
|
||||
return false;
|
||||
}
|
||||
const targetSessionKey = params.record.targetSessionKey.trim();
|
||||
return targetSessionKey.startsWith(`${PLUGIN_BINDING_SESSION_PREFIX}:${params.pluginId}:`);
|
||||
}
|
||||
|
||||
function buildDiscordButtonRow(
|
||||
approvalId: string,
|
||||
labels?: { once?: string; always?: string; deny?: string },
|
||||
@ -525,12 +542,22 @@ export async function requestPluginConversationBinding(params: {
|
||||
const ref = toConversationRef(conversation);
|
||||
const existing = getSessionBindingService().resolveByConversation(ref);
|
||||
const existingPluginBinding = toPluginConversationBinding(existing);
|
||||
const existingLegacyPluginBinding = isLegacyPluginBindingRecord({
|
||||
record: existing,
|
||||
pluginId: params.pluginId,
|
||||
});
|
||||
if (existing && !existingPluginBinding) {
|
||||
return {
|
||||
status: "error",
|
||||
message:
|
||||
"This conversation is already bound by core routing and cannot be claimed by a plugin.",
|
||||
};
|
||||
if (existingLegacyPluginBinding) {
|
||||
log.info(
|
||||
`plugin binding migrating legacy record plugin=${params.pluginId} root=${params.pluginRoot} channel=${ref.channel} account=${ref.accountId} conversation=${ref.conversationId}`,
|
||||
);
|
||||
} else {
|
||||
return {
|
||||
status: "error",
|
||||
message:
|
||||
"This conversation is already bound by core routing and cannot be claimed by a plugin.",
|
||||
};
|
||||
}
|
||||
}
|
||||
if (existingPluginBinding && existingPluginBinding.pluginRoot !== params.pluginRoot) {
|
||||
return {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user