forked from openclaw/openclaw
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprobe.ts
More file actions
138 lines (131 loc) · 4.55 KB
/
Copy pathprobe.ts
File metadata and controls
138 lines (131 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import type { OpenClawConfig } from "../../config/types.js";
import type { GatewayProbeResult } from "../../gateway/probe.js";
import { formatErrorMessage } from "../../infra/errors.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import { withProgress } from "../progress.js";
type GatewayStatusProbeKind = "connect" | "read";
type GatewayStatusRequireRpcProbeResult = {
ok: true;
authProbe: GatewayProbeResult | null;
};
type GatewayStatusProbeResult = GatewayProbeResult | GatewayStatusRequireRpcProbeResult;
const probeGatewayModuleLoader = createLazyImportLoader(() => import("../../gateway/probe.js"));
async function loadProbeGatewayModule(): Promise<typeof import("../../gateway/probe.js")> {
return await probeGatewayModuleLoader.load();
}
function resolveProbeFailureMessage(result: {
error?: string | null;
close?: { code: number; reason: string } | null;
}): string {
const closeHint = result.close
? `gateway closed (${result.close.code}): ${result.close.reason}`
: null;
if (closeHint && (!result.error || result.error === "timeout")) {
return closeHint;
}
return result.error ?? closeHint ?? "gateway probe failed";
}
function resolveGatewayStatusProbeDetails(result: GatewayStatusProbeResult) {
return "authProbe" in result ? result.authProbe : result;
}
function readRuntimeVersionFromStatusPayload(payload: unknown): string | null {
if (!payload || typeof payload !== "object") {
return null;
}
const runtimeVersion = (payload as { runtimeVersion?: unknown }).runtimeVersion;
return typeof runtimeVersion === "string" && runtimeVersion.trim().length > 0
? runtimeVersion.trim()
: null;
}
export async function probeGatewayStatus(opts: {
url: string;
token?: string;
password?: string;
config?: OpenClawConfig;
tlsFingerprint?: string;
timeoutMs: number;
preauthHandshakeTimeoutMs?: number;
json?: boolean;
requireRpc?: boolean;
configPath?: string;
}) {
const kind = (opts.requireRpc ? "read" : "connect") satisfies GatewayStatusProbeKind;
try {
let statusRuntimeVersion: string | null = null;
const result = await withProgress<GatewayStatusProbeResult>(
{
label: "Checking gateway status...",
indeterminate: true,
enabled: opts.json !== true,
},
async () => {
const { probeGateway } = await loadProbeGatewayModule();
const probeOpts = {
url: opts.url,
auth: {
token: opts.token,
password: opts.password,
},
tlsFingerprint: opts.tlsFingerprint,
...(opts.preauthHandshakeTimeoutMs !== undefined
? { preauthHandshakeTimeoutMs: opts.preauthHandshakeTimeoutMs }
: {}),
timeoutMs: opts.timeoutMs,
includeDetails: false,
};
if (opts.requireRpc) {
const { callGateway } = await import("../../gateway/call.js");
const statusPayload = await callGateway({
url: opts.url,
token: opts.token,
password: opts.password,
tlsFingerprint: opts.tlsFingerprint,
...(opts.config ? { config: opts.config } : {}),
method: "status",
timeoutMs: opts.timeoutMs,
...(opts.configPath ? { configPath: opts.configPath } : {}),
});
statusRuntimeVersion = readRuntimeVersionFromStatusPayload(statusPayload);
const authProbe = await probeGateway(probeOpts).catch(() => null);
return { ok: true as const, authProbe };
}
return await probeGateway(probeOpts);
},
);
const probeDetails = resolveGatewayStatusProbeDetails(result);
const auth = probeDetails?.auth;
const server = probeDetails?.server;
const serverSummary = server ? { server } : {};
const version = server?.version ?? ("authProbe" in result ? statusRuntimeVersion : null);
if (result.ok) {
return {
ok: true,
kind,
capability:
kind === "read"
? auth?.capability && auth.capability !== "unknown"
? auth.capability
: "read_only"
: auth?.capability,
auth,
...serverSummary,
...(version != null ? { version } : {}),
} as const;
}
return {
ok: false,
kind,
capability: auth?.capability,
auth,
...serverSummary,
...(version != null ? { version } : {}),
error: resolveProbeFailureMessage(result),
} as const;
} catch (err) {
return {
ok: false,
kind,
error: formatErrorMessage(err),
} as const;
}
}