openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
614 lines (613 loc) • 30.6 kB
JavaScript
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js";
import { t as createLazyImportLoader } from "./lazy-promise-DGqyc4Y4.js";
import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js";
import { c as resolveAgentConfig, i as listAgentEntries, t as AgentSelectionRequiredError } from "./agent-scope-config-DcbEhP0R.js";
import "./session-key-BnWWjqNc.js";
import { n as normalizeAccountId, t as DEFAULT_ACCOUNT_ID } from "./account-id-CETVCrTz.js";
import { i as normalizeChatChannelId } from "./ids-BVZRYG0I.js";
import { i as resolveProviderToolPolicyEntry, n as normalizeToolProviderPolicyKey, r as resolveProviderToolPolicy } from "./provider-tool-policy-BKZP2YeG.js";
import { u as resolveToolProfilePolicy } from "./tool-policy-shared-DIyS0iQC.js";
import { a as isToolAllowedByPolicies, o as isToolAllowedByPolicyName } from "./tool-policy-match-TnFxBs5z.js";
import { n as pickSandboxToolPolicy } from "./sandbox-tool-policy-G7E6RfNN.js";
import { l as mergeAlsoAllowPolicy } from "./tool-policy-Wi0C45cX.js";
import { i as listRouteBindings } from "./bindings-CI-O7TMQ.js";
import { s as resolveAgentRoute } from "./resolve-route-BRXfbiKP.js";
import { r as VERSION_BOUND_RUNTIME_PLUGIN_POLICY_IDS_BY_SURFACE } from "./configured-runtime-plugin-installs-DWgjbBZ4.js";
import { t as resolveDoctorPrimaryModelRef } from "./primary-model-ref-B2MIBjw4.js";
//#region src/routing/channel-route-targets.ts
const CHANNELS_CONFIG_META_KEYS = /* @__PURE__ */ new Set(["defaults", "modelByChannel"]);
function normalizeConfiguredChannelKey(raw) {
return normalizeChatChannelId(raw) ?? normalizeLowercaseStringOrEmpty(raw);
}
function normalizeRouteBindingChannelKey(raw) {
return normalizeLowercaseStringOrEmpty(raw);
}
function listConfiguredChannelIds(cfg) {
if (!isRecord(cfg.channels)) return [];
return Object.entries(cfg.channels).filter(([id, value]) => {
if (CHANNELS_CONFIG_META_KEYS.has(id)) return false;
return !(isRecord(value) && value.enabled === false);
}).map(([id]) => normalizeConfiguredChannelKey(id)).filter(Boolean).toSorted();
}
function listConfiguredChannelAccountIds(cfg, channelId) {
if (!isRecord(cfg.channels)) return [];
const channel = Object.entries(cfg.channels).find(([id]) => normalizeConfiguredChannelKey(id) === channelId)?.[1];
if (!isRecord(channel) || !isRecord(channel.accounts)) return [];
return Object.entries(channel.accounts).filter(([, value]) => !(isRecord(value) && value.enabled === false)).map(([accountId]) => normalizeAccountId(accountId)).filter(Boolean).toSorted();
}
function addTarget(byAgent, agentId, channel) {
const normalizedAgentId = normalizeAgentId(agentId);
const trimmedChannel = channel.trim();
if (!normalizedAgentId || !trimmedChannel) return;
const channels = byAgent.get(normalizedAgentId) ?? /* @__PURE__ */ new Set();
channels.add(trimmedChannel);
byAgent.set(normalizedAgentId, channels);
}
function collectChannelRouteTargets(cfg) {
const byAgent = /* @__PURE__ */ new Map();
for (const binding of listRouteBindings(cfg)) addTarget(byAgent, binding.agentId, normalizeRouteBindingChannelKey(binding.match.channel));
for (const channel of listConfiguredChannelIds(cfg)) {
const accountIds = listConfiguredChannelAccountIds(cfg, channel);
const sampledAccountIds = accountIds.length > 0 ? accountIds : [DEFAULT_ACCOUNT_ID];
for (const accountId of sampledAccountIds) try {
addTarget(byAgent, resolveAgentRoute({
cfg,
channel,
accountId
}).agentId, channel);
} catch (error) {
if (!(error instanceof AgentSelectionRequiredError)) throw error;
}
}
return Array.from(byAgent.entries()).map(([agentId, channels]) => ({
agentId,
channels: Array.from(channels).toSorted()
})).filter((target) => target.channels.length > 0).toSorted((a, b) => a.agentId.localeCompare(b.agentId));
}
//#endregion
//#region src/commands/doctor/shared/preview-warnings.ts
const channelDoctorModuleLoader = createLazyImportLoader(() => import("./channel-doctor-CY5m3coi.js"));
function loadChannelDoctorModule() {
return channelDoctorModuleLoader.load();
}
function listAgentRecords(cfg) {
return listAgentEntries(cfg).filter(isRecord);
}
function hasChannels(cfg) {
return isRecord(cfg.channels);
}
function hasPlugins(cfg) {
return isRecord(cfg.plugins);
}
function hasPluginLoadPaths(cfg) {
const plugins = cfg.plugins;
if (!isRecord(plugins)) return false;
const load = plugins.load;
return isRecord(load) && Array.isArray(load.paths) && load.paths.length > 0;
}
function hasSubagentAllowlistConfig(cfg) {
if (Array.isArray(cfg.agents?.defaults?.subagents?.allowAgents)) return true;
return listAgentRecords(cfg).some((agent) => {
const subagents = isRecord(agent.subagents) ? agent.subagents : void 0;
return Array.isArray(subagents?.allowAgents);
});
}
function hasToolsBySenderKey(value) {
if (Array.isArray(value)) return value.some(hasToolsBySenderKey);
if (!isRecord(value)) return false;
if (isRecord(value.toolsBySender)) return true;
return Object.entries(value).some(([key, nested]) => key !== "toolsBySender" && hasToolsBySenderKey(nested));
}
function hasConfiguredSafeBins(cfg) {
const globalExec = cfg.tools?.exec;
if (isRecord(globalExec) && Array.isArray(globalExec.safeBins) && globalExec.safeBins.length > 0) return true;
return listAgentRecords(cfg).some((agent) => {
const agentExec = isRecord(agent) && isRecord(agent.tools) ? agent.tools.exec : void 0;
return isRecord(agentExec) && Array.isArray(agentExec.safeBins) && agentExec.safeBins.length > 0;
});
}
function resolveMessageToolAvailability(params) {
const agentConfig = params.agentId ? resolveAgentConfig(params.cfg, params.agentId) : void 0;
const modelRef = resolveDoctorPrimaryModelRef(params.cfg, agentConfig?.model);
const providerPolicy = resolveProviderToolPolicy({
byProvider: params.globalTools?.byProvider,
modelProvider: modelRef.provider,
modelId: modelRef.model
});
const agentProviderPolicy = resolveProviderToolPolicy({
byProvider: params.agentTools?.byProvider,
modelProvider: modelRef.provider,
modelId: modelRef.model
});
const profile = params.agentTools?.profile ?? params.globalTools?.profile;
const configuredAlsoAllow = Array.isArray(params.agentTools?.alsoAllow) ? params.agentTools.alsoAllow : Array.isArray(params.globalTools?.alsoAllow) ? params.globalTools.alsoAllow : [];
const providerAlsoAllow = Array.isArray(agentProviderPolicy?.alsoAllow) ? agentProviderPolicy.alsoAllow : Array.isArray(providerPolicy?.alsoAllow) ? providerPolicy.alsoAllow : [];
const profileAlsoAllow = [...configuredAlsoAllow, ...params.runtimeAlsoAllow ?? []];
const providerProfileAlsoAllow = [...providerAlsoAllow, ...params.runtimeAlsoAllow ?? []];
const profilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(profile), profileAlsoAllow);
const providerProfilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(agentProviderPolicy?.profile ?? providerPolicy?.profile), providerProfileAlsoAllow);
return isToolAllowedByPolicies("message", [
profilePolicy,
providerProfilePolicy,
pickSandboxToolPolicy(providerPolicy),
pickSandboxToolPolicy(agentProviderPolicy),
pickSandboxToolPolicy(params.globalTools),
pickSandboxToolPolicy(params.agentTools)
]);
}
const SOURCE_REPLY_RUNTIME_MESSAGE_ALLOW = ["message"];
function resolveSourceReplyMessageToolAvailability(params) {
return resolveMessageToolAvailability({
...params,
runtimeAlsoAllow: SOURCE_REPLY_RUNTIME_MESSAGE_ALLOW
});
}
function sourceReplyRuntimeMayAllowMessageTool(cfg) {
if (resolveGroupVisibleReplyProvenance(cfg).value === "message_tool") return true;
if (cfg.messages?.visibleReplies === "message_tool") return true;
return false;
}
function collectMessageToolUnavailableTargets(cfg, options = {}) {
const agents = listAgentRecords(cfg);
if (agents.length === 0) return (options.sourceReplyRuntimeGrant ? resolveSourceReplyMessageToolAvailability({
cfg,
globalTools: cfg.tools
}) : resolveMessageToolAvailability({
cfg,
globalTools: cfg.tools
})) ? [] : ["default tool policy"];
return agents.flatMap((agent) => {
const agentId = typeof agent.id === "string" ? agent.id : "unknown";
return (options.sourceReplyRuntimeGrant ? resolveSourceReplyMessageToolAvailability({
cfg,
agentId,
globalTools: cfg.tools,
agentTools: agent.tools
}) : resolveMessageToolAvailability({
cfg,
agentId,
globalTools: cfg.tools,
agentTools: agent.tools
})) ? [] : [`agent "${agentId}"`];
});
}
function resolveGroupVisibleReplyProvenance(cfg) {
const groupVisibleReplies = cfg.messages?.groupChat?.visibleReplies;
if (groupVisibleReplies) return {
path: "messages.groupChat.visibleReplies",
provenance: "group-explicit",
value: groupVisibleReplies
};
const globalVisibleReplies = cfg.messages?.visibleReplies;
if (globalVisibleReplies) return {
path: "messages.visibleReplies",
provenance: "global-explicit",
value: globalVisibleReplies
};
return {
path: "messages.groupChat.visibleReplies",
provenance: "default",
value: "automatic"
};
}
function formatTargets(targets) {
if (targets.length <= 2) return targets.join(" and ");
return `${targets.slice(0, 2).join(", ")}, and ${targets.length - 2} more`;
}
/** Warn when visible-reply policy selects message_tool but message is unavailable. */
function collectVisibleReplyToolPolicyWarnings(cfg) {
const groupPolicy = resolveGroupVisibleReplyProvenance(cfg);
const warnings = [];
if (groupPolicy.value === "message_tool") {
const targets = collectMessageToolUnavailableTargets(cfg, { sourceReplyRuntimeGrant: true });
if (targets.length === 0) return warnings;
warnings.push(`- ${groupPolicy.path} is set to "message_tool", but the message tool is unavailable for ${formatTargets(targets)}; OpenClaw falls back to automatic visible replies, so normal replies may post to the source chat. Enable the message tool or set ${groupPolicy.path} to "automatic".`);
}
if (cfg.messages?.visibleReplies === "message_tool" && groupPolicy.path !== "messages.visibleReplies") {
const targets = collectMessageToolUnavailableTargets(cfg, { sourceReplyRuntimeGrant: true });
if (targets.length === 0) return warnings;
warnings.push(`- messages.visibleReplies is set to "message_tool", but the message tool is unavailable for ${formatTargets(targets)}; OpenClaw falls back to automatic direct-chat replies, so normal replies may post to the source chat. Enable the message tool or set messages.visibleReplies to "automatic".`);
}
return warnings;
}
function formatChannelList(channels) {
if (channels.length <= 2) return channels.map((channel) => `"${channel}"`).join(" and ");
return `${channels.slice(0, 2).map((channel) => `"${channel}"`).join(", ")}, and ${channels.length - 2} more`;
}
/** Warn when routed channel agents lack the message tool required for channel actions. */
function collectChannelBoundMessageToolPolicyWarnings(cfg) {
return collectChannelRouteTargets(cfg).flatMap((target) => {
const agentTools = resolveAgentConfig(cfg, target.agentId)?.tools;
if (sourceReplyRuntimeMayAllowMessageTool(cfg) ? resolveSourceReplyMessageToolAvailability({
cfg,
agentId: target.agentId,
globalTools: cfg.tools,
agentTools
}) : resolveMessageToolAvailability({
cfg,
agentId: target.agentId,
globalTools: cfg.tools,
agentTools
})) return [];
return [`- Agent "${target.agentId}" is routed from channel ${formatChannelList(target.channels)}, but the message tool is unavailable for that agent; explicit channel actions such as sendAttachment, upload-file, thread-reply, or reply can fail. Add "message" to the agent tool allowlist, add "group:messaging", or switch the agent to a profile that includes messaging tools.`];
});
}
const PROFILE_CONFIGURED_TOOL_SECTIONS = [{
key: "exec",
label: "tools.exec",
grants: ["exec", "process"]
}, {
key: "fs",
label: "tools.fs",
grants: [
"read",
"write",
"edit"
]
}];
function collectConfiguredToolSectionGrantEntries(params) {
const entries = [];
for (const section of PROFILE_CONFIGURED_TOOL_SECTIONS) if (isRecord(params.tools?.[section.key])) entries.push({
label: `${params.pathLabel}.${section.key}`,
grants: [...section.grants]
});
return entries;
}
function formatQuotedList(values) {
return values.map((value) => `"${value}"`).join(", ");
}
function hasNonEmptyStringList(value) {
return Array.isArray(value) && value.some((entry) => typeof entry === "string");
}
function readPreviewStringList(value) {
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
}
function collectUncoveredConfiguredToolSectionGrantEntries(configuredEntries, profilePolicy) {
if (!profilePolicy) return [];
return configuredEntries.map((entry) => ({
...entry,
grants: entry.grants.filter((toolName) => !isToolAllowedByPolicyName(toolName, profilePolicy))
})).filter((entry) => entry.grants.length > 0);
}
function formatProfileConfiguredSectionGrantAdvice(params) {
const providerSuffix = params.provider ? " for that provider" : "";
if (params.hasAllow) return `Add these grants to ${params.pathLabel}.allow and set ${params.pathLabel}.profile to "full" if these tools should be available${providerSuffix}.`;
return `Add ${params.pathLabel}.alsoAllow: [${formatQuotedList(params.grants)}] if these tools should be available${providerSuffix}.`;
}
function collectProfileConfiguredToolSectionScopeWarnings(params) {
const tools = params.tools;
const profile = (typeof tools?.profile === "string" ? tools.profile : void 0) ?? params.inheritedProfile;
if (!profile) return [];
const configuredEntries = [...params.includeInheritedSections && params.inheritedTools && params.inheritedPathLabel ? collectConfiguredToolSectionGrantEntries({
tools: params.inheritedTools,
pathLabel: params.inheritedPathLabel
}) : [], ...collectConfiguredToolSectionGrantEntries({
tools,
pathLabel: params.pathLabel
})];
if (configuredEntries.length === 0) return [];
const alsoAllow = Array.isArray(tools?.alsoAllow) ? tools.alsoAllow.filter((entry) => typeof entry === "string") : params.inheritedAlsoAllow;
const profilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(profile), alsoAllow);
if (!profilePolicy) return [];
const uncoveredEntries = collectUncoveredConfiguredToolSectionGrantEntries(configuredEntries, profilePolicy);
if (uncoveredEntries.length === 0) return [];
const uncoveredGrants = [...new Set(uncoveredEntries.flatMap((entry) => entry.grants))];
const advice = formatProfileConfiguredSectionGrantAdvice({
pathLabel: params.pathLabel,
grants: uncoveredGrants,
hasAllow: hasNonEmptyStringList(tools?.allow)
});
return [`- ${params.pathLabel}.profile is "${profile}" and ${uncoveredEntries.map((entry) => entry.label).join(" / ")} is configured, but configured sections no longer widen the active profile. ${advice}`];
}
function collectByProviderConfiguredToolSectionWarnings(params) {
const byProvider = isRecord(params.tools?.byProvider) ? params.tools.byProvider : void 0;
if (!byProvider || params.configuredEntries.length === 0) return [];
const inheritedByProvider = isRecord(params.inheritedTools?.byProvider) ? params.inheritedTools.byProvider : void 0;
return Object.entries(byProvider).flatMap(([providerKey, policyValue]) => {
const policy = isRecord(policyValue) ? policyValue : void 0;
if (!policy) return [];
const profile = typeof policy.profile === "string" ? policy.profile : void 0;
if (!profile) return [];
const inheritedPolicy = resolveInheritedProviderPolicyForPreview(inheritedByProvider, providerKey);
const alsoAllow = readPreviewStringList(policy.alsoAllow) ?? readPreviewStringList(inheritedPolicy?.alsoAllow);
const profilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(profile), alsoAllow);
if (!profilePolicy) return [];
const uncoveredEntries = collectUncoveredConfiguredToolSectionGrantEntries(params.configuredEntries, profilePolicy);
if (uncoveredEntries.length === 0) return [];
const providerPath = `${params.pathLabel}.byProvider.${providerKey}`;
const advice = formatProfileConfiguredSectionGrantAdvice({
pathLabel: providerPath,
grants: [...new Set(uncoveredEntries.flatMap((entry) => entry.grants))],
hasAllow: hasNonEmptyStringList(policy.allow),
provider: true
});
return [`- ${providerPath}.profile is "${profile}" and ${uncoveredEntries.map((entry) => entry.label).join(" / ")} is configured, but configured sections no longer widen the provider profile. ${advice}`];
});
}
function resolveInheritedProviderPolicyForPreview(inheritedByProvider, providerKey) {
if (!inheritedByProvider) return;
const normalized = normalizeToolProviderPolicyKey(providerKey);
const slashIndex = normalized.indexOf("/");
const modelProvider = slashIndex > 0 ? normalized.slice(0, slashIndex) : normalized;
const modelId = slashIndex > 0 ? normalized.slice(slashIndex + 1) : void 0;
const policy = resolveProviderToolPolicy({
byProvider: inheritedByProvider,
modelProvider,
modelId
});
return policy && isRecord(policy) ? policy : void 0;
}
function resolveProviderPolicyEntryForPreview(params) {
const entry = resolveProviderToolPolicyEntry(params);
return entry ? {
key: entry.key,
policy: entry.policy
} : void 0;
}
function collectInheritedByProviderConfiguredToolSectionWarnings(params) {
const inheritedByProvider = isRecord(params.inheritedTools?.byProvider) ? params.inheritedTools.byProvider : void 0;
if (!inheritedByProvider || params.configuredEntries.length === 0) return [];
const overridingByProvider = isRecord(params.overridingTools?.byProvider) ? params.overridingTools.byProvider : void 0;
const inheritedEntryForModel = resolveProviderPolicyEntryForPreview({
byProvider: inheritedByProvider,
modelProvider: params.modelProvider,
modelId: params.modelId
});
return Object.entries(inheritedByProvider).flatMap(([providerKey, policyValue]) => {
if (params.modelProvider && inheritedEntryForModel?.key !== providerKey) return [];
const inheritedPolicy = isRecord(policyValue) ? policyValue : void 0;
if (!inheritedPolicy) return [];
const profile = typeof inheritedPolicy.profile === "string" ? inheritedPolicy.profile : void 0;
if (!profile) return [];
const overridingEntry = resolveProviderPolicyEntryForPreview({
byProvider: overridingByProvider,
modelProvider: params.modelProvider,
modelId: params.modelId
}) ?? (isRecord(overridingByProvider?.[providerKey]) ? {
key: providerKey,
policy: overridingByProvider[providerKey]
} : void 0);
const overridingPolicy = overridingEntry?.policy;
if (typeof overridingPolicy?.profile === "string") return [];
const alsoAllow = readPreviewStringList(overridingPolicy?.alsoAllow) ?? readPreviewStringList(inheritedPolicy.alsoAllow);
const profilePolicy = mergeAlsoAllowPolicy(resolveToolProfilePolicy(profile), alsoAllow);
if (!profilePolicy) return [];
const uncoveredEntries = collectUncoveredConfiguredToolSectionGrantEntries(params.configuredEntries, profilePolicy);
if (uncoveredEntries.length === 0) return [];
const overridePath = `${params.overridingPathLabel}.byProvider.${overridingEntry?.key ?? providerKey}`;
const inheritedPath = `${params.inheritedPathLabel}.byProvider.${providerKey}`;
const advice = formatProfileConfiguredSectionGrantAdvice({
pathLabel: overridePath,
grants: [...new Set(uncoveredEntries.flatMap((entry) => entry.grants))],
hasAllow: hasNonEmptyStringList(overridingPolicy?.allow),
provider: true
});
return [`- ${inheritedPath}.profile is "${profile}" and ${uncoveredEntries.map((entry) => entry.label).join(" / ")} is configured, but configured sections no longer widen the inherited provider profile. ${advice}`];
});
}
/** Warn when configured tool sections no longer widen restrictive tool profiles. */
function collectProfileConfiguredToolSectionWarnings(cfg) {
const warnings = [];
const globalTools = isRecord(cfg.tools) ? cfg.tools : void 0;
const globalAlsoAllow = Array.isArray(globalTools?.alsoAllow) ? globalTools.alsoAllow.filter((entry) => typeof entry === "string") : void 0;
const globalProfile = typeof globalTools?.profile === "string" ? globalTools.profile : void 0;
const globalConfiguredEntries = collectConfiguredToolSectionGrantEntries({
tools: globalTools,
pathLabel: "tools"
});
warnings.push(...collectProfileConfiguredToolSectionScopeWarnings({
tools: globalTools,
pathLabel: "tools"
}), ...collectByProviderConfiguredToolSectionWarnings({
tools: globalTools,
pathLabel: "tools",
configuredEntries: globalConfiguredEntries
}));
listAgentRecords(cfg).forEach((agent, index) => {
const agentTools = isRecord(agent.tools) ? agent.tools : void 0;
const agentId = typeof agent.id === "string" ? agent.id : void 0;
const agentConfig = agentId ? resolveAgentConfig(cfg, agentId) : void 0;
const modelRef = resolveDoctorPrimaryModelRef(cfg, agentConfig?.model);
const agentPath = `agents.list[${index}].tools`;
const includeInheritedSections = agentTools !== void 0 && typeof agentTools.profile !== "string";
const ownAgentConfiguredEntries = collectConfiguredToolSectionGrantEntries({
tools: agentTools,
pathLabel: agentPath
});
const agentConfiguredEntries = [...globalConfiguredEntries, ...ownAgentConfiguredEntries];
warnings.push(...collectProfileConfiguredToolSectionScopeWarnings({
tools: agentTools,
inheritedTools: globalTools,
pathLabel: agentPath,
inheritedPathLabel: "tools",
includeInheritedSections,
inheritedProfile: globalProfile,
inheritedAlsoAllow: globalAlsoAllow
}), ...collectByProviderConfiguredToolSectionWarnings({
tools: agentTools,
inheritedTools: globalTools,
pathLabel: agentPath,
configuredEntries: agentConfiguredEntries
}), ...collectInheritedByProviderConfiguredToolSectionWarnings({
inheritedTools: globalTools,
inheritedPathLabel: "tools",
overridingTools: agentTools,
overridingPathLabel: agentPath,
configuredEntries: ownAgentConfiguredEntries,
modelProvider: modelRef.provider,
modelId: modelRef.model
}));
});
return warnings;
}
async function resolveDoctorChannelPreviewConfig(params) {
const [{ resolveCommandSecretRefsViaGateway }, { getConfiguredChannelsCommandSecretTargetIds }] = await Promise.all([import("./command-secret-gateway-D-ezkHjN.js"), import("./command-secret-targets-BeqSZC8z.js")]);
const targetIds = getConfiguredChannelsCommandSecretTargetIds(params.cfg, params.env);
if (targetIds.size === 0) return {
cfg: params.cfg,
diagnostics: []
};
const resolved = await resolveCommandSecretRefsViaGateway({
config: params.cfg,
commandName: "doctor preview",
targetIds,
mode: "read_only_status",
allowLocalExecSecretRefs: params.allowExec === true,
scrubUnresolvedSecretRefs: false
});
return {
cfg: resolved.resolvedConfig,
diagnostics: resolved.diagnostics
};
}
/** Collect info and warning notes for doctor preview mode. */
async function collectDoctorPreviewNotes(params) {
const infoNotes = [];
const warnings = [];
const env = params.env ?? process.env;
const hasChannelConfig = hasChannels(params.cfg);
const hasPluginConfig = hasPlugins(params.cfg);
warnings.push(...collectVisibleReplyToolPolicyWarnings(params.cfg));
warnings.push(...collectChannelBoundMessageToolPolicyWarnings(params.cfg));
warnings.push(...collectProfileConfiguredToolSectionWarnings(params.cfg));
const { collectActiveToolSchemaProjectionWarnings } = await import("./active-tool-schema-warnings-D66Qmi6X.js");
warnings.push(...await collectActiveToolSchemaProjectionWarnings({
cfg: params.cfg,
env,
...params.runWithPluginMetadataSnapshot ? { runWithPluginMetadataSnapshot: params.runWithPluginMetadataSnapshot } : {}
}));
const channelPluginRuntime = await import("./channel-plugin-blockers-Du_re0_7.js");
const channelPluginBlockerHits = channelPluginRuntime.scanConfiguredChannelPluginBlockers(params.cfg, env, params.activationSourceConfig);
if (channelPluginBlockerHits.length > 0) warnings.push(channelPluginRuntime.collectConfiguredChannelPluginBlockerWarnings(channelPluginBlockerHits).join("\n"));
if (hasChannelConfig) {
const channelPreviewConfig = await resolveDoctorChannelPreviewConfig({
cfg: params.cfg,
env,
allowExec: params.allowExec
});
warnings.push(...channelPreviewConfig.diagnostics);
const { collectChannelDoctorPreviewWarnings } = await loadChannelDoctorModule();
const channelDoctorWarnings = await collectChannelDoctorPreviewWarnings({
cfg: channelPreviewConfig.cfg,
doctorFixCommand: params.doctorFixCommand,
env
});
if (channelDoctorWarnings.length > 0) warnings.push(...channelDoctorWarnings);
const { collectOpenPolicyAllowFromWarnings, maybeRepairOpenPolicyAllowFrom } = await import("./open-policy-allowfrom-CLWAWN6i.js");
const allowFromScan = maybeRepairOpenPolicyAllowFrom(params.cfg);
if (allowFromScan.changes.length > 0) warnings.push(collectOpenPolicyAllowFromWarnings({
changes: allowFromScan.changes,
doctorFixCommand: params.doctorFixCommand
}).join("\n"));
}
if ((hasPluginConfig || hasChannelConfig) && params.cfg.plugins?.enabled !== false) {
const { collectStalePluginConfigWarnings, isStalePluginAutoRepairBlocked, scanStalePluginConfig } = await import("./stale-plugin-config-DPFXm3GS.js");
const stalePluginHits = scanStalePluginConfig(params.cfg, env);
if (stalePluginHits.length > 0) {
const stalePluginWarnings = collectStalePluginConfigWarnings({
hits: stalePluginHits,
doctorFixCommand: params.doctorFixCommand,
autoRepairBlocked: isStalePluginAutoRepairBlocked(params.cfg, env),
surfacePreservePluginIds: VERSION_BOUND_RUNTIME_PLUGIN_POLICY_IDS_BY_SURFACE
});
if (stalePluginWarnings.length > 0) warnings.push(stalePluginWarnings.join("\n"));
}
}
const { collectCodexRouteWarnings } = await import("./codex-route-warnings-BF2lkUuZ.js");
warnings.push(...collectCodexRouteWarnings({
cfg: params.cfg,
env,
blockedProviderPlan: params.blockedCodexProviderPlan
}));
if (hasPluginConfig) {
const { collectContextEngineHostCompatibilityWarnings } = await import("./context-engine-host-compat-CfQFtBOn.js");
warnings.push(...await collectContextEngineHostCompatibilityWarnings({
cfg: params.cfg,
doctorFixCommand: params.doctorFixCommand,
env
}));
}
if (hasSubagentAllowlistConfig(params.cfg)) {
const { collectStaleSubagentAllowlistWarnings, scanStaleSubagentAllowlistReferences } = await import("./stale-subagent-allowlist-C9SCSk3l.js");
const staleSubagentAllowlistHits = scanStaleSubagentAllowlistReferences(params.cfg);
if (staleSubagentAllowlistHits.length > 0) warnings.push(collectStaleSubagentAllowlistWarnings({
hits: staleSubagentAllowlistHits,
doctorFixCommand: params.doctorFixCommand
}).join("\n"));
}
const { collectCodexNativeAssetInfoNotes } = await import("./codex-native-assets-C61tfEpS.js");
infoNotes.push(...await collectCodexNativeAssetInfoNotes({
cfg: params.cfg,
env
}));
if (hasPluginLoadPaths(params.cfg)) {
const { collectBundledPluginLoadPathWarnings, scanBundledPluginLoadPathMigrations } = await import("./bundled-plugin-load-paths-GGSgjMkn.js");
const bundledPluginLoadPathHits = scanBundledPluginLoadPathMigrations(params.cfg, env);
if (bundledPluginLoadPathHits.length > 0) warnings.push(collectBundledPluginLoadPathWarnings({
hits: bundledPluginLoadPathHits,
doctorFixCommand: params.doctorFixCommand
}).join("\n"));
}
if (hasChannelConfig) {
const { createChannelDoctorEmptyAllowlistPolicyHooks } = await loadChannelDoctorModule();
const { scanEmptyAllowlistPolicyWarnings } = await import("./empty-allowlist-scan-DnUoJivE.js");
const emptyAllowlistHooks = createChannelDoctorEmptyAllowlistPolicyHooks({
cfg: params.cfg,
env
});
const emptyAllowlistWarnings = scanEmptyAllowlistPolicyWarnings(params.cfg, {
doctorFixCommand: params.doctorFixCommand,
extraWarningsForAccount: emptyAllowlistHooks.extraWarningsForAccount,
shouldSkipDefaultEmptyGroupAllowlistWarning: emptyAllowlistHooks.shouldSkipDefaultEmptyGroupAllowlistWarning
}).filter((warning) => !channelPluginRuntime.isWarningBlockedByChannelPlugin(warning, channelPluginBlockerHits));
if (emptyAllowlistWarnings.length > 0) {
const { sanitizeForLog } = await import("./terminal-core/ansi.js");
warnings.push(emptyAllowlistWarnings.map((line) => sanitizeForLog(line)).join("\n"));
}
}
if (hasToolsBySenderKey(params.cfg)) {
const { collectLegacyToolsBySenderWarnings, scanLegacyToolsBySenderKeys } = await import("./legacy-tools-by-sender-CF9ixQCN.js");
const toolsBySenderHits = scanLegacyToolsBySenderKeys(params.cfg);
if (toolsBySenderHits.length > 0) warnings.push(collectLegacyToolsBySenderWarnings({
hits: toolsBySenderHits,
doctorFixCommand: params.doctorFixCommand
}).join("\n"));
}
if (hasConfiguredSafeBins(params.cfg)) {
const { collectExecSafeBinCoverageWarnings, collectExecSafeBinTrustedDirHintWarnings, scanExecSafeBinCoverage, scanExecSafeBinTrustedDirHints } = await import("./exec-safe-bins-HHwphFI3.js");
const safeBinCoverage = scanExecSafeBinCoverage(params.cfg);
if (safeBinCoverage.length > 0) warnings.push(collectExecSafeBinCoverageWarnings({
hits: safeBinCoverage,
doctorFixCommand: params.doctorFixCommand
}).join("\n"));
const safeBinTrustedDirHints = scanExecSafeBinTrustedDirHints(params.cfg);
if (safeBinTrustedDirHints.length > 0) warnings.push(collectExecSafeBinTrustedDirHintWarnings(safeBinTrustedDirHints).join("\n"));
}
const { collectStaleOAuthProfileShadowWarnings, scanStaleOAuthProfileShadows } = await import("./stale-oauth-profile-shadows-DxgZowvj.js");
const staleOAuthProfileShadows = await scanStaleOAuthProfileShadows({
cfg: params.cfg,
env
});
if (staleOAuthProfileShadows.length > 0) warnings.push(collectStaleOAuthProfileShadowWarnings({
hits: staleOAuthProfileShadows,
doctorFixCommand: params.doctorFixCommand
}).join("\n"));
const { collectStaleConfiguredAuthOrderWarnings } = await import("./stale-auth-order-DIg3yeMO.js");
warnings.push(...collectStaleConfiguredAuthOrderWarnings({
cfg: params.cfg,
doctorFixCommand: params.doctorFixCommand,
env
}));
const { repairMergedGatewayOwnerProfile } = await import("./user-profiles-owner-migration-B_JxqgwW.js");
warnings.push(...repairMergedGatewayOwnerProfile({
env,
shouldRepair: false
}).warnings);
return {
infoNotes,
warningNotes: warnings
};
}
//#endregion
export { resolveDoctorChannelPreviewConfig as n, collectDoctorPreviewNotes as t };