@mininglamp-oss/octo-runtime 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/cli/dist/build-info.json +2 -2
- package/apps/cli/dist/manifest.json +5 -0
- package/node_modules/@mininglamp-oss/octo-runtime-acp-client/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-acp/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-antigravity/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-claude-code/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-codebuddy/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-codex/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.d.ts +54 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.js +399 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.d.ts +14 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.js +156 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.d.ts +29 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.js +273 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.d.ts +27 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.js +161 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/package.json +17 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-hermes/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-kimi-code/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-mcode/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.d.ts +24 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.js +181 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.d.ts +9 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.js +24 -8
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/index.js +229 -225
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-opencode/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-qodercli/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-qoderclicn/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.d.ts +4 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.js +5 -6
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-zcode-gui/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/build-info.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/manifest.json +5 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/package.json +23 -22
- package/node_modules/@mininglamp-oss/octo-runtime-cross-service/package.json +1 -1
- package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.d.ts +1 -1
- package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.js +13 -9
- package/node_modules/@mininglamp-oss/octo-runtime-executor-core/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/application/im-channel.js +2 -1
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/contracts.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/execution/dispatcher.js +24 -0
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/contexts.js +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.d.ts +5 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.js +19 -5
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/normalize.js +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/package.json +6 -6
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/package.json +5 -5
- package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-protocol/package.json +1 -1
- package/package.json +27 -25
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mininglamp-oss/octo-runtime-adapter-kimi-code",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./dist/index.js",
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@mininglamp-oss/octo-runtime-adapter-acp": "1.1.
|
|
12
|
+
"@mininglamp-oss/octo-runtime-adapter-acp": "1.1.2"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mininglamp-oss/octo-runtime-adapter-mcode",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./dist/index.js",
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@mininglamp-oss/octo-runtime-adapter-acp": "1.1.
|
|
12
|
+
"@mininglamp-oss/octo-runtime-adapter-acp": "1.1.2"
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ApprovalMode } from "@mininglamp-oss/octo-runtime-protocol";
|
|
2
|
+
type JsonRecord = Record<string, unknown>;
|
|
3
|
+
export type GatewayTerminal = "completed" | "failed" | "cancelled";
|
|
4
|
+
export interface GatewayContract {
|
|
5
|
+
version: string;
|
|
6
|
+
family: "legacy" | "session-permissions";
|
|
7
|
+
approvalTransport: boolean;
|
|
8
|
+
scopes?: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
export interface GatewayPermissionPolicy {
|
|
11
|
+
effective: "ask" | "full_access";
|
|
12
|
+
fallbackReason?: string;
|
|
13
|
+
}
|
|
14
|
+
/** 每条连接以真实 hello 选择固定源码核对过的合同;v4 不表示请求字段相同。 */
|
|
15
|
+
export declare function resolveGatewayContract(value: unknown): GatewayContract;
|
|
16
|
+
/** 用户已授权 ask 不可用时向 full 回退;原始请求与 Context 不随 effective 改写。 */
|
|
17
|
+
export declare function resolveGatewayPermission(contract: GatewayContract, requested: ApprovalMode): GatewayPermissionPolicy;
|
|
18
|
+
export declare function gatewayCreateParams(contract: GatewayContract, policy: GatewayPermissionPolicy, params: JsonRecord, requestId: string, thinking: unknown): JsonRecord;
|
|
19
|
+
export declare function gatewayLegacyPermissionParams(key: string): JsonRecord;
|
|
20
|
+
/** 同一执行的中间回执在 RPC 等待、终态归一化和对账中使用同一判定。 */
|
|
21
|
+
export declare function isGatewayRunPending(value: unknown): boolean;
|
|
22
|
+
/** RPC 最终回执、lifecycle 与 agent.wait 共用归一化;超时归因优先于 abort 清理。 */
|
|
23
|
+
export declare function gatewayTerminal(value: unknown, source: "wait" | "final" | "lifecycle"): GatewayTerminal | undefined;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
const LEGACY_RELEASES = [
|
|
2
|
+
"2026.6.11",
|
|
3
|
+
"2026.7.1",
|
|
4
|
+
"2026.7.1-1",
|
|
5
|
+
"2026.7.1-2",
|
|
6
|
+
"2026.7.33",
|
|
7
|
+
"2026.7.34",
|
|
8
|
+
"2026.7.35"
|
|
9
|
+
];
|
|
10
|
+
const SESSION_PERMISSION_RELEASES = [
|
|
11
|
+
"2026.8.1",
|
|
12
|
+
"2026.8.2",
|
|
13
|
+
"2026.8.33",
|
|
14
|
+
"2026.8.34",
|
|
15
|
+
"2026.8.35",
|
|
16
|
+
"2026.9.1",
|
|
17
|
+
"2026.9.2",
|
|
18
|
+
"2026.9.3",
|
|
19
|
+
"2026.9.4",
|
|
20
|
+
"2026.9.5",
|
|
21
|
+
"2026.9.6",
|
|
22
|
+
"2026.9.7",
|
|
23
|
+
"2026.9.8",
|
|
24
|
+
"2026.9.9",
|
|
25
|
+
"2026.9.33",
|
|
26
|
+
"2026.10.1",
|
|
27
|
+
"2026.10.2",
|
|
28
|
+
"2026.10.3",
|
|
29
|
+
"2026.10.4",
|
|
30
|
+
"2026.10.5"
|
|
31
|
+
];
|
|
32
|
+
const RELEASES = new Map([
|
|
33
|
+
...LEGACY_RELEASES.map((version) => [version, "legacy"]),
|
|
34
|
+
...SESSION_PERMISSION_RELEASES.map((version) => [version, "session-permissions"])
|
|
35
|
+
]);
|
|
36
|
+
const EXECUTION_METHODS = [
|
|
37
|
+
"agents.list",
|
|
38
|
+
"sessions.create",
|
|
39
|
+
"sessions.messages.subscribe",
|
|
40
|
+
"agent",
|
|
41
|
+
"agent.wait",
|
|
42
|
+
"sessions.abort"
|
|
43
|
+
];
|
|
44
|
+
const APPROVAL_METHODS = ["exec.approval.list", "exec.approval.resolve"];
|
|
45
|
+
const APPROVAL_EVENTS = ["exec.approval.requested", "exec.approval.resolved"];
|
|
46
|
+
function record(value) {
|
|
47
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
48
|
+
? value
|
|
49
|
+
: undefined;
|
|
50
|
+
}
|
|
51
|
+
function strings(value) {
|
|
52
|
+
return Array.isArray(value)
|
|
53
|
+
? value.filter((item) => typeof item === "string")
|
|
54
|
+
: [];
|
|
55
|
+
}
|
|
56
|
+
/** 每条连接以真实 hello 选择固定源码核对过的合同;v4 不表示请求字段相同。 */
|
|
57
|
+
export function resolveGatewayContract(value) {
|
|
58
|
+
const hello = record(value);
|
|
59
|
+
const rawVersion = record(hello?.server)?.version;
|
|
60
|
+
const version = typeof rawVersion === "string" && /^v?\d{4}\.\d{1,2}\.\d{1,2}(?:-\d{1,2})?$/.test(rawVersion)
|
|
61
|
+
? rawVersion.replace(/^v/, "")
|
|
62
|
+
: "unknown";
|
|
63
|
+
const fail = (reason) => {
|
|
64
|
+
const displayVersion = typeof rawVersion === "string" && /^[A-Za-z0-9.+_-]{1,80}$/.test(rawVersion)
|
|
65
|
+
? rawVersion
|
|
66
|
+
: version;
|
|
67
|
+
throw new Error(`OPENCLAW_COMPATIBILITY_UNSUPPORTED: OpenClaw ${displayVersion}: ${reason}`);
|
|
68
|
+
};
|
|
69
|
+
if (hello?.protocol !== 4)
|
|
70
|
+
fail("unsupported Gateway protocol");
|
|
71
|
+
const family = RELEASES.get(version);
|
|
72
|
+
if (!family)
|
|
73
|
+
return fail("server.version has no verified contract");
|
|
74
|
+
const features = record(hello?.features);
|
|
75
|
+
const methods = strings(features?.methods);
|
|
76
|
+
const events = strings(features?.events);
|
|
77
|
+
for (const method of EXECUTION_METHODS) {
|
|
78
|
+
if (!methods.includes(method))
|
|
79
|
+
fail(`missing required method ${method}`);
|
|
80
|
+
}
|
|
81
|
+
if (family === "legacy" && !methods.includes("sessions.patch"))
|
|
82
|
+
fail("missing required method sessions.patch");
|
|
83
|
+
if (!events.includes("agent"))
|
|
84
|
+
fail("missing required agent event stream");
|
|
85
|
+
const auth = record(hello?.auth);
|
|
86
|
+
return {
|
|
87
|
+
version,
|
|
88
|
+
family,
|
|
89
|
+
approvalTransport: APPROVAL_METHODS.every((method) => methods.includes(method)) &&
|
|
90
|
+
APPROVAL_EVENTS.every((event) => events.includes(event)),
|
|
91
|
+
...(Array.isArray(auth?.scopes) ? { scopes: strings(auth.scopes) } : {})
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** 用户已授权 ask 不可用时向 full 回退;原始请求与 Context 不随 effective 改写。 */
|
|
95
|
+
export function resolveGatewayPermission(contract, requested) {
|
|
96
|
+
if (requested === "assisted")
|
|
97
|
+
throw new Error("APPROVAL_MODE_UNSUPPORTED: OpenClaw has no qualified assisted policy");
|
|
98
|
+
const fallbackReason = requested !== "ask"
|
|
99
|
+
? undefined
|
|
100
|
+
: contract.family === "legacy"
|
|
101
|
+
? "legacy_human_reviewer_unconfirmed"
|
|
102
|
+
: !contract.approvalTransport
|
|
103
|
+
? "approval_transport_unavailable"
|
|
104
|
+
: contract.scopes &&
|
|
105
|
+
!contract.scopes.includes("operator.approvals") &&
|
|
106
|
+
!contract.scopes.includes("operator.admin")
|
|
107
|
+
? "approval_scope_unavailable"
|
|
108
|
+
: undefined;
|
|
109
|
+
const effective = requested === "ask" && !fallbackReason ? "ask" : "full_access";
|
|
110
|
+
if (effective === "full_access" &&
|
|
111
|
+
contract.family === "session-permissions" &&
|
|
112
|
+
contract.scopes &&
|
|
113
|
+
!contract.scopes.includes("operator.admin")) {
|
|
114
|
+
throw new Error(`OPENCLAW_PERMISSION_UNAVAILABLE: OpenClaw ${contract.version}: full requires operator.admin`);
|
|
115
|
+
}
|
|
116
|
+
return { effective, ...(fallbackReason ? { fallbackReason } : {}) };
|
|
117
|
+
}
|
|
118
|
+
export function gatewayCreateParams(contract, policy, params, requestId, thinking) {
|
|
119
|
+
if (contract.family === "legacy")
|
|
120
|
+
return { ...params };
|
|
121
|
+
return {
|
|
122
|
+
...params,
|
|
123
|
+
permissionMode: policy.effective === "full_access" ? "full" : "guarded",
|
|
124
|
+
idempotencyKey: `${requestId}-session`,
|
|
125
|
+
...(typeof thinking === "string" ? { thinkingLevel: thinking } : {})
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export function gatewayLegacyPermissionParams(key) {
|
|
129
|
+
// 旧字段不能区分 ask 与 auto reviewer,使用已授权的免审批回退,不伪称人工 ask。
|
|
130
|
+
return { key, execSecurity: "full", execAsk: "off" };
|
|
131
|
+
}
|
|
132
|
+
/** 同一执行的中间回执在 RPC 等待、终态归一化和对账中使用同一判定。 */
|
|
133
|
+
export function isGatewayRunPending(value) {
|
|
134
|
+
const response = record(value);
|
|
135
|
+
return (response?.pendingError === true ||
|
|
136
|
+
["accepted", "in_flight", "queued", "pending", "running"].includes(String(response?.status)));
|
|
137
|
+
}
|
|
138
|
+
/** RPC 最终回执、lifecycle 与 agent.wait 共用归一化;超时归因优先于 abort 清理。 */
|
|
139
|
+
export function gatewayTerminal(value, source) {
|
|
140
|
+
const response = record(value);
|
|
141
|
+
const meta = record(record(response?.result)?.meta);
|
|
142
|
+
const status = typeof response?.status === "string"
|
|
143
|
+
? response.status
|
|
144
|
+
: source === "lifecycle"
|
|
145
|
+
? response?.phase === "end"
|
|
146
|
+
? "ok"
|
|
147
|
+
: response?.phase === "error"
|
|
148
|
+
? "error"
|
|
149
|
+
: undefined
|
|
150
|
+
: undefined;
|
|
151
|
+
if (!status || isGatewayRunPending(response))
|
|
152
|
+
return undefined;
|
|
153
|
+
const reason = response?.stopReason ?? meta?.stopReason;
|
|
154
|
+
const timeoutPhase = response?.timeoutPhase ?? meta?.timeoutPhase;
|
|
155
|
+
const hardTimeout = ["preflight", "provider", "post_turn"].includes(String(timeoutPhase)) ||
|
|
156
|
+
(status === "timeout" &&
|
|
157
|
+
reason !== "restart" &&
|
|
158
|
+
(response?.providerStarted ?? meta?.providerStarted) === true);
|
|
159
|
+
if (hardTimeout)
|
|
160
|
+
return "failed";
|
|
161
|
+
const livenessValue = response?.livenessState ?? meta?.livenessState;
|
|
162
|
+
const liveness = typeof livenessValue === "string" ? livenessValue.trim().toLowerCase() : "";
|
|
163
|
+
const ended = typeof response?.endedAt === "number" && Number.isFinite(response.endedAt);
|
|
164
|
+
if (source === "wait" && status === "timeout" && !ended)
|
|
165
|
+
return undefined;
|
|
166
|
+
if (liveness === "blocked" || reason === "timeout")
|
|
167
|
+
return "failed";
|
|
168
|
+
if (reason === "restart" ||
|
|
169
|
+
reason === "aborted" ||
|
|
170
|
+
(status !== "ok" && (reason === "rpc" || reason === "stop")) ||
|
|
171
|
+
response?.aborted === true ||
|
|
172
|
+
meta?.aborted === true)
|
|
173
|
+
return "cancelled";
|
|
174
|
+
if (liveness === "abandoned")
|
|
175
|
+
return "failed";
|
|
176
|
+
if (status === "ok")
|
|
177
|
+
return "completed";
|
|
178
|
+
if (status === "error" || status === "timeout")
|
|
179
|
+
return "failed";
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
@@ -17,6 +17,9 @@ export interface OpenClawGatewayEvent {
|
|
|
17
17
|
export interface OpenClawGatewayHello {
|
|
18
18
|
type: "hello-ok";
|
|
19
19
|
protocol: number;
|
|
20
|
+
server?: {
|
|
21
|
+
version?: string;
|
|
22
|
+
};
|
|
20
23
|
features?: {
|
|
21
24
|
methods?: string[];
|
|
22
25
|
events?: string[];
|
|
@@ -27,6 +30,12 @@ export interface OpenClawGatewayHello {
|
|
|
27
30
|
role?: string;
|
|
28
31
|
};
|
|
29
32
|
}
|
|
33
|
+
/** 保留原生错误码和 RPC,兼容判断不依赖拼接字符串或记录完整 details。 */
|
|
34
|
+
export declare class OpenClawGatewayRpcError extends Error {
|
|
35
|
+
readonly code: string | undefined;
|
|
36
|
+
readonly method: string;
|
|
37
|
+
constructor(code: string | undefined, method: string, message: string);
|
|
38
|
+
}
|
|
30
39
|
export declare function createOpenClawDeviceIdentity(): OpenClawDeviceIdentity;
|
|
31
40
|
/** Minimal authenticated Gateway RPC client. One instance owns exactly one WebSocket. */
|
|
32
41
|
export declare class OpenClawGatewayClient {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash, generateKeyPairSync, randomUUID, sign } from "node:crypto";
|
|
2
2
|
import WebSocket from "ws";
|
|
3
|
+
import { isGatewayRunPending } from "./compatibility.js";
|
|
3
4
|
const PROTOCOL_VERSION = 4;
|
|
4
5
|
const CLIENT_ID = "cli";
|
|
5
6
|
const CLIENT_MODE = "cli";
|
|
@@ -24,13 +25,24 @@ function messageText(data) {
|
|
|
24
25
|
return Buffer.concat(data).toString("utf8");
|
|
25
26
|
return Buffer.from(data).toString("utf8");
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
+
/** 保留原生错误码和 RPC,兼容判断不依赖拼接字符串或记录完整 details。 */
|
|
29
|
+
export class OpenClawGatewayRpcError extends Error {
|
|
30
|
+
code;
|
|
31
|
+
method;
|
|
32
|
+
constructor(code, method, message) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.code = code;
|
|
35
|
+
this.method = method;
|
|
36
|
+
this.name = "OpenClawGatewayRpcError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function errorFromFrame(frame, method) {
|
|
28
40
|
const native = record(frame.error);
|
|
29
41
|
const message = typeof native?.message === "string" ? native.message : "OpenClaw Gateway request failed";
|
|
30
42
|
const details = record(native?.details);
|
|
31
43
|
const requestId = typeof details?.requestId === "string" ? ` (pairing request ${details.requestId})` : "";
|
|
32
44
|
const code = typeof native?.code === "string" ? ` [${native.code}]` : "";
|
|
33
|
-
return new
|
|
45
|
+
return new OpenClawGatewayRpcError(typeof native?.code === "string" ? native.code : undefined, method, `${message}${requestId}${code}`);
|
|
34
46
|
}
|
|
35
47
|
function withRequestId(error, requestId) {
|
|
36
48
|
if (error.message.includes("request_id="))
|
|
@@ -171,8 +183,10 @@ export class OpenClawGatewayClient {
|
|
|
171
183
|
device: deviceProof(this.#options.device, this.#options.token, nonce, signedAt)
|
|
172
184
|
}, { timeoutMs }).then((value) => {
|
|
173
185
|
const hello = record(value);
|
|
174
|
-
if (!hello || hello.type !== "hello-ok")
|
|
175
|
-
|
|
186
|
+
if (!hello || hello.type !== "hello-ok") {
|
|
187
|
+
finish(new Error("OpenClaw Gateway returned an invalid hello response"));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
176
190
|
this.#hello = hello;
|
|
177
191
|
finish(undefined, hello);
|
|
178
192
|
}, (error) => finish(error instanceof Error ? error : new Error("OpenClaw Gateway connect request failed")));
|
|
@@ -180,6 +194,8 @@ export class OpenClawGatewayClient {
|
|
|
180
194
|
});
|
|
181
195
|
}
|
|
182
196
|
request(method, params, options = {}) {
|
|
197
|
+
if (options.signal?.aborted)
|
|
198
|
+
return Promise.reject(new Error(`OpenClaw Gateway request ${method} aborted`));
|
|
183
199
|
const socket = this.#socket;
|
|
184
200
|
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
185
201
|
return Promise.reject(new Error("OpenClaw Gateway is not connected"));
|
|
@@ -187,6 +203,7 @@ export class OpenClawGatewayClient {
|
|
|
187
203
|
const id = randomUUID();
|
|
188
204
|
return new Promise((resolve, reject) => {
|
|
189
205
|
const pending = {
|
|
206
|
+
method,
|
|
190
207
|
resolve,
|
|
191
208
|
reject,
|
|
192
209
|
expectFinal: options.expectFinal === true,
|
|
@@ -199,6 +216,7 @@ export class OpenClawGatewayClient {
|
|
|
199
216
|
pending.timer = setTimeout(() => {
|
|
200
217
|
if (!this.#pending.delete(id))
|
|
201
218
|
return;
|
|
219
|
+
pending.cleanup?.();
|
|
202
220
|
reject(new Error(`OpenClaw Gateway request ${method} timed out after ${timeoutMs}ms`));
|
|
203
221
|
}, timeoutMs);
|
|
204
222
|
pending.timer.unref?.();
|
|
@@ -211,8 +229,6 @@ export class OpenClawGatewayClient {
|
|
|
211
229
|
pending.cleanup?.();
|
|
212
230
|
reject(new Error(`OpenClaw Gateway request ${method} aborted`));
|
|
213
231
|
};
|
|
214
|
-
if (options.signal?.aborted)
|
|
215
|
-
return abort();
|
|
216
232
|
options.signal?.addEventListener("abort", abort, { once: true });
|
|
217
233
|
pending.cleanup = () => options.signal?.removeEventListener("abort", abort);
|
|
218
234
|
this.#pending.set(id, pending);
|
|
@@ -278,7 +294,7 @@ export class OpenClawGatewayClient {
|
|
|
278
294
|
if (!pending)
|
|
279
295
|
return;
|
|
280
296
|
const payload = record(frame.payload);
|
|
281
|
-
if (frame.ok === true && pending.expectFinal && payload
|
|
297
|
+
if (frame.ok === true && pending.expectFinal && isGatewayRunPending(payload)) {
|
|
282
298
|
pending.accepted?.(frame.payload);
|
|
283
299
|
return;
|
|
284
300
|
}
|
|
@@ -289,7 +305,7 @@ export class OpenClawGatewayClient {
|
|
|
289
305
|
if (frame.ok === true)
|
|
290
306
|
pending.resolve(frame.payload);
|
|
291
307
|
else
|
|
292
|
-
pending.reject(errorFromFrame(frame));
|
|
308
|
+
pending.reject(errorFromFrame(frame, pending.method));
|
|
293
309
|
}
|
|
294
310
|
#failPending(error) {
|
|
295
311
|
for (const pending of this.#pending.values()) {
|