UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

189 lines (188 loc) • 7.69 kB
import { _ as resolvePrimaryStringValue, c as normalizeOptionalLowercaseString, l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs"; import "./session-key-DY3MOX4N.mjs"; import { n as normalizeAccountId } from "./account-id-ifCOO7_9.mjs"; import { d as resolveAgentWorkspaceDir, r as resolveAgentConfig } from "./agent-scope-config-BEk6-ThS.mjs"; import "./agent-scope-bJOokm5r.mjs"; import { i as getPluginRegistryForContext } from "./gateway-request-scope-DV3FHtde.mjs"; import { r as getLoadedChannelPluginEntryById } from "./registry-loaded-BXeI0CAQ.mjs"; import { n as parseModelRef } from "./model-selection-normalize-B-Anaau2.mjs"; import { n as resolveConfiguredThinkingDefaultCore } from "./model-thinking-default-Cepu2GOi.mjs"; import { r as listConfiguredBindings } from "./bindings-Cw_QSeBA.mjs"; import { a as pickFirstExistingAgentId } from "./resolve-route-DeZAxBYa.mjs"; import { i as parseConfiguredAcpSessionKey, n as normalizeBindingConfig, o as toConfiguredAcpBindingRecord, r as normalizeMode } from "./persistent-bindings.types-CPjcRT6x.mjs"; //#region src/channels/plugins/configured-binding-compiler.ts function resolveCompiledBindingRegistry(cfg) { const rulesByChannel = /* @__PURE__ */ new Map(); for (const binding of listConfiguredBindings(cfg)) { if (binding.type !== "acp") continue; const bindingConversationId = normalizeOptionalString(binding.match?.peer?.id); if (!bindingConversationId) continue; const channel = normalizeOptionalLowercaseString(binding.match.channel); if (!channel) continue; const plugin = getLoadedChannelPluginEntryById(channel, getPluginRegistryForContext() ?? void 0)?.plugin; const provider = plugin?.bindings; if (!plugin || !provider?.compileConfiguredBinding || !provider.matchInboundConversation) continue; const channelId = plugin.id; const target = provider.compileConfiguredBinding({ binding, conversationId: bindingConversationId }); if (!target) continue; const agentId = pickFirstExistingAgentId(cfg, binding.agentId ?? "main"); const agent = resolveAgentConfig(cfg, agentId); const runtimeDefaults = agent?.runtime?.type === "acp" ? agent.runtime.acp : void 0; const acpAgentId = normalizeOptionalString(runtimeDefaults?.agent); const bindingOverrides = normalizeBindingConfig(binding.acp); const mode = normalizeMode(bindingOverrides.mode ?? normalizeOptionalString(runtimeDefaults?.mode)); const model = resolvePrimaryStringValue(agent?.model); const modelRef = model ? parseModelRef(model, "") : null; const thinking = agent?.thinkingDefault ?? (modelRef ? resolveConfiguredThinkingDefaultCore({ cfg, ...modelRef }) : cfg.agents?.defaults?.thinkingDefault); const cwd = bindingOverrides.cwd ?? normalizeOptionalString(runtimeDefaults?.cwd) ?? (normalizeOptionalString(agent?.workspace) || normalizeOptionalString(cfg.agents?.defaults?.workspace) ? resolveAgentWorkspaceDir(cfg, agentId) : void 0); const backend = bindingOverrides.backend ?? normalizeOptionalString(runtimeDefaults?.backend); const rule = { channel: channelId, accountPattern: normalizeOptionalString(binding.match.accountId), binding, bindingConversationId, target, agentId, provider, targetFactory: { driverId: "acp", materialize: ({ accountId, conversation }) => { const record = toConfiguredAcpBindingRecord({ channel: channelId, accountId, conversationId: conversation.conversationId, parentConversationId: conversation.parentConversationId, agentId, acpAgentId, mode, model, thinking, cwd, backend, label: bindingOverrides.label }); return { record, statefulTarget: { kind: "stateful", driverId: "acp", sessionKey: record.targetSessionKey, agentId, ...bindingOverrides.label ? { label: bindingOverrides.label } : {} } }; } } }; const rules = rulesByChannel.get(rule.channel) ?? []; rules.push(rule); rulesByChannel.set(rule.channel, rules); } return rulesByChannel; } //#endregion //#region src/channels/plugins/configured-binding-registry.ts function resolveAccountMatchPriority(match, actual) { if (!match) return actual === "default" ? 2 : 0; if (match === "*") return 1; return normalizeAccountId(match) === actual ? 2 : 0; } /** Compile plugin binding rules before publishing a config or plugin generation. */ function validateConfiguredBindings(cfg) { resolveCompiledBindingRegistry(cfg); } /** * Resolves a configured binding record from explicit channel/account/conversation ids. */ function resolveConfiguredBindingRecord(params) { const resolved = resolveConfiguredBinding({ cfg: params.cfg, conversation: params }); return resolved ? { record: resolved.record, statefulTarget: resolved.statefulTarget } : null; } /** * Resolves the full configured binding match, including compiled rule and match diagnostics. */ function resolveConfiguredBinding(params) { const channel = normalizeOptionalLowercaseString(params.conversation.channel); const conversationId = params.conversation.conversationId.trim(); if (!channel || !conversationId) return null; const conversation = { channel, accountId: normalizeAccountId(params.conversation.accountId), conversationId, parentConversationId: normalizeOptionalString(params.conversation.parentConversationId) }; const rules = resolveCompiledBindingRegistry(params.cfg).get(channel); let bestMatch = null; let bestAccountPriority = 0; let bestMatchPriority = 0; for (const rule of rules ?? []) { const accountMatchPriority = resolveAccountMatchPriority(rule.accountPattern, conversation.accountId); if (accountMatchPriority === 0) continue; const match = rule.provider.matchInboundConversation({ binding: rule.binding, compiledBinding: rule.target, conversationId, parentConversationId: conversation.parentConversationId }); if (!match) continue; const matchPriority = match.matchPriority ?? 0; if (!bestMatch || accountMatchPriority > bestAccountPriority || accountMatchPriority === bestAccountPriority && matchPriority > bestMatchPriority) { bestMatch = { rule, match }; bestAccountPriority = accountMatchPriority; bestMatchPriority = matchPriority; } } if (!bestMatch) return null; return { conversation, compiledBinding: bestMatch.rule, match: bestMatch.match, ...bestMatch.rule.targetFactory.materialize({ accountId: conversation.accountId, conversation: bestMatch.match }) }; } /** * Resolves a configured binding record by the stateful target session key. */ function resolveConfiguredBindingRecordBySessionKey(params) { const registry = resolveCompiledBindingRegistry(params.cfg); const sessionKey = params.sessionKey.trim(); if (!sessionKey) return null; const parsed = parseConfiguredAcpSessionKey(sessionKey); if (!parsed) return null; const rules = registry.get(parsed.channel); if (!rules) return null; let wildcardMatch = null; for (const rule of rules) { const accountMatchPriority = resolveAccountMatchPriority(rule.accountPattern, parsed.accountId); if (accountMatchPriority === 0) continue; const materializedTarget = rule.targetFactory.materialize({ accountId: parsed.accountId, conversation: rule.target }); if (materializedTarget.record.targetSessionKey === sessionKey) { if (accountMatchPriority === 2) return materializedTarget; wildcardMatch = materializedTarget; } } return wildcardMatch; } //#endregion export { validateConfiguredBindings as i, resolveConfiguredBindingRecord as n, resolveConfiguredBindingRecordBySessionKey as r, resolveConfiguredBinding as t };