mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-13 10:26:11 +00:00
docs: document gateway reload helpers
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// Gateway config reload planner.
|
||||
// Maps changed config paths to hot-reload actions, no-ops, or full restarts.
|
||||
import { type ChannelId, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import {
|
||||
getActivePluginChannelRegistryVersion,
|
||||
@@ -146,6 +148,8 @@ function listReloadRules(): ReloadRule[] {
|
||||
const registry = getActivePluginRegistry();
|
||||
const activeRegistryVersion = getActivePluginRegistryVersion();
|
||||
const channelRegistryVersion = getActivePluginChannelRegistryVersion();
|
||||
// Plugin/channel reload rules are process-stable until the active registry
|
||||
// version changes; cache them to keep every config diff cheap.
|
||||
if (
|
||||
registry !== cachedRegistry ||
|
||||
activeRegistryVersion !== cachedActiveRegistryVersion ||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Gateway config hot-reload watcher.
|
||||
// Diffs config/plugin install snapshots and dispatches hot reload or restart plans.
|
||||
import chokidar from "chokidar";
|
||||
import type { ConfigWriteNotification } from "../config/io.js";
|
||||
import { formatConfigIssueLines } from "../config/issue-format.js";
|
||||
@@ -126,6 +128,8 @@ export function startGatewayConfigReloader(opts: {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
// Coalesce filesystem/write-listener bursts into one reload pass. Config
|
||||
// writes often touch temp and final paths in quick succession.
|
||||
if (debounceTimer) {
|
||||
clearTimeout(debounceTimer);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Gateway credential planning helpers.
|
||||
// Classifies local/remote auth inputs before SecretRef resolution.
|
||||
import { normalizeOptionalString } from "../../packages/normalization-core/src/string-coerce.js";
|
||||
import { containsEnvVarReference } from "../config/env-substitution.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
@@ -145,6 +147,8 @@ export function createGatewayCredentialPlan(params: {
|
||||
const remoteUrlConfigured = Boolean(trimToUndefined(remote?.url));
|
||||
const tailscaleRemoteExposure =
|
||||
gateway?.tailscale?.mode === "serve" || gateway?.tailscale?.mode === "funnel";
|
||||
// Remote credential surfaces are considered active when the gateway is used
|
||||
// remotely or when local auth may be borrowed for a published Tailscale URL.
|
||||
const remoteConfiguredSurface = remoteMode || remoteUrlConfigured || tailscaleRemoteExposure;
|
||||
// Remote credentials may borrow local auth credentials only when the remote
|
||||
// surface exists but no explicit remote/env candidate can satisfy the mode.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Gateway iOS exec-approval push delivery.
|
||||
// Sends APNs request/resolution wakes to paired operator devices.
|
||||
import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce";
|
||||
import { getRuntimeConfig } from "../config/io.js";
|
||||
import {
|
||||
@@ -149,6 +151,8 @@ async function resolveDeliveryPlan(params: {
|
||||
isTargetVisible?: (target: ApprovalPushTarget) => boolean;
|
||||
log: GatewayLikeLogger;
|
||||
}): Promise<DeliveryPlan> {
|
||||
// Request delivery requires current approval scope; resolution delivery may
|
||||
// target prior node ids so existing notification badges can be cleared.
|
||||
const targets = params.explicitNodeIds?.length
|
||||
? await loadRegisteredTargets({ deviceIds: params.explicitNodeIds })
|
||||
: await resolvePairedTargets({
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Gateway exec approval manager.
|
||||
// Tracks pending operator decisions and short-lived resolved approval records.
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { resolveExpiresAtMsFromDurationMs } from "@openclaw/normalization-core/number-coercion";
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
@@ -18,6 +20,8 @@ function unrefTimer(timer: ReturnType<typeof setTimeout>): void {
|
||||
}
|
||||
|
||||
function scheduleResolvedEntryCleanup(cleanup: () => void): void {
|
||||
// Resolved approvals stay visible briefly so node.invoke sanitizers can
|
||||
// consume a just-approved id after the UI decision races the command retry.
|
||||
const timer = setTimeout(cleanup, RESOLVED_ENTRY_GRACE_MS);
|
||||
unrefTimer(timer);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Gateway model-pricing cache state.
|
||||
// Stores normalized pricing rows and source-health failures for runtime reads.
|
||||
import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id";
|
||||
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
|
||||
import { normalizeModelRef } from "../agents/model-selection.js";
|
||||
@@ -42,6 +44,8 @@ const sourceFailures = new Map<
|
||||
>();
|
||||
|
||||
function modelPricingCacheKey(provider: string, model: string): string {
|
||||
// Keys accept both provider/model and provider-prefixed model ids so external
|
||||
// catalogs can be queried without double-prefixing.
|
||||
const providerId = normalizeProviderId(provider);
|
||||
const modelId = model.trim();
|
||||
if (!providerId || !modelId) {
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
// Gateway model-pricing refresh and normalization.
|
||||
// Fetches, normalizes, and schedules cached pricing for model usage estimates.
|
||||
import type { ModelCatalogCost } from "@openclaw/model-catalog-core/model-catalog-types";
|
||||
import {
|
||||
normalizeOptionalString,
|
||||
resolvePrimaryStringValue,
|
||||
} from "../../packages/normalization-core/src/string-coerce.js";
|
||||
import { DEFAULT_PROVIDER } from "../agents/defaults.js";
|
||||
import {
|
||||
buildModelAliasIndex,
|
||||
@@ -26,7 +32,6 @@ import {
|
||||
} from "../plugins/plugin-metadata-snapshot.js";
|
||||
import type { PluginMetadataRegistryView } from "../plugins/plugin-metadata-snapshot.types.js";
|
||||
import type { PluginRegistrySnapshot } from "../plugins/plugin-registry.js";
|
||||
import { normalizeOptionalString, resolvePrimaryStringValue } from "../../packages/normalization-core/src/string-coerce.js";
|
||||
import {
|
||||
clearGatewayModelPricingCacheState,
|
||||
clearGatewayModelPricingFailures,
|
||||
@@ -180,6 +185,8 @@ function isTimeoutError(error: unknown): boolean {
|
||||
}
|
||||
|
||||
function createPricingFetchSignal(signal: AbortSignal | undefined): AbortSignal {
|
||||
// Pricing fetches are background refreshes; bound them so startup/reload
|
||||
// cannot leave an unbounded network request alive.
|
||||
const timeoutSignal = AbortSignal.timeout(FETCH_TIMEOUT_MS);
|
||||
return signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Gateway hot-reload handlers.
|
||||
// Applies config reload plans to hooks, cron, heartbeat, plugins, channels, and restarts.
|
||||
import { disposeAllSessionMcpRuntimes } from "../agents/agent-bundle-mcp-tools.js";
|
||||
import {
|
||||
getActiveEmbeddedRunCount,
|
||||
@@ -102,6 +104,8 @@ async function disposeMcpRuntimesWithTimeout(params: {
|
||||
onWarn: (message: string) => void;
|
||||
label: string;
|
||||
}) {
|
||||
// MCP runtime disposal may need async provider cleanup. Bound it so config
|
||||
// reload can proceed and report the stale runtime risk.
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
const disposePromise = params.dispose().catch((error: unknown) => {
|
||||
params.onWarn(`${params.label} failed: ${String(error)}`);
|
||||
|
||||
Reference in New Issue
Block a user