openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
312 lines (311 loc) • 14.2 kB
JavaScript
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js";
import { u as resolveToolProfilePolicy } from "./tool-policy-shared-DIyS0iQC.js";
import { a as isToolAllowedByPolicies } from "./tool-policy-match-TnFxBs5z.js";
import { l as mergeAlsoAllowPolicy } from "./tool-policy-Wi0C45cX.js";
import { o as resolveSessionStorePathCore } from "./paths-CXdaYWF_.js";
import { i as buildModelAliasIndex, y as resolveModelRefFromString } from "./model-selection-shared-BlLyx1r2.js";
import { _ as resolveSessionAgentId } from "./agent-scope-DbtJyKUL.js";
import { t as resolveDefaultModelForAgent } from "./model-selection-config-BrdmmqKD.js";
import { u as normalizeVerboseLevel } from "./thinking.shared-bHYuuc1L.js";
import { r as logVerbose } from "./globals-CTaGxEqj.js";
import "./message-channel-constants-2zSoJXQC.js";
import "./message-channel-BQrhwUEA.js";
import { t as normalizeChatType } from "./chat-type-CG0X_HJM.js";
import { d as sessionDeliveryChannel, f as sessionDeliveryOrigin, n as deliveryContextFromSession } from "./delivery-context.shared-CXmRgetN.js";
import "./session-accessor-YsytfDtG.js";
import { u as loadSessionEntryReadOnly } from "./session-accessor.sqlite-entry-CWk3jL7s.js";
import { r as resolveGroupSessionKey } from "./group-DlTf9maP.js";
import { h as resolveSessionPinnedHarnessId } from "./agent-harness-session-key-BOz3yx0-.js";
import "./thinking-DterdXhr.js";
import { i as resolveSessionRuntimeOverrideForProvider } from "./session-runtime-compat-DNAICzi6.js";
import "./model-selection-di2kjKCB.js";
import { a as isNativeCommandTurn, c as resolveCommandTurnContext } from "./command-turn-context-CmPEYNmV.js";
import { o as resolveSourceReplyDeliveryMode } from "./source-reply-delivery-mode-Ct9PBal_.js";
import { s as resolveSubagentCapabilityStore, t as isSubagentEnvelopeSession } from "./subagent-capabilities-Cd0-4jrx.js";
import { a as resolveSubagentToolPolicyForSession, i as resolveInheritedToolPolicyForSession, n as resolveEffectiveToolPolicy, r as resolveGroupToolPolicy } from "./agent-tools.policy-NF_9Y4S4.js";
import "./internal-hooks-Dgwjgwuj.js";
import { c as selectAgentHarness } from "./selection-CgLPGlZh.js";
import { t as resolveChannelModelOverride } from "./model-overrides-DPMkS7yu.js";
import { n as resolveStoredModelOverride } from "./stored-model-overrides-j_gQYbkA.js";
import { t as resolveOriginMessageProvider } from "./origin-routing-CgwQQ0I7.js";
//#region src/auto-reply/reply/dispatch-from-config.runtime.ts
/** Runtime-only dispatch dependencies shared by config-driven reply delivery. */
/** Runtime-only dispatch dependencies shared by config-driven reply delivery. */
function loadSessionStoreEntry(params) {
return loadSessionEntryReadOnly(params);
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.harness-defaults.ts
function createShouldEmitVerboseProgress(params) {
let runVerbosity;
const resolveCurrentExplicitLevel = () => {
if (params.sessionKey && params.storePath) try {
const entry = loadSessionStoreEntry({
...params.agentId ? { agentId: params.agentId } : {},
storePath: params.storePath,
sessionKey: params.sessionKey,
readConsistency: "latest",
clone: false
});
return normalizeVerboseLevel(entry?.verboseLevel ?? "");
} catch {}
return normalizeVerboseLevel(params.initialExplicitLevel ?? "");
};
const resolveLevel = () => runVerbosity?.verboseLevelOverride ?? resolveCurrentExplicitLevel() ?? runVerbosity?.resolvedVerboseLevel ?? normalizeVerboseLevel(params.fallbackLevel) ?? "off";
return {
noteRunVerbosity: (settings) => {
runVerbosity = settings;
},
shouldEmit: () => resolveLevel() !== "off",
shouldEmitFull: () => resolveLevel() === "full"
};
}
function resolveHarnessDefaultChannel(params) {
const originatingChannel = typeof params.ctx.OriginatingChannel === "string" ? params.ctx.OriginatingChannel : void 0;
return sessionDeliveryChannel(params.entry) ?? originatingChannel ?? params.ctx.Provider ?? params.ctx.Surface;
}
function resolveHarnessDefaultParentSessionKey(params) {
return params.entry?.parentSessionKey ?? params.ctx.ModelParentSessionKey ?? params.ctx.ParentSessionKey;
}
function resolveTurnModelOverride(replyOptions) {
if (replyOptions?.isHeartbeat !== true) return;
return normalizeOptionalString(replyOptions.heartbeatModelOverride);
}
function resolveChannelModelCandidate(params) {
if (!params.cfg.channels?.modelByChannel) return;
const channel = resolveHarnessDefaultChannel({
ctx: params.ctx,
entry: params.entry
});
const channelModelOverride = resolveChannelModelOverride({
cfg: params.cfg,
channel,
groupId: params.entry?.groupId,
groupChatType: params.entry?.chatType ?? params.ctx.ChatType,
groupChannel: params.entry?.groupChannel ?? params.ctx.GroupChannel,
groupSubject: params.entry?.subject ?? params.ctx.GroupSubject,
parentSessionKey: params.parentSessionKey,
directUserIds: [
sessionDeliveryOrigin(params.entry)?.nativeDirectUserId,
sessionDeliveryOrigin(params.entry)?.from,
sessionDeliveryOrigin(params.entry)?.to,
params.ctx.OriginatingTo,
params.ctx.From,
params.ctx.SenderId
]
});
if (!channelModelOverride) return;
return resolveModelRefFromString({
raw: channelModelOverride.model,
defaultProvider: params.defaultProvider,
aliasIndex: params.aliasIndex
})?.ref;
}
function resolveStoredModelCandidate(params) {
const storedModelRef = resolveStoredModelOverride({
loadSessionEntry: (sessionKey) => {
const agentId = resolveSessionAgentId({
sessionKey,
config: params.cfg,
fallbackAgentId: params.sessionAgentId
});
return loadSessionStoreEntry({
agentId,
storePath: resolveSessionStorePathCore(params.cfg.session?.store, { agentId }),
sessionKey,
readConsistency: "latest",
clone: false
});
},
sessionEntry: params.entry,
sessionStore: params.sessionStore,
sessionKey: params.sessionKey,
parentSessionKey: params.parentSessionKey,
defaultProvider: params.defaultProvider
});
if (!storedModelRef) return;
return {
provider: storedModelRef.provider ?? params.defaultProvider,
model: storedModelRef.model
};
}
function resolveModelOverrideCandidate(params) {
if (!params.modelOverride) return;
return resolveModelRefFromString({
raw: params.modelOverride,
defaultProvider: params.defaultProvider,
aliasIndex: params.aliasIndex
})?.ref;
}
/**
* Resolves the configured visible-replies mode plus the guarded harness
* default. One owner for dispatch and synthetic-turn binding facts: both must
* derive the same session-stable delivery mode or CLI session bindings
* ping-pong across turn kinds (#121485).
*/
function resolveVisibleRepliesPolicy(params) {
const configuredVisibleReplies = params.chatType === "group" || params.chatType === "channel" ? params.cfg.messages?.groupChat?.visibleReplies ?? params.cfg.messages?.visibleReplies : params.cfg.messages?.visibleReplies;
return {
configuredVisibleReplies,
harnessDefaultVisibleReplies: configuredVisibleReplies === void 0 && params.chatType !== "group" && params.chatType !== "channel" ? resolveHarnessSourceVisibleRepliesDefault({
cfg: params.cfg,
ctx: params.ctx,
entry: params.entry,
sessionAgentId: params.sessionAgentId,
sessionKey: params.sessionKey,
sessionStore: params.sessionStore,
turnModelOverride: params.turnModelOverride
}) : void 0
};
}
function resolveHarnessSourceVisibleRepliesDefault(params) {
if (isNativeCommandTurn(resolveCommandTurnContext(params.ctx))) return;
try {
const defaultModelRef = resolveDefaultModelForAgent({
cfg: params.cfg,
agentId: params.sessionAgentId
});
const aliasIndex = buildModelAliasIndex({
cfg: params.cfg,
agentId: params.sessionAgentId,
defaultProvider: defaultModelRef.provider
});
const parentSessionKey = resolveHarnessDefaultParentSessionKey(params);
const channelModelCandidate = resolveChannelModelCandidate({
aliasIndex,
cfg: params.cfg,
ctx: params.ctx,
defaultProvider: defaultModelRef.provider,
entry: params.entry,
parentSessionKey
});
const storedModelCandidate = resolveStoredModelCandidate({
cfg: params.cfg,
defaultProvider: defaultModelRef.provider,
entry: params.entry,
parentSessionKey,
sessionAgentId: params.sessionAgentId,
sessionKey: params.sessionKey,
sessionStore: params.sessionStore
});
const turnModelCandidate = resolveModelOverrideCandidate({
aliasIndex,
defaultProvider: defaultModelRef.provider,
modelOverride: params.turnModelOverride
});
const resolveCandidateDefault = (candidate) => {
const agentHarnessRuntimeOverride = resolveSessionRuntimeOverrideForProvider({
provider: candidate.provider,
entry: params.entry,
cfg: params.cfg
});
const harness = selectAgentHarness({
provider: candidate.provider,
modelId: candidate.model,
config: params.cfg,
agentId: params.sessionAgentId,
sessionKey: params.sessionKey,
agentHarnessId: resolveSessionPinnedHarnessId(params.entry),
agentHarnessRuntimeOverride
});
return harness.deliveryDefaults?.visibleReplies ?? harness.deliveryDefaults?.sourceVisibleReplies;
};
const selectedModelCandidate = turnModelCandidate ?? storedModelCandidate ?? channelModelCandidate;
if (selectedModelCandidate) return resolveCandidateDefault(selectedModelCandidate);
const sourceProvider = normalizeOptionalString(sessionDeliveryOrigin(params.entry)?.provider ?? params.ctx.Provider ?? params.ctx.Surface);
if (sourceProvider) {
const sourceDefault = resolveCandidateDefault({ provider: sourceProvider });
if (sourceDefault) return sourceDefault;
}
return resolveCandidateDefault(defaultModelRef);
} catch (error) {
logVerbose(`dispatch-from-config: could not resolve harness visible-reply defaults: ${formatErrorMessage(error)}`);
return;
}
}
//#endregion
//#region src/auto-reply/reply/session-stable-reply-mode.ts
/**
* Resolves the session's stable source-reply mode the way dispatch does, from
* a synthetic turn's restored context plus persisted session facts. Synthetic
* turns keep their effective delivery mode, but CLI session reuse belongs to
* the session's normal source-reply policy — every turn kind must derive the
* same messageToolPolicyHash, or chat and heartbeat turns ping-pong the CLI
* binding on each transition (#121485).
*/
function resolveSessionStableReplyMode(params) {
const { cfg, ctx, sessionEntry } = params;
const chatType = normalizeChatType(ctx.ChatType) ?? normalizeChatType(sessionEntry.chatType) ?? void 0;
const stableReplyContext = {
CommandAuthorized: false,
ChatType: chatType,
Provider: normalizeOptionalString(ctx.Provider) ?? sessionDeliveryOrigin(sessionEntry)?.provider ?? "webchat",
Surface: normalizeOptionalString(ctx.Surface) ?? sessionDeliveryChannel(sessionEntry),
ExplicitDeliverRoute: ctx.ExplicitDeliverRoute
};
const { harnessDefaultVisibleReplies } = resolveVisibleRepliesPolicy({
cfg,
chatType,
ctx,
entry: sessionEntry,
sessionAgentId: params.sessionAgentId,
sessionKey: params.sessionKey,
sessionStore: params.sessionStore,
turnModelOverride: params.turnModelOverride
});
const candidateMode = resolveSourceReplyDeliveryMode({
cfg,
ctx: stableReplyContext,
defaultVisibleReplies: harnessDefaultVisibleReplies
});
if (candidateMode !== "message_tool_only") return candidateMode;
return resolveStableMessageToolAvailability(params) ? candidateMode : "automatic";
}
/**
* Sender-independent message-tool availability for the session-stable mode.
* One owner for dispatch's stable-mode downgrade and synthetic-turn binding
* facts: sender-scoped denials apply to the sender's turn, never to the
* session policy every turn kind must hash identically (#121485).
*/
function resolveStableMessageToolAvailability(params) {
const { cfg, ctx, sessionEntry } = params;
const { globalPolicy, globalProviderPolicy, agentPolicy, agentProviderPolicy, profile, providerProfile, profileAlsoAllow, providerProfileAlsoAllow } = resolveEffectiveToolPolicy({
config: cfg,
sessionKey: params.sessionKey,
agentId: params.sessionAgentId
});
const profilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(profile), [...profileAlsoAllow ?? [], "message"]);
const providerProfilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(providerProfile), [...providerProfileAlsoAllow ?? [], "message"]);
const groupPolicy = resolveGroupToolPolicy({
config: cfg,
sessionKey: params.sessionKey,
messageProvider: resolveOriginMessageProvider({
originatingChannel: ctx.OriginatingChannel ?? (sessionEntry ? sessionDeliveryChannel(sessionEntry) : void 0),
provider: normalizeOptionalString(ctx.Provider ?? ctx.Surface) ?? (sessionEntry ? sessionDeliveryOrigin(sessionEntry)?.provider : void 0)
}),
groupId: resolveGroupSessionKey(ctx)?.id ?? sessionEntry?.groupId,
groupChannel: normalizeOptionalString(ctx.GroupChannel) ?? normalizeOptionalString(ctx.GroupSubject) ?? normalizeOptionalString(sessionEntry?.groupChannel) ?? normalizeOptionalString(sessionEntry?.subject),
groupSpace: normalizeOptionalString(ctx.GroupSpace),
accountId: ctx.AccountId ?? (sessionEntry ? deliveryContextFromSession(sessionEntry)?.accountId : void 0)
});
const subagentStore = resolveSubagentCapabilityStore(params.sessionKey, { cfg });
const subagentPolicy = params.sessionKey && isSubagentEnvelopeSession(params.sessionKey, {
cfg,
store: subagentStore
}) ? resolveSubagentToolPolicyForSession(cfg, params.sessionKey, { store: subagentStore }) : void 0;
const inheritedToolPolicy = resolveInheritedToolPolicyForSession(cfg, params.sessionKey, { store: subagentStore });
return isToolAllowedByPolicies("message", [
profilePolicy,
providerProfilePolicy,
globalProviderPolicy,
agentProviderPolicy,
globalPolicy,
agentPolicy,
groupPolicy,
subagentPolicy,
inheritedToolPolicy
]);
}
//#endregion
export { resolveVisibleRepliesPolicy as a, resolveTurnModelOverride as i, resolveStableMessageToolAvailability as n, loadSessionStoreEntry as o, createShouldEmitVerboseProgress as r, resolveSessionStableReplyMode as t };