mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 03:50:20 +00:00
fix(cli): keep status json startup path lean
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
import { hasPotentialConfiguredChannels } from "../channels/config-presence.js";
|
||||
import { resolveCommandConfigWithSecrets } from "../cli/command-config-resolution.js";
|
||||
import { getStatusCommandSecretTargetIds } from "../cli/command-secret-targets.js";
|
||||
import { readBestEffortConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
import type { collectChannelStatusIssues as collectChannelStatusIssuesFn } from "../infra/channels-status-issues.js";
|
||||
import { resolveOsSummary } from "../infra/os-summary.js";
|
||||
@@ -24,6 +21,13 @@ let statusUpdateModulePromise: Promise<typeof import("./status.update.js")> | un
|
||||
let statusScanRuntimeModulePromise: Promise<typeof import("./status.scan.runtime.js")> | undefined;
|
||||
let gatewayCallModulePromise: Promise<typeof import("../gateway/call.js")> | undefined;
|
||||
let statusSummaryModulePromise: Promise<typeof import("./status.summary.js")> | undefined;
|
||||
let configModulePromise: Promise<typeof import("../config/config.js")> | undefined;
|
||||
let commandConfigResolutionModulePromise:
|
||||
| Promise<typeof import("../cli/command-config-resolution.js")>
|
||||
| undefined;
|
||||
let commandSecretTargetsModulePromise:
|
||||
| Promise<typeof import("../cli/command-secret-targets.js")>
|
||||
| undefined;
|
||||
|
||||
function loadStatusScanDepsRuntimeModule() {
|
||||
statusScanDepsRuntimeModulePromise ??= import("./status.scan.deps.runtime.js");
|
||||
@@ -55,6 +59,21 @@ function loadStatusSummaryModule() {
|
||||
return statusSummaryModulePromise;
|
||||
}
|
||||
|
||||
function loadConfigModule() {
|
||||
configModulePromise ??= import("../config/config.js");
|
||||
return configModulePromise;
|
||||
}
|
||||
|
||||
function loadCommandConfigResolutionModule() {
|
||||
commandConfigResolutionModulePromise ??= import("../cli/command-config-resolution.js");
|
||||
return commandConfigResolutionModulePromise;
|
||||
}
|
||||
|
||||
function loadCommandSecretTargetsModule() {
|
||||
commandSecretTargetsModulePromise ??= import("../cli/command-secret-targets.js");
|
||||
return commandSecretTargetsModulePromise;
|
||||
}
|
||||
|
||||
async function resolveStatusChannelsStatus(params: {
|
||||
cfg: OpenClawConfig;
|
||||
gatewayReachable: boolean;
|
||||
@@ -142,12 +161,14 @@ export async function collectStatusScanOverview(params: {
|
||||
} = await loadStatusScanCommandConfig({
|
||||
commandName: params.commandName,
|
||||
allowMissingConfigFastPath: params.allowMissingConfigFastPath,
|
||||
readBestEffortConfig,
|
||||
readBestEffortConfig: async () => (await loadConfigModule()).readBestEffortConfig(),
|
||||
resolveConfig: async (loadedConfig) =>
|
||||
await resolveCommandConfigWithSecrets({
|
||||
await (
|
||||
await loadCommandConfigResolutionModule()
|
||||
).resolveCommandConfigWithSecrets({
|
||||
config: loadedConfig,
|
||||
commandName: params.commandName,
|
||||
targetIds: getStatusCommandSecretTargetIds(),
|
||||
targetIds: (await loadCommandSecretTargetsModule()).getStatusCommandSecretTargetIds(),
|
||||
mode: "read_only_status",
|
||||
...(params.runtime ? { runtime: params.runtime } : {}),
|
||||
}),
|
||||
|
||||
@@ -12,7 +12,7 @@ vi.mock("../gateway/connection-details.js", () => ({
|
||||
buildGatewayConnectionDetailsWithResolvers: mocks.buildGatewayConnectionDetailsWithResolvers,
|
||||
}));
|
||||
|
||||
vi.mock("../gateway/probe-auth.js", () => ({
|
||||
vi.mock("../gateway/probe-target.js", () => ({
|
||||
resolveGatewayProbeTarget: mocks.resolveGatewayProbeTarget,
|
||||
}));
|
||||
|
||||
|
||||
@@ -2,19 +2,25 @@ import { existsSync } from "node:fs";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
import { buildGatewayConnectionDetailsWithResolvers } from "../gateway/connection-details.js";
|
||||
import { normalizeControlUiBasePath } from "../gateway/control-ui-shared.js";
|
||||
import { resolveGatewayProbeTarget } from "../gateway/probe-auth.js";
|
||||
import { probeGateway } from "../gateway/probe.js";
|
||||
import { resolveGatewayProbeTarget } from "../gateway/probe-target.js";
|
||||
import type { probeGateway as probeGatewayFn } from "../gateway/probe.js";
|
||||
import type { MemoryProviderStatus } from "../memory-host-sdk/engine-storage.js";
|
||||
import { pickGatewaySelfPresence } from "./gateway-presence.js";
|
||||
export { pickGatewaySelfPresence } from "./gateway-presence.js";
|
||||
|
||||
let gatewayProbeModulePromise: Promise<typeof import("./status.gateway-probe.js")> | undefined;
|
||||
let probeGatewayModulePromise: Promise<typeof import("../gateway/probe.js")> | undefined;
|
||||
|
||||
function loadGatewayProbeModule() {
|
||||
gatewayProbeModulePromise ??= import("./status.gateway-probe.js");
|
||||
return gatewayProbeModulePromise;
|
||||
}
|
||||
|
||||
function loadProbeGatewayModule() {
|
||||
probeGatewayModulePromise ??= import("../gateway/probe.js");
|
||||
return probeGatewayModulePromise;
|
||||
}
|
||||
|
||||
export type MemoryStatusSnapshot = MemoryProviderStatus & {
|
||||
agentId: string;
|
||||
};
|
||||
@@ -34,7 +40,7 @@ export type GatewayProbeSnapshot = {
|
||||
password?: string;
|
||||
};
|
||||
gatewayProbeAuthWarning?: string;
|
||||
gatewayProbe: Awaited<ReturnType<typeof probeGateway>> | null;
|
||||
gatewayProbe: Awaited<ReturnType<typeof probeGatewayFn>> | null;
|
||||
gatewayReachable: boolean;
|
||||
gatewaySelf: ReturnType<typeof pickGatewaySelfPresence>;
|
||||
gatewayCallOverrides?: {
|
||||
@@ -96,12 +102,16 @@ export async function resolveGatewayProbeSnapshot(params: {
|
||||
: { auth: {}, warning: undefined };
|
||||
let gatewayProbeAuthWarning = gatewayProbeAuthResolution.warning;
|
||||
const gatewayProbe = shouldProbe
|
||||
? await probeGateway({
|
||||
url: gatewayConnection.url,
|
||||
auth: gatewayProbeAuthResolution.auth,
|
||||
timeoutMs: Math.min(params.opts.all ? 5000 : 2500, params.opts.timeoutMs ?? 10_000),
|
||||
detailLevel: params.opts.detailLevel ?? "presence",
|
||||
}).catch(() => null)
|
||||
? await loadProbeGatewayModule()
|
||||
.then(({ probeGateway }) =>
|
||||
probeGateway({
|
||||
url: gatewayConnection.url,
|
||||
auth: gatewayProbeAuthResolution.auth,
|
||||
timeoutMs: Math.min(params.opts.all ? 5000 : 2500, params.opts.timeoutMs ?? 10_000),
|
||||
detailLevel: params.opts.detailLevel ?? "presence",
|
||||
}),
|
||||
)
|
||||
.catch(() => null)
|
||||
: null;
|
||||
if (
|
||||
(params.opts.mergeAuthWarningIntoProbeError ?? true) &&
|
||||
|
||||
@@ -15,6 +15,7 @@ export type StatusScanSharedMocks = {
|
||||
getStatusSummary: UnknownMock;
|
||||
getMemorySearchManager: UnknownMock;
|
||||
buildGatewayConnectionDetails: UnknownMock;
|
||||
resolveGatewayProbeTarget: UnknownMock;
|
||||
probeGateway: UnknownMock;
|
||||
resolveGatewayProbeAuthResolution: UnknownMock;
|
||||
ensurePluginRegistryLoaded: UnknownMock;
|
||||
@@ -32,6 +33,11 @@ export function createStatusScanSharedMocks(configPathLabel: string): StatusScan
|
||||
getStatusSummary: vi.fn(),
|
||||
getMemorySearchManager: vi.fn(),
|
||||
buildGatewayConnectionDetails: vi.fn(),
|
||||
resolveGatewayProbeTarget: vi.fn(() => ({
|
||||
mode: "local",
|
||||
gatewayMode: "local",
|
||||
remoteUrlMissing: false,
|
||||
})),
|
||||
probeGateway: vi.fn(),
|
||||
resolveGatewayProbeAuthResolution: vi.fn(),
|
||||
ensurePluginRegistryLoaded: vi.fn(),
|
||||
@@ -224,6 +230,9 @@ export async function loadStatusScanModuleForTest(
|
||||
vi.doMock("../gateway/probe.js", () => ({
|
||||
probeGateway: mocks.probeGateway,
|
||||
}));
|
||||
vi.doMock("../gateway/probe-target.js", () => ({
|
||||
resolveGatewayProbeTarget: mocks.resolveGatewayProbeTarget,
|
||||
}));
|
||||
vi.doMock("./status.gateway-probe.js", () => createStatusGatewayProbeModuleMock(mocks));
|
||||
vi.doMock("../gateway/connection-details.js", () => ({
|
||||
buildGatewayConnectionDetails: mocks.buildGatewayConnectionDetails,
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveGatewayCredentialsWithSecretInputs } from "./call.js";
|
||||
import {
|
||||
type ExplicitGatewayAuth,
|
||||
isGatewaySecretRefUnavailableError,
|
||||
resolveGatewayProbeCredentialsFromConfig,
|
||||
} from "./credentials.js";
|
||||
|
||||
export type GatewayProbeTargetResolution = {
|
||||
gatewayMode: "local" | "remote";
|
||||
mode: "local" | "remote";
|
||||
remoteUrlMissing: boolean;
|
||||
};
|
||||
export { resolveGatewayProbeTarget } from "./probe-target.js";
|
||||
export type { GatewayProbeTargetResolution } from "./probe-target.js";
|
||||
|
||||
function buildGatewayProbeCredentialPolicy(params: {
|
||||
cfg: OpenClawConfig;
|
||||
@@ -53,18 +48,6 @@ function resolveGatewayProbeWarning(error: unknown): string | undefined {
|
||||
return buildUnresolvedProbeAuthWarning(error.path);
|
||||
}
|
||||
|
||||
export function resolveGatewayProbeTarget(cfg: OpenClawConfig): GatewayProbeTargetResolution {
|
||||
const gatewayMode = cfg.gateway?.mode === "remote" ? "remote" : "local";
|
||||
const remoteUrlRaw =
|
||||
typeof cfg.gateway?.remote?.url === "string" ? cfg.gateway.remote.url.trim() : "";
|
||||
const remoteUrlMissing = gatewayMode === "remote" && !remoteUrlRaw;
|
||||
return {
|
||||
gatewayMode,
|
||||
mode: gatewayMode === "remote" && !remoteUrlMissing ? "remote" : "local",
|
||||
remoteUrlMissing,
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveGatewayProbeAuth(params: {
|
||||
cfg: OpenClawConfig;
|
||||
mode: "local" | "remote";
|
||||
@@ -81,13 +64,15 @@ export async function resolveGatewayProbeAuthWithSecretInputs(params: {
|
||||
explicitAuth?: ExplicitGatewayAuth;
|
||||
}): Promise<{ token?: string; password?: string }> {
|
||||
const policy = buildGatewayProbeCredentialPolicy(params);
|
||||
return await resolveGatewayCredentialsWithSecretInputs({
|
||||
config: policy.config,
|
||||
env: policy.env,
|
||||
explicitAuth: policy.explicitAuth,
|
||||
modeOverride: policy.modeOverride,
|
||||
remoteTokenFallback: policy.remoteTokenFallback,
|
||||
});
|
||||
return await import("./call.js").then(({ resolveGatewayCredentialsWithSecretInputs }) =>
|
||||
resolveGatewayCredentialsWithSecretInputs({
|
||||
config: policy.config,
|
||||
env: policy.env,
|
||||
explicitAuth: policy.explicitAuth,
|
||||
modeOverride: policy.modeOverride,
|
||||
remoteTokenFallback: policy.remoteTokenFallback,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export async function resolveGatewayProbeAuthSafeWithSecretInputs(params: {
|
||||
|
||||
19
src/gateway/probe-target.ts
Normal file
19
src/gateway/probe-target.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
export type GatewayProbeTargetResolution = {
|
||||
gatewayMode: "local" | "remote";
|
||||
mode: "local" | "remote";
|
||||
remoteUrlMissing: boolean;
|
||||
};
|
||||
|
||||
export function resolveGatewayProbeTarget(cfg: OpenClawConfig): GatewayProbeTargetResolution {
|
||||
const gatewayMode = cfg.gateway?.mode === "remote" ? "remote" : "local";
|
||||
const remoteUrlRaw =
|
||||
typeof cfg.gateway?.remote?.url === "string" ? cfg.gateway.remote.url.trim() : "";
|
||||
const remoteUrlMissing = gatewayMode === "remote" && !remoteUrlRaw;
|
||||
return {
|
||||
gatewayMode,
|
||||
mode: gatewayMode === "remote" && !remoteUrlMissing ? "remote" : "local",
|
||||
remoteUrlMissing,
|
||||
};
|
||||
}
|
||||
@@ -206,7 +206,7 @@ function normalizeLookupResults(results: LookupResult): readonly LookupAddress[]
|
||||
if (Array.isArray(results)) {
|
||||
return results;
|
||||
}
|
||||
return [results as LookupAddress];
|
||||
return [results];
|
||||
}
|
||||
|
||||
export function createPinnedLookup(params: {
|
||||
|
||||
Reference in New Issue
Block a user