UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

232 lines (231 loc) • 12.2 kB
import { D as withPluginCache, a as createPluginCache } from "./plugin-cache-BABafcXD.mjs"; import { r as createLazyRuntimeModule } from "./lazy-runtime-CJrzFzqU.mjs"; import { r as defaultRuntime } from "./runtime-DlO3PTAd.mjs"; import { t as _usingCtx } from "./usingCtx-DwOBYOJf.mjs"; import { t as runOutsidePluginRuntimeGenerationScope } from "./generation-scope-tH9UXyLm.mjs"; import { i as appendSystemAgentAuditEntry } from "./audit-FqvDk6WR.mjs"; import { stat } from "node:fs/promises"; //#region src/system-agent/hosted-setup.runtime.ts const loadSetupShared = createLazyRuntimeModule(() => import("./setup.shared-FFZuR7xZ.mjs")); const GATEWAY_WRITE_POLICY = { mode: "none", reason: "Gateway setup defers runtime apply until explicit restart" }; function requireLocalGateway(config) { if (config.gateway?.mode === "local") return; throw new Error("Hosted Gateway setup manages only a local Gateway. Use `openclaw onboard` for fresh setup or `openclaw configure` for the mode question, then retry after selecting local mode."); } function createHostedWizardRuntime(runtime) { return { ...runtime, exit: (code) => { throw new Error(`hosted wizard exited with code ${String(code)}`); } }; } async function runHostedSetup(params) { try { var _usingCtx$1 = _usingCtx(); const cache = _usingCtx$1.a(createPluginCache()); return await runOutsidePluginRuntimeGenerationScope(() => withPluginCache(cache, async () => { const { readSetupConfigFileSnapshot, writeWizardConfigFile } = await loadSetupShared(); const snapshot = await readSetupConfigFileSnapshot(); if (!snapshot.exists || !snapshot.valid || !snapshot.hash) throw new Error(`${params.label} requires a valid saved config snapshot. On the machine running OpenClaw, run \`openclaw doctor --fix\` and resolve any remaining validation errors; then retry.`); const baseConfig = snapshot.sourceConfig ?? snapshot.config; const runtime = params.runtime ?? createHostedWizardRuntime(defaultRuntime); const result = await params.run({ baseConfig, runtime }); if ("keptCurrent" in result) return "kept-current"; await params.beforePersistentApply(runtime); const committed = await writeWizardConfigFile(result.nextConfig, { allowConfigSizeDrop: false, baseHash: snapshot.hash, ...params.afterWrite ? { afterWrite: params.afterWrite } : {} }); await result.afterWrite?.(committed.path); return "applied"; })); } catch (_) { _usingCtx$1.e = _; } finally { await _usingCtx$1.d(); } } async function runHostedChannelSetup(channel, prompter, beforePersistentApply, runtime, assertPersistentEffectCurrent) { const { createChannelSetupHooks, setupChannels } = await import("./channel-setup-Ba_UavNN.mjs"); return await runHostedSetup({ label: "Channel setup", runtime, beforePersistentApply, run: async ({ baseConfig, runtime: setupRuntime }) => { const channelSetup = createChannelSetupHooks({ runtime: setupRuntime, beforePersistentEffect: async () => await beforePersistentApply(setupRuntime) }); return { nextConfig: await setupChannels(baseConfig, setupRuntime, prompter, { initialSelection: [channel], forceAllowFromChannels: [channel], allowIMessageInstall: true, allowSignalInstall: true, deferStatusUntilSelection: true, quickstartDefaults: true, skipDmPolicyPrompt: true, skipConfirm: true, beforePersistentEffect: async () => await beforePersistentApply(setupRuntime), ...assertPersistentEffectCurrent ? { assertPersistentEffectCurrent } : {}, onPostWriteHook: channelSetup.onPostWriteHook }), afterWrite: async (configPath) => await channelSetup.runPostWriteHooks(configPath) }; } }); } async function runHostedSkillsSetup(prompter, beforePersistentApply, runtime) { const [{ setupSkills }, { resolveSystemAgentOnboardingTarget }] = await Promise.all([import("./onboard-skills-CgU6irfz.mjs"), import("./onboard-agent-target-DHswuRSu.mjs")]); return await runHostedSetup({ label: "Skills setup", runtime, beforePersistentApply, run: async ({ baseConfig, runtime: setupRuntime }) => ({ nextConfig: await setupSkills(baseConfig, resolveSystemAgentOnboardingTarget(baseConfig).workspaceDir, setupRuntime, prompter, { beforePersistentEffect: async () => await beforePersistentApply(setupRuntime) }) }) }); } async function runHostedSearchSetup(prompter, beforePersistentApply, runtime) { const { runSearchSetupFlow } = await import("./search-setup-Db5MOgrw.mjs"); return await runHostedSetup({ label: "Web search setup", runtime, beforePersistentApply, run: async ({ baseConfig, runtime: setupRuntime }) => { const result = await runSearchSetupFlow(baseConfig, setupRuntime, prompter, { preserveDisabledSearchState: false, beforePersistentEffect: async () => await beforePersistentApply(setupRuntime) }); if (result.outcome === "install-failed") { const failure = result.reason === "timed-out" ? "timed out" : "failed"; throw new Error(`web search provider ${result.providerId} installation ${failure}`); } if (result.outcome === "kept-current") { if (result.reason === "user-skipped" || result.reason === "provider-install-skipped") return { keptCurrent: true }; const reason = result.reason === "no-providers" ? "no web search providers are available under the current plugin policy" : "the selected web search provider is no longer available"; throw new Error(reason); } return { nextConfig: result.config }; } }); } async function runHostedGatewaySetup(prompter, beforePersistentApply, runtime) { const [{ configureGatewayForSetup }, { resolveQuickstartGatewayDefaults }] = await Promise.all([import("./setup.gateway-config-BtlkpOQP.mjs"), loadSetupShared()]); return await runHostedSetup({ label: "Gateway setup", runtime, beforePersistentApply, afterWrite: GATEWAY_WRITE_POLICY, run: async ({ baseConfig }) => { requireLocalGateway(baseConfig); return { nextConfig: (await configureGatewayForSetup({ flow: "advanced", baseConfig, nextConfig: baseConfig, quickstartGateway: resolveQuickstartGatewayDefaults(baseConfig), prompter })).nextConfig }; } }); } async function runHostedMemoryImport(prompter, beforePersistentApply, onProviderOutcome) { const [{ readSetupConfigFileSnapshot }, { resolveSystemAgentOnboardingTarget }] = await Promise.all([loadSetupShared(), import("./onboard-agent-target-DHswuRSu.mjs")]); const snapshot = await readSetupConfigFileSnapshot(); if (!snapshot.exists || !snapshot.valid || !snapshot.hash) throw new Error("Memory import requires a valid saved config. Run `openclaw doctor --fix`, then retry."); const baseHash = snapshot.hash; const config = snapshot.config; const { agentId, workspaceDir: workspace } = resolveSystemAgentOnboardingTarget(config); try { if (!(await stat(workspace)).isDirectory()) return { status: "workspace-missing", providers: [], workspace }; } catch (error) { const code = error.code; if (code === "ENOENT" || code === "ENOTDIR") return { status: "workspace-missing", providers: [], workspace }; throw error; } const { runSetupMemoryImportStep } = await import("./setup.memory-import-DpGgl2uJ.mjs"); const runtime = createHostedWizardRuntime(defaultRuntime); return await runSetupMemoryImportStep({ config, agentId, prompter, runtime, beforeApply: async () => { await beforePersistentApply(runtime); const currentSnapshot = await readSetupConfigFileSnapshot(); if (!currentSnapshot.exists || !currentSnapshot.valid || currentSnapshot.hash !== baseHash) throw new Error("configuration changed during memory import; nothing further was copied — retry to import against the current setup"); }, onProviderOutcome }); } function hasConfirmedMemoryImportCount(provider) { return provider.copiesIndeterminate !== true; } function formatItemCount(count) { return `${count} ${count === 1 ? "item" : "items"}`; } function formatMemoryImportProviders(providers) { return providers.map((provider) => `${provider.label} (${formatItemCount(provider.migrated)})`).join(", "); } async function auditMemoryImport(providers, appendAuditEntry = appendSystemAgentAuditEntry) { const importedProviders = providers.filter(hasConfirmedMemoryImportCount).filter((provider) => provider.migrated > 0); const indeterminateProviders = providers.filter((provider) => provider.copiesIndeterminate === true); const importedItems = importedProviders.reduce((total, provider) => total + provider.migrated, 0); if (importedItems === 0 && indeterminateProviders.length === 0) return; const providerSummary = formatMemoryImportProviders(importedProviders); const indeterminateSummary = indeterminateProviders.map((provider) => `${provider.label} (copy count indeterminate)`).join(", "); await appendAuditEntry({ operation: "memory.import", summary: indeterminateProviders.length > 0 ? `Memory import failed partway via chat: ${[providerSummary ? `confirmed ${providerSummary}` : "", indeterminateSummary].filter(Boolean).join("; ")}` : `Imported memory via chat: ${providerSummary}`, details: { ...indeterminateProviders.length > 0 ? { confirmedItems: importedItems, copiesIndeterminate: true } : { totalItems: importedItems }, providers: providers.map((provider) => provider.copiesIndeterminate === true ? { providerId: provider.providerId, copiesIndeterminate: true } : { providerId: provider.providerId, items: provider.migrated, ...provider.failure ? { partial: true } : {} }) } }); } async function renderMemoryImport(outcome, appendAuditEntry = appendSystemAgentAuditEntry) { if (!outcome) return "Memory import did not complete. No outcome was reported, and no success was assumed."; if (outcome.status === "workspace-missing") return [`Memory import is unavailable because the default agent workspace does not exist at ${outcome.workspace}.`, "Finish onboarding first with `openclaw onboard`, then retry."].join("\n"); if (outcome.status === "nothing-to-import") return "Nothing to import — no new memory files were detected in supported local agent homes."; if (outcome.status === "skipped") return "Memory import skipped. Nothing was copied."; const confirmedProviders = outcome.providers.filter(hasConfirmedMemoryImportCount); const importedProviders = confirmedProviders.filter((provider) => provider.migrated > 0); const failedProviders = confirmedProviders.filter((provider) => provider.failure); const indeterminateProviders = outcome.providers.filter((provider) => provider.copiesIndeterminate === true); const importedItems = importedProviders.reduce((total, provider) => total + provider.migrated, 0); const providerSummary = formatMemoryImportProviders(importedProviders); await auditMemoryImport(outcome.providers, appendAuditEntry); if (importedItems === 0) { if (indeterminateProviders.length > 0) return ["Memory import failed partway. Some files may have been copied before the failure.", `Copy counts are indeterminate for: ${indeterminateProviders.map((provider) => provider.label).join(", ")}.`].join("\n"); if (failedProviders.length > 0) return ["Memory import did not complete. No files were copied.", `Failed providers: ${failedProviders.map((provider) => provider.label).join(", ")}.`].join("\n"); return "Nothing was imported. No files were copied."; } const sourceSummary = importedProviders.length === 1 ? importedProviders[0].label : providerSummary; return [`Imported ${formatItemCount(importedItems)} from ${sourceSummary}.`, indeterminateProviders.length > 0 ? `Memory import failed partway for ${indeterminateProviders.map((provider) => provider.label).join(", ")}; some additional files may have been copied before the failure.` : failedProviders.length > 0 ? `Some providers did not complete: ${failedProviders.map((provider) => provider.label).join(", ")}.` : ""].filter(Boolean).join("\n"); } //#endregion export { GATEWAY_WRITE_POLICY, auditMemoryImport, renderMemoryImport, requireLocalGateway, runHostedChannelSetup, runHostedGatewaySetup, runHostedMemoryImport, runHostedSearchSetup, runHostedSetup, runHostedSkillsSetup };