UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

231 lines (230 loc) 8.84 kB
import { c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js"; import "./string-coerce-runtime-CEGJWkQ_.js"; import { r as normalizeFeishuTarget } from "./targets-DGmM3dk9.js"; import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-CgQX90Pg.js"; import { n as getFeishuThreadBindingManager } from "./thread-bindings-BhKhjD5Z.js"; //#region extensions/feishu/src/subagent-hooks.ts function summarizeError(err) { if (err instanceof Error) return err.message; if (typeof err === "string") return err; return "error"; } function stripProviderPrefix(raw) { return raw.replace(/^(feishu|lark):/i, "").trim(); } function resolveFeishuRequesterConversation(params) { const manager = getFeishuThreadBindingManager(params.accountId); if (!manager) return null; const rawTo = params.to?.trim(); const withoutProviderPrefix = rawTo ? stripProviderPrefix(rawTo) : ""; const normalizedTarget = rawTo ? normalizeFeishuTarget(rawTo) : null; const threadId = params.threadId != null && params.threadId !== "" ? String(params.threadId).trim() : ""; const isChatTarget = /^(chat|group|channel):/i.test(withoutProviderPrefix); const parsedRequesterTopic = normalizedTarget && threadId && isChatTarget ? parseFeishuConversationId({ conversationId: buildFeishuConversationId({ chatId: normalizedTarget, scope: "group_topic", topicId: threadId }), parentConversationId: normalizedTarget }) : null; const requesterSessionKey = params.requesterSessionKey?.trim(); if (requesterSessionKey) { const existingBindings = manager.listBySessionKey(requesterSessionKey); if (existingBindings.length === 1) { const existing = existingBindings[0]; return { accountId: existing.accountId, conversationId: existing.conversationId, parentConversationId: existing.parentConversationId }; } if (existingBindings.length > 1) { if (rawTo && normalizedTarget && !threadId && !isChatTarget) { const directMatches = existingBindings.filter((entry) => entry.accountId === manager.accountId && entry.conversationId === normalizedTarget && !entry.parentConversationId); if (directMatches.length === 1) { const existing = directMatches[0]; return { accountId: existing.accountId, conversationId: existing.conversationId, parentConversationId: existing.parentConversationId }; } return null; } if (parsedRequesterTopic) { const matchingTopicBindings = existingBindings.filter((entry) => { const parsed = parseFeishuConversationId({ conversationId: entry.conversationId, parentConversationId: entry.parentConversationId }); return parsed?.chatId === parsedRequesterTopic.chatId && parsed?.topicId === parsedRequesterTopic.topicId; }); if (matchingTopicBindings.length === 1) { const existing = matchingTopicBindings[0]; return { accountId: existing.accountId, conversationId: existing.conversationId, parentConversationId: existing.parentConversationId }; } const senderScopedTopicBindings = matchingTopicBindings.filter((entry) => { return parseFeishuConversationId({ conversationId: entry.conversationId, parentConversationId: entry.parentConversationId })?.scope === "group_topic_sender"; }); if (senderScopedTopicBindings.length === 1 && matchingTopicBindings.length === senderScopedTopicBindings.length) { const existing = senderScopedTopicBindings[0]; return { accountId: existing.accountId, conversationId: existing.conversationId, parentConversationId: existing.parentConversationId }; } return null; } } } if (!rawTo) return null; if (!normalizedTarget) return null; if (threadId) { if (!isChatTarget) return null; return { accountId: manager.accountId, conversationId: buildFeishuConversationId({ chatId: normalizedTarget, scope: "group_topic", topicId: threadId }), parentConversationId: normalizedTarget }; } if (isChatTarget) return null; return { accountId: manager.accountId, conversationId: normalizedTarget }; } function resolveFeishuDeliveryOrigin(params) { const deliveryTo = params.deliveryTo?.trim(); const deliveryThreadId = params.deliveryThreadId?.trim(); if (deliveryTo) return { channel: "feishu", accountId: params.accountId, to: deliveryTo, ...deliveryThreadId ? { threadId: deliveryThreadId } : {} }; const parsed = parseFeishuConversationId({ conversationId: params.conversationId, parentConversationId: params.parentConversationId }); if (parsed?.topicId) return { channel: "feishu", accountId: params.accountId, to: `chat:${params.parentConversationId?.trim() || parsed.chatId}`, threadId: parsed.topicId }; return { channel: "feishu", accountId: params.accountId, to: `user:${params.conversationId}` }; } function resolveMatchingChildBinding(params) { const manager = getFeishuThreadBindingManager(params.accountId); if (!manager) return null; const childBindings = manager.listBySessionKey(params.childSessionKey.trim()); if (childBindings.length === 0) return null; const requesterConversation = resolveFeishuRequesterConversation({ accountId: manager.accountId, to: params.requesterOrigin?.to, threadId: params.requesterOrigin?.threadId, requesterSessionKey: params.requesterSessionKey }); if (requesterConversation) { const matched = childBindings.find((entry) => entry.accountId === requesterConversation.accountId && entry.conversationId === requesterConversation.conversationId && normalizeOptionalString(entry.parentConversationId) === normalizeOptionalString(requesterConversation.parentConversationId)); if (matched) return matched; } return childBindings.length === 1 ? childBindings[0] : null; } async function handleFeishuSubagentSpawning(event, ctx) { if (!event.threadRequested) return; if (normalizeOptionalLowercaseString(event.requester?.channel) !== "feishu") return; const manager = getFeishuThreadBindingManager(event.requester?.accountId); if (!manager) return { status: "error", error: "Feishu current-conversation binding is unavailable because the Feishu account monitor is not active." }; const conversation = resolveFeishuRequesterConversation({ accountId: event.requester?.accountId, to: event.requester?.to, threadId: event.requester?.threadId, requesterSessionKey: ctx.requesterSessionKey }); if (!conversation) return { status: "error", error: "Feishu current-conversation binding is only available in direct messages or topic conversations." }; try { const binding = manager.bindConversation({ conversationId: conversation.conversationId, parentConversationId: conversation.parentConversationId, targetKind: "subagent", targetSessionKey: event.childSessionKey, metadata: { agentId: event.agentId, label: event.label, boundBy: "system", deliveryTo: event.requester?.to, deliveryThreadId: event.requester?.threadId != null && event.requester.threadId !== "" ? String(event.requester.threadId) : void 0 } }); if (!binding) return { status: "error", error: "Unable to bind this Feishu conversation to the spawned subagent session. Session mode is unavailable for this target." }; return { status: "ok", threadBindingReady: true, deliveryOrigin: resolveFeishuDeliveryOrigin({ conversationId: binding.conversationId, parentConversationId: binding.parentConversationId, accountId: binding.accountId, deliveryTo: binding.deliveryTo, deliveryThreadId: binding.deliveryThreadId }) }; } catch (err) { return { status: "error", error: `Feishu conversation bind failed: ${summarizeError(err)}` }; } } function handleFeishuSubagentDeliveryTarget(event) { if (!event.expectsCompletionMessage) return; if (normalizeOptionalLowercaseString(event.requesterOrigin?.channel) !== "feishu") return; const binding = resolveMatchingChildBinding({ accountId: event.requesterOrigin?.accountId, childSessionKey: event.childSessionKey, requesterSessionKey: event.requesterSessionKey, requesterOrigin: { to: event.requesterOrigin?.to, threadId: event.requesterOrigin?.threadId } }); if (!binding) return; return { origin: resolveFeishuDeliveryOrigin({ conversationId: binding.conversationId, parentConversationId: binding.parentConversationId, accountId: binding.accountId, deliveryTo: binding.deliveryTo, deliveryThreadId: binding.deliveryThreadId }) }; } function handleFeishuSubagentEnded(event) { getFeishuThreadBindingManager(event.accountId)?.unbindBySessionKey(event.targetSessionKey); } //#endregion export { handleFeishuSubagentEnded as n, handleFeishuSubagentSpawning as r, handleFeishuSubagentDeliveryTarget as t };