@mininglamp-oss/octo-runtime 1.1.1 → 1.1.3

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.
Files changed (59) hide show
  1. package/apps/cli/dist/build-info.json +2 -2
  2. package/apps/cli/dist/manifest.json +5 -0
  3. package/node_modules/@mininglamp-oss/octo-runtime-acp-client/package.json +3 -3
  4. package/node_modules/@mininglamp-oss/octo-runtime-adapter-acp/package.json +4 -4
  5. package/node_modules/@mininglamp-oss/octo-runtime-adapter-antigravity/package.json +3 -3
  6. package/node_modules/@mininglamp-oss/octo-runtime-adapter-claude-code/package.json +3 -3
  7. package/node_modules/@mininglamp-oss/octo-runtime-adapter-codebuddy/package.json +4 -4
  8. package/node_modules/@mininglamp-oss/octo-runtime-adapter-codex/package.json +3 -3
  9. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.d.ts +54 -0
  10. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.js +399 -0
  11. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.d.ts +14 -0
  12. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.js +156 -0
  13. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.d.ts +29 -0
  14. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.js +273 -0
  15. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.d.ts +27 -0
  16. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.js +161 -0
  17. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/package.json +17 -0
  18. package/node_modules/@mininglamp-oss/octo-runtime-adapter-hermes/package.json +2 -2
  19. package/node_modules/@mininglamp-oss/octo-runtime-adapter-kimi-code/package.json +2 -2
  20. package/node_modules/@mininglamp-oss/octo-runtime-adapter-mcode/package.json +2 -2
  21. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.d.ts +24 -0
  22. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.js +181 -0
  23. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.d.ts +9 -0
  24. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.js +24 -8
  25. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/index.js +229 -225
  26. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/package.json +3 -3
  27. package/node_modules/@mininglamp-oss/octo-runtime-adapter-opencode/package.json +4 -4
  28. package/node_modules/@mininglamp-oss/octo-runtime-adapter-qodercli/package.json +2 -2
  29. package/node_modules/@mininglamp-oss/octo-runtime-adapter-qoderclicn/package.json +2 -2
  30. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.d.ts +4 -0
  31. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.js +5 -6
  32. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/package.json +2 -2
  33. package/node_modules/@mininglamp-oss/octo-runtime-adapter-zcode-gui/package.json +3 -3
  34. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/build-info.json +2 -2
  35. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/manifest.json +5 -0
  36. package/node_modules/@mininglamp-oss/octo-runtime-cli/package.json +23 -22
  37. package/node_modules/@mininglamp-oss/octo-runtime-cross-service/package.json +1 -1
  38. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.d.ts +1 -1
  39. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.js +13 -9
  40. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/package.json +3 -3
  41. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/invocation-manifest.js +31 -8
  42. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/package.json +4 -4
  43. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/config-schema.json +1 -1
  44. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/application/im-channel.js +2 -1
  45. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/contracts.d.ts +2 -0
  46. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/execution/dispatcher.js +24 -0
  47. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/channel.js +5 -4
  48. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/contexts.js +2 -2
  49. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.d.ts +5 -2
  50. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.js +19 -5
  51. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/normalize.d.ts +1 -1
  52. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/normalize.js +5 -2
  53. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/package.json +6 -6
  54. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/package.json +5 -5
  55. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/package.json +2 -2
  56. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/package.json +4 -4
  57. package/node_modules/@mininglamp-oss/octo-runtime-protocol/package.json +1 -1
  58. package/package.json +27 -25
  59. package/packages/octo-runtime-extra-channel-gateway/config-schema.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-kimi-code",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
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.1"
12
+ "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.3"
13
13
  }
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-mcode",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
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.1"
12
+ "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.3"
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
- function errorFromFrame(frame) {
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 Error(`${message}${requestId}${code}`);
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
- throw new Error("OpenClaw Gateway returned an invalid hello response");
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?.status === "accepted") {
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()) {