mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
refactor: extract gateway client package (#87797)
* refactor: extract gateway client package * chore: drop generated gateway package artifacts * refactor: move gateway protocol package * refactor: remove old gateway protocol tree * test: keep auth compat split in run mode * test: expose gateway wrapper options for internals * fix: watch moved gateway package sources * test: normalize slash command import guard * chore: teach knip gateway package entries * ci: route gateway client package checks * fix: reuse ipaddr for gateway client hosts * fix: sync gateway protocol usage schema
This commit is contained in:
committed by
GitHub
parent
fd8353012f
commit
b1117d9862
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -31,7 +31,7 @@
|
||||
/src/gateway/**/*secret*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/security-path*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/resolve-configured-secret-input-string*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/protocol/**/*secret*.ts @openclaw/openclaw-secops
|
||||
/packages/gateway-protocol/src/**/*secret*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/server-methods/secrets*.ts @openclaw/openclaw-secops
|
||||
/src/agents/*auth*.ts @openclaw/openclaw-secops
|
||||
/src/agents/**/*auth*.ts @openclaw/openclaw-secops
|
||||
|
||||
@@ -19,7 +19,7 @@ paths:
|
||||
- src/config/types.channel*.ts
|
||||
- src/gateway/server-channel*.ts
|
||||
- src/gateway/server-methods/channels.ts
|
||||
- src/gateway/protocol/schema/channels.ts
|
||||
- packages/gateway-protocol/src/schema/channels.ts
|
||||
- src/infra/channel-*.ts
|
||||
- src/infra/exec-approval-channel-runtime.ts
|
||||
- src/infra/outbound/channel-*.ts
|
||||
|
||||
@@ -30,7 +30,7 @@ paths:
|
||||
- src/gateway/**/*auth*.ts
|
||||
- src/gateway/*secret*.ts
|
||||
- src/gateway/**/*secret*.ts
|
||||
- src/gateway/protocol/**/*secret*.ts
|
||||
- packages/gateway-protocol/src/**/*secret*.ts
|
||||
- src/gateway/resolve-configured-secret-input-string*.ts
|
||||
- src/gateway/security-path*.ts
|
||||
- src/gateway/server-methods/secrets*.ts
|
||||
|
||||
@@ -30,7 +30,7 @@ paths:
|
||||
- src/gateway/**/*auth*.ts
|
||||
- src/gateway/*secret*.ts
|
||||
- src/gateway/**/*secret*.ts
|
||||
- src/gateway/protocol/**/*secret*.ts
|
||||
- packages/gateway-protocol/src/**/*secret*.ts
|
||||
- src/gateway/resolve-configured-secret-input-string*.ts
|
||||
- src/gateway/security-path*.ts
|
||||
- src/gateway/server-methods/secrets*.ts
|
||||
|
||||
@@ -15,7 +15,7 @@ query-filters:
|
||||
|
||||
paths:
|
||||
- src/gateway/method-scopes.ts
|
||||
- src/gateway/protocol
|
||||
- packages/gateway-protocol/src
|
||||
- src/gateway/server-methods
|
||||
- src/gateway/server-methods.ts
|
||||
- src/gateway/server-methods-list.ts
|
||||
|
||||
3
.github/labeler.yml
vendored
3
.github/labeler.yml
vendored
@@ -188,7 +188,7 @@
|
||||
- "ui/**"
|
||||
- "src/gateway/control-ui.ts"
|
||||
- "src/gateway/control-ui-shared.ts"
|
||||
- "src/gateway/protocol/**"
|
||||
- "packages/gateway-protocol/src/**"
|
||||
- "src/gateway/server-methods/chat.ts"
|
||||
- "src/infra/control-ui-assets.ts"
|
||||
|
||||
@@ -196,6 +196,7 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "src/gateway/**"
|
||||
- "packages/gateway-protocol/src/**"
|
||||
- "src/daemon/**"
|
||||
- "docs/gateway/**"
|
||||
|
||||
|
||||
@@ -106,13 +106,13 @@ on:
|
||||
- "src/gateway/**/*auth*.ts"
|
||||
- "src/gateway/*secret*.ts"
|
||||
- "src/gateway/**/*secret*.ts"
|
||||
- "src/gateway/protocol/**/*secret*.ts"
|
||||
- "packages/gateway-protocol/src/**/*secret*.ts"
|
||||
- "src/gateway/resolve-configured-secret-input-string*.ts"
|
||||
- "src/gateway/security-path*.ts"
|
||||
- "src/gateway/server-methods/secrets*.ts"
|
||||
- "src/gateway/server-startup-memory.ts"
|
||||
- "src/gateway/method-scopes.ts"
|
||||
- "src/gateway/protocol/**"
|
||||
- "packages/gateway-protocol/src/**"
|
||||
- "src/gateway/server-methods/**"
|
||||
- "src/gateway/server-methods.ts"
|
||||
- "src/gateway/server-methods-list.ts"
|
||||
@@ -244,14 +244,14 @@ jobs:
|
||||
src/config/*)
|
||||
config=true
|
||||
;;
|
||||
src/gateway/protocol/*secret*.ts|src/gateway/server-methods/secrets*.ts)
|
||||
packages/gateway-protocol/src/*secret*.ts|packages/gateway-protocol/src/**/*secret*.ts|src/gateway/server-methods/secrets*.ts)
|
||||
core_auth_secrets=true
|
||||
gateway=true
|
||||
;;
|
||||
src/agents/*auth*.ts|src/agents/auth-health*.ts|src/agents/auth-profiles|src/agents/auth-profiles/*|src/agents/bash-tools.exec-host-shared.ts|src/agents/sandbox|src/agents/sandbox.ts|src/agents/sandbox-*.ts|src/agents/sandbox/*|src/cron/service/jobs.ts|src/cron/stagger.ts|src/gateway/*auth*.ts|src/gateway/*secret*.ts|src/gateway/resolve-configured-secret-input-string*.ts|src/gateway/security-path*.ts|src/infra/secret-file*.ts|src/secrets/*|src/security/*)
|
||||
core_auth_secrets=true
|
||||
;;
|
||||
src/gateway/method-scopes.ts|src/gateway/protocol/*|src/gateway/server-methods/*|src/gateway/server-methods.ts|src/gateway/server-methods-list.ts)
|
||||
packages/gateway-protocol/src/*|packages/gateway-protocol/src/**/*|src/gateway/method-scopes.ts|src/gateway/server-methods/*|src/gateway/server-methods.ts|src/gateway/server-methods-list.ts)
|
||||
gateway=true
|
||||
;;
|
||||
packages/memory-host-sdk/*|src/commands/doctor-cron-dreaming-payload-migration.ts|src/commands/doctor-memory-search.ts|src/gateway/server-startup-memory.ts|src/memory/*|src/memory-host-sdk/*)
|
||||
|
||||
@@ -35,9 +35,9 @@ Skills own workflows; root owns hard policy and routing.
|
||||
|
||||
## Map
|
||||
|
||||
- Core TS: `src/`, `ui/`, `packages/`; plugins: `extensions/`; SDK: `src/plugin-sdk/*`; channels: `src/channels/*`; loader: `src/plugins/*`; protocol: `src/gateway/protocol/*`; docs/apps: `docs/`, `apps/`.
|
||||
- Core TS: `src/`, `ui/`, `packages/`; plugins: `extensions/`; SDK: `src/plugin-sdk/*`; channels: `src/channels/*`; loader: `src/plugins/*`; protocol: `packages/gateway-protocol/*`; docs/apps: `docs/`, `apps/`.
|
||||
- Installers: sibling `../openclaw.ai`.
|
||||
- Scoped guides: `extensions/`, `src/{plugin-sdk,channels,plugins,gateway,gateway/protocol,agents}/`, `test/helpers*/`, `docs/`, `ui/`, `scripts/`.
|
||||
- Scoped guides: `extensions/`, `src/{plugin-sdk,channels,plugins,gateway,agents}/`, `packages/`, `test/helpers*/`, `docs/`, `ui/`, `scripts/`.
|
||||
|
||||
## Docs
|
||||
|
||||
|
||||
@@ -168,6 +168,14 @@ const config = {
|
||||
entry: ["src/index.ts!", "src/*.ts!", "src/harness/**/*.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-client": {
|
||||
entry: ["src/index.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-protocol": {
|
||||
entry: ["src/index.ts!", "src/schema.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/*": {
|
||||
entry: ["index.js!", "scripts/postinstall.js!"],
|
||||
project: ["index.js!", "scripts/**/*.js!"],
|
||||
|
||||
@@ -53,8 +53,8 @@ Authoritative advertised **discovery** inventory lives in
|
||||
|
||||
## Where the schemas live
|
||||
|
||||
- Source: `src/gateway/protocol/schema.ts`
|
||||
- Runtime validators (AJV): `src/gateway/protocol/index.ts`
|
||||
- Source: `packages/gateway-protocol/src/schema.ts`
|
||||
- Runtime validators (AJV): `packages/gateway-protocol/src/index.ts`
|
||||
- Advertised feature/discovery registry: `src/gateway/server-methods-list.ts`
|
||||
- Server handshake + method dispatch: `src/gateway/server.impl.ts`
|
||||
- Node client: `src/gateway/client.ts`
|
||||
@@ -195,7 +195,7 @@ Example: add a new `system.echo` request that returns `{ ok: true, text }`.
|
||||
|
||||
1. **Schema (source of truth)**
|
||||
|
||||
Add to `src/gateway/protocol/schema.ts`:
|
||||
Add to `packages/gateway-protocol/src/schema.ts`:
|
||||
|
||||
```ts
|
||||
export const SystemEchoParamsSchema = Type.Object(
|
||||
@@ -223,7 +223,7 @@ export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;
|
||||
|
||||
2. **Validation**
|
||||
|
||||
In `src/gateway/protocol/index.ts`, export an AJV validator:
|
||||
In `packages/gateway-protocol/src/index.ts`, export an AJV validator:
|
||||
|
||||
```ts
|
||||
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);
|
||||
@@ -272,7 +272,7 @@ Unknown frame types are preserved as raw payloads for forward compatibility.
|
||||
|
||||
## Versioning + compatibility
|
||||
|
||||
- `PROTOCOL_VERSION` lives in `src/gateway/protocol/version.ts`.
|
||||
- `PROTOCOL_VERSION` lives in `packages/gateway-protocol/src/version.ts`.
|
||||
- Clients send `minProtocol` + `maxProtocol`; the server rejects ranges that
|
||||
do not include its current protocol.
|
||||
- The Swift models keep unknown frame types to avoid breaking older clients.
|
||||
|
||||
@@ -104,7 +104,7 @@ within their overall connection budget instead of surfacing it as a terminal
|
||||
handshake failure.
|
||||
|
||||
`server`, `features`, `snapshot`, and `policy` are all required by the schema
|
||||
(`src/gateway/protocol/schema/frames.ts`). `auth` is also required and reports
|
||||
(`packages/gateway-protocol/src/schema/frames.ts`). `auth` is also required and reports
|
||||
the negotiated role/scopes. `pluginSurfaceUrls` is optional and maps plugin
|
||||
surface names, such as `canvas`, to scoped hosted URLs.
|
||||
|
||||
@@ -648,7 +648,7 @@ terminal summary, and sanitized error text.
|
||||
|
||||
## Versioning
|
||||
|
||||
- `PROTOCOL_VERSION` lives in `src/gateway/protocol/version.ts`.
|
||||
- `PROTOCOL_VERSION` lives in `packages/gateway-protocol/src/version.ts`.
|
||||
- Clients send `minProtocol` + `maxProtocol`; the server rejects ranges that
|
||||
do not include its current protocol. Current clients and servers require
|
||||
protocol v4.
|
||||
@@ -664,8 +664,8 @@ stable across protocol v4 and are the expected baseline for third-party clients.
|
||||
|
||||
| Constant | Default | Source |
|
||||
| ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `PROTOCOL_VERSION` | `4` | `src/gateway/protocol/version.ts` |
|
||||
| `MIN_CLIENT_PROTOCOL_VERSION` | `4` | `src/gateway/protocol/version.ts` |
|
||||
| `PROTOCOL_VERSION` | `4` | `packages/gateway-protocol/src/version.ts` |
|
||||
| `MIN_CLIENT_PROTOCOL_VERSION` | `4` | `packages/gateway-protocol/src/version.ts` |
|
||||
| Request timeout (per RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) |
|
||||
| Preauth / connect-challenge timeout | `15_000` ms | `src/gateway/handshake-timeouts.ts` (config/env can raise the paired server/client budget) |
|
||||
| Initial reconnect backoff | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) |
|
||||
@@ -818,7 +818,7 @@ Migration target:
|
||||
|
||||
This protocol exposes the **full gateway API** (status, channels, models, chat,
|
||||
agent, sessions, nodes, approvals, etc.). The exact surface is defined by the
|
||||
TypeBox schemas in `src/gateway/protocol/schema.ts`.
|
||||
TypeBox schemas in `packages/gateway-protocol/src/schema.ts`.
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
@@ -1623,7 +1623,7 @@
|
||||
"start": "node openclaw.mjs",
|
||||
"test": "node scripts/test-projects.mjs",
|
||||
"test:all": "pnpm lint && pnpm build && pnpm test && pnpm test:e2e && pnpm test:live && pnpm test:docker:all",
|
||||
"test:auth:compat": "node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server.auth.compat-baseline.test.ts src/gateway/client.test.ts src/gateway/reconnect-gating.test.ts src/gateway/protocol/connect-error-details.test.ts",
|
||||
"test:auth:compat": "node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server.auth.compat-baseline.test.ts src/gateway/client.test.ts src/gateway/reconnect-gating.test.ts && node scripts/run-vitest.mjs run packages/gateway-protocol/src/connect-error-details.test.ts",
|
||||
"test:build:singleton": "node scripts/test-built-plugin-singleton.mjs",
|
||||
"test:build:status-message-runtime": "node scripts/test-built-status-message-runtime.mjs",
|
||||
"test:bundled": "node scripts/run-vitest.mjs run --config test/vitest/vitest.bundled.config.ts",
|
||||
|
||||
36
packages/gateway-client/package.json
Normal file
36
packages/gateway-client/package.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@openclaw/gateway-client",
|
||||
"version": "0.0.0-private",
|
||||
"private": true,
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"./readiness": {
|
||||
"types": "./dist/readiness.d.mts",
|
||||
"import": "./dist/readiness.mjs",
|
||||
"default": "./dist/readiness.mjs"
|
||||
},
|
||||
"./timeouts": {
|
||||
"types": "./dist/timeouts.d.mts",
|
||||
"import": "./dist/timeouts.mjs",
|
||||
"default": "./dist/timeouts.mjs"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/readiness.ts src/timeouts.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openclaw/gateway-protocol": "workspace:*",
|
||||
"ipaddr.js": "2.4.0",
|
||||
"ws": "8.21.0"
|
||||
}
|
||||
}
|
||||
1512
packages/gateway-client/src/client.ts
Normal file
1512
packages/gateway-client/src/client.ts
Normal file
File diff suppressed because it is too large
Load Diff
64
packages/gateway-client/src/device-auth.ts
Normal file
64
packages/gateway-client/src/device-auth.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
export function normalizeDeviceMetadataForAuth(value?: string | null): string {
|
||||
if (typeof value !== "string") {
|
||||
return "";
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) {
|
||||
return "";
|
||||
}
|
||||
return trimmed.replace(/[A-Z]/g, (char) => String.fromCharCode(char.charCodeAt(0) + 32));
|
||||
}
|
||||
|
||||
type DeviceAuthPayloadParams = {
|
||||
deviceId: string;
|
||||
clientId: string;
|
||||
clientMode: string;
|
||||
role: string;
|
||||
scopes: string[];
|
||||
signedAtMs: number;
|
||||
token?: string | null;
|
||||
nonce: string;
|
||||
};
|
||||
|
||||
type DeviceAuthPayloadV3Params = DeviceAuthPayloadParams & {
|
||||
platform?: string | null;
|
||||
deviceFamily?: string | null;
|
||||
};
|
||||
|
||||
export function buildDeviceAuthPayload(params: DeviceAuthPayloadParams): string {
|
||||
const scopes = params.scopes.join(",");
|
||||
const token = params.token ?? "";
|
||||
return [
|
||||
"v2",
|
||||
params.deviceId,
|
||||
params.clientId,
|
||||
params.clientMode,
|
||||
params.role,
|
||||
scopes,
|
||||
String(params.signedAtMs),
|
||||
token,
|
||||
params.nonce,
|
||||
].join("|");
|
||||
}
|
||||
|
||||
export function buildDeviceAuthPayloadV3(params: DeviceAuthPayloadV3Params): string {
|
||||
const scopes = params.scopes.join(",");
|
||||
const token = params.token ?? "";
|
||||
// Device signatures are byte-for-byte compared by the gateway. Normalize
|
||||
// optional metadata before joining so case differences do not break auth.
|
||||
const platform = normalizeDeviceMetadataForAuth(params.platform);
|
||||
const deviceFamily = normalizeDeviceMetadataForAuth(params.deviceFamily);
|
||||
return [
|
||||
"v3",
|
||||
params.deviceId,
|
||||
params.clientId,
|
||||
params.clientMode,
|
||||
params.role,
|
||||
scopes,
|
||||
String(params.signedAtMs),
|
||||
token,
|
||||
params.nonce,
|
||||
platform,
|
||||
deviceFamily,
|
||||
].join("|");
|
||||
}
|
||||
116
packages/gateway-client/src/event-loop-ready.ts
Normal file
116
packages/gateway-client/src/event-loop-ready.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
function resolveSafeTimeoutDelayMs(value: number): number {
|
||||
return Math.max(0, Math.min(value, 2_147_483_647));
|
||||
}
|
||||
|
||||
export type EventLoopReadyResult = {
|
||||
ready: boolean;
|
||||
elapsedMs: number;
|
||||
maxDriftMs: number;
|
||||
checks: number;
|
||||
aborted: boolean;
|
||||
};
|
||||
|
||||
type EventLoopReadyOptions = {
|
||||
maxWaitMs?: number;
|
||||
intervalMs?: number;
|
||||
driftThresholdMs?: number;
|
||||
consecutiveReadyChecks?: number;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
const DEFAULT_MAX_WAIT_MS = 10_000;
|
||||
const DEFAULT_INTERVAL_MS = 1;
|
||||
const DEFAULT_DRIFT_THRESHOLD_MS = 200;
|
||||
const DEFAULT_CONSECUTIVE_READY_CHECKS = 2;
|
||||
|
||||
function resolvePositiveInteger(value: number | undefined, fallback: number): number {
|
||||
return Number.isFinite(value) && value !== undefined ? Math.max(1, Math.floor(value)) : fallback;
|
||||
}
|
||||
|
||||
export async function waitForEventLoopReady(
|
||||
options: EventLoopReadyOptions = {},
|
||||
): Promise<EventLoopReadyResult> {
|
||||
const maxWaitMs = resolveSafeTimeoutDelayMs(options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS);
|
||||
const intervalMs = resolvePositiveInteger(options.intervalMs, DEFAULT_INTERVAL_MS);
|
||||
const driftThresholdMs = resolvePositiveInteger(
|
||||
options.driftThresholdMs,
|
||||
DEFAULT_DRIFT_THRESHOLD_MS,
|
||||
);
|
||||
const consecutiveReadyChecks = resolvePositiveInteger(
|
||||
options.consecutiveReadyChecks,
|
||||
DEFAULT_CONSECUTIVE_READY_CHECKS,
|
||||
);
|
||||
const signal = options.signal;
|
||||
|
||||
const startedAt = Date.now();
|
||||
let readyChecks = 0;
|
||||
let checks = 0;
|
||||
let maxDriftMs = 0;
|
||||
|
||||
return await new Promise<EventLoopReadyResult>((resolve) => {
|
||||
let settled = false;
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
const clearTimer = () => {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
};
|
||||
const finish = (ready: boolean, aborted = false) => {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimer();
|
||||
signal?.removeEventListener("abort", onAbort);
|
||||
resolve({
|
||||
ready,
|
||||
elapsedMs: Math.max(0, Date.now() - startedAt),
|
||||
maxDriftMs,
|
||||
checks,
|
||||
aborted,
|
||||
});
|
||||
};
|
||||
const onAbort = () => {
|
||||
finish(false, true);
|
||||
};
|
||||
if (signal?.aborted) {
|
||||
finish(false, true);
|
||||
return;
|
||||
}
|
||||
signal?.addEventListener("abort", onAbort, { once: true });
|
||||
|
||||
const scheduleNext = () => {
|
||||
if (signal?.aborted) {
|
||||
finish(false, true);
|
||||
return;
|
||||
}
|
||||
const elapsedMs = Math.max(0, Date.now() - startedAt);
|
||||
const remainingMs = maxWaitMs - elapsedMs;
|
||||
if (remainingMs <= 0) {
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
const delayMs = Math.min(intervalMs, remainingMs);
|
||||
const scheduledAt = Date.now();
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
checks += 1;
|
||||
const driftMs = Math.max(0, Date.now() - scheduledAt - delayMs);
|
||||
maxDriftMs = Math.max(maxDriftMs, driftMs);
|
||||
if (driftMs > driftThresholdMs) {
|
||||
readyChecks = 0;
|
||||
} else {
|
||||
readyChecks += 1;
|
||||
}
|
||||
if (readyChecks >= consecutiveReadyChecks) {
|
||||
finish(true);
|
||||
return;
|
||||
}
|
||||
scheduleNext();
|
||||
}, delayMs);
|
||||
};
|
||||
|
||||
scheduleNext();
|
||||
});
|
||||
}
|
||||
5
packages/gateway-client/src/index.ts
Normal file
5
packages/gateway-client/src/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from "./client.js";
|
||||
export * from "./device-auth.js";
|
||||
export * from "./event-loop-ready.js";
|
||||
export * from "./readiness.js";
|
||||
export * from "./timeouts.js";
|
||||
46
packages/gateway-client/src/readiness.ts
Normal file
46
packages/gateway-client/src/readiness.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { GatewayClient, GatewayClientOptions } from "./client.js";
|
||||
import { waitForEventLoopReady, type EventLoopReadyResult } from "./event-loop-ready.js";
|
||||
import { resolveConnectChallengeTimeoutMs } from "./timeouts.js";
|
||||
|
||||
export type GatewayClientStartReadinessOptions = {
|
||||
timeoutMs?: number;
|
||||
clientOptions?: Pick<
|
||||
GatewayClientOptions,
|
||||
"connectChallengeTimeoutMs" | "connectDelayMs" | "preauthHandshakeTimeoutMs"
|
||||
>;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
function resolveGatewayClientStartReadinessTimeoutMs(
|
||||
options: GatewayClientStartReadinessOptions = {},
|
||||
): number {
|
||||
if (typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)) {
|
||||
return options.timeoutMs;
|
||||
}
|
||||
const clientOptions = options.clientOptions ?? {};
|
||||
const timeoutOverride =
|
||||
typeof clientOptions.connectChallengeTimeoutMs === "number" &&
|
||||
Number.isFinite(clientOptions.connectChallengeTimeoutMs)
|
||||
? clientOptions.connectChallengeTimeoutMs
|
||||
: typeof clientOptions.connectDelayMs === "number" &&
|
||||
Number.isFinite(clientOptions.connectDelayMs)
|
||||
? clientOptions.connectDelayMs
|
||||
: undefined;
|
||||
return resolveConnectChallengeTimeoutMs(timeoutOverride, {
|
||||
configuredTimeoutMs: clientOptions.preauthHandshakeTimeoutMs,
|
||||
});
|
||||
}
|
||||
|
||||
export async function startGatewayClientWhenEventLoopReady(
|
||||
client: GatewayClient,
|
||||
options: GatewayClientStartReadinessOptions = {},
|
||||
): Promise<EventLoopReadyResult> {
|
||||
const readiness = await waitForEventLoopReady({
|
||||
maxWaitMs: resolveGatewayClientStartReadinessTimeoutMs(options),
|
||||
signal: options.signal,
|
||||
});
|
||||
if (readiness.ready && !readiness.aborted && options.signal?.aborted !== true) {
|
||||
client.start();
|
||||
}
|
||||
return readiness;
|
||||
}
|
||||
96
packages/gateway-client/src/timeouts.ts
Normal file
96
packages/gateway-client/src/timeouts.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
function parseStrictPositiveInteger(value: string): number | undefined {
|
||||
if (!/^[1-9]\d*$/u.test(value)) {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = Number(value);
|
||||
return Number.isSafeInteger(parsed) ? parsed : undefined;
|
||||
}
|
||||
|
||||
export const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 15_000;
|
||||
export const MIN_CONNECT_CHALLENGE_TIMEOUT_MS = 250;
|
||||
export const MAX_CONNECT_CHALLENGE_TIMEOUT_MS = DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS;
|
||||
|
||||
export function clampConnectChallengeTimeoutMs(
|
||||
timeoutMs: number,
|
||||
maxTimeoutMs = MAX_CONNECT_CHALLENGE_TIMEOUT_MS,
|
||||
): number {
|
||||
return Math.max(
|
||||
MIN_CONNECT_CHALLENGE_TIMEOUT_MS,
|
||||
Math.min(Math.max(MIN_CONNECT_CHALLENGE_TIMEOUT_MS, maxTimeoutMs), timeoutMs),
|
||||
);
|
||||
}
|
||||
|
||||
export function getConnectChallengeTimeoutMsFromEnv(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
): number | undefined {
|
||||
const raw = env.OPENCLAW_CONNECT_CHALLENGE_TIMEOUT_MS;
|
||||
if (raw) {
|
||||
const parsed = parseStrictPositiveInteger(raw);
|
||||
if (parsed !== undefined) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function normalizePositiveTimeoutMs(timeoutMs: unknown): number | undefined {
|
||||
return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0
|
||||
? timeoutMs
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function resolveConnectChallengeTimeoutMs(
|
||||
timeoutMs?: number | null,
|
||||
params?: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
configuredTimeoutMs?: number | null;
|
||||
},
|
||||
): number {
|
||||
const configuredPreauthTimeoutMs = resolvePreauthHandshakeTimeoutMs({
|
||||
env: params?.env,
|
||||
configuredTimeoutMs: params?.configuredTimeoutMs,
|
||||
});
|
||||
// The client watchdog must never fire before the server-side preauth timeout.
|
||||
// Tests may raise the env override above that server default, so widen the cap.
|
||||
const maxTimeoutMs = Math.max(DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, configuredPreauthTimeoutMs);
|
||||
if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs)) {
|
||||
return clampConnectChallengeTimeoutMs(timeoutMs, maxTimeoutMs);
|
||||
}
|
||||
const envOverride = getConnectChallengeTimeoutMsFromEnv(params?.env);
|
||||
if (envOverride !== undefined) {
|
||||
return clampConnectChallengeTimeoutMs(envOverride, Math.max(maxTimeoutMs, envOverride));
|
||||
}
|
||||
return clampConnectChallengeTimeoutMs(configuredPreauthTimeoutMs, maxTimeoutMs);
|
||||
}
|
||||
|
||||
export function getPreauthHandshakeTimeoutMsFromEnv(env: NodeJS.ProcessEnv = process.env): number {
|
||||
const configuredTimeout =
|
||||
env.OPENCLAW_HANDSHAKE_TIMEOUT_MS || (env.VITEST && env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS);
|
||||
if (configuredTimeout) {
|
||||
const parsed = parseStrictPositiveInteger(configuredTimeout);
|
||||
if (parsed !== undefined) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
return DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
export function resolvePreauthHandshakeTimeoutMs(params?: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
configuredTimeoutMs?: number | null;
|
||||
}): number {
|
||||
const env = params?.env ?? process.env;
|
||||
const configuredTimeout =
|
||||
env.OPENCLAW_HANDSHAKE_TIMEOUT_MS || (env.VITEST && env.OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS);
|
||||
if (configuredTimeout) {
|
||||
const parsed = parseStrictPositiveInteger(configuredTimeout);
|
||||
if (parsed !== undefined) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
const configured = normalizePositiveTimeoutMs(params?.configuredTimeoutMs);
|
||||
if (configured !== undefined) {
|
||||
return configured;
|
||||
}
|
||||
return DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS;
|
||||
}
|
||||
49
packages/gateway-protocol/package.json
Normal file
49
packages/gateway-protocol/package.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "@openclaw/gateway-protocol",
|
||||
"version": "0.0.0-private",
|
||||
"private": true,
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"./client-info": {
|
||||
"types": "./dist/client-info.d.mts",
|
||||
"import": "./dist/client-info.mjs",
|
||||
"default": "./dist/client-info.mjs"
|
||||
},
|
||||
"./connect-error-details": {
|
||||
"types": "./dist/connect-error-details.d.mts",
|
||||
"import": "./dist/connect-error-details.mjs",
|
||||
"default": "./dist/connect-error-details.mjs"
|
||||
},
|
||||
"./schema": {
|
||||
"types": "./dist/schema.d.mts",
|
||||
"import": "./dist/schema.mjs",
|
||||
"default": "./dist/schema.mjs"
|
||||
},
|
||||
"./startup-unavailable": {
|
||||
"types": "./dist/startup-unavailable.d.mts",
|
||||
"import": "./dist/startup-unavailable.mjs",
|
||||
"default": "./dist/startup-unavailable.mjs"
|
||||
},
|
||||
"./version": {
|
||||
"types": "./dist/version.d.mts",
|
||||
"import": "./dist/version.mjs",
|
||||
"default": "./dist/version.mjs"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/client-info.ts src/connect-error-details.ts src/schema.ts src/startup-unavailable.ts src/version.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"typebox": "1.1.38"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js";
|
||||
function normalizeOptionalLowercaseString(raw?: string | null): string | undefined {
|
||||
if (typeof raw !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = raw.trim().toLowerCase();
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
export const GATEWAY_CLIENT_IDS = {
|
||||
WEBCHAT_UI: "webchat-ui",
|
||||
@@ -1,5 +1,22 @@
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { normalizeArrayBackedTrimmedStringList } from "../../shared/string-normalization.js";
|
||||
function normalizeOptionalString(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
}
|
||||
|
||||
function normalizeArrayBackedTrimmedStringList(value: unknown): string[] | undefined {
|
||||
if (!Array.isArray(value)) {
|
||||
return undefined;
|
||||
}
|
||||
const values = value
|
||||
.map((entry) => normalizeOptionalString(entry))
|
||||
.filter((entry): entry is string => Boolean(entry));
|
||||
// Pairing details omit absent lists. Emitting empty arrays makes clients think
|
||||
// the gateway intentionally supplied scope/role context when it did not.
|
||||
return values.length > 0 ? values : undefined;
|
||||
}
|
||||
|
||||
export const ConnectErrorDetailCodes = {
|
||||
AUTH_REQUIRED: "AUTH_REQUIRED",
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { TALK_TEST_PROVIDER_ID } from "../../test-utils/talk-test-provider.js";
|
||||
import { TALK_TEST_PROVIDER_ID } from "../../../src/test-utils/talk-test-provider.js";
|
||||
import * as protocol from "./index.js";
|
||||
import {
|
||||
formatValidationErrors,
|
||||
@@ -1,6 +1,4 @@
|
||||
import { Compile, type Validator as TypeBoxValidator } from "typebox/compile";
|
||||
import { uniqueStrings } from "../../shared/string-normalization.js";
|
||||
import type { SessionsPatchResult } from "../session-utils.types.js";
|
||||
import {
|
||||
type AgentEvent,
|
||||
AgentEventSchema,
|
||||
@@ -1266,3 +1264,26 @@ export type {
|
||||
UpdateRunParams,
|
||||
ChatInjectParams,
|
||||
};
|
||||
function uniqueStrings(values: string[]): string[] {
|
||||
return [...new Set(values)];
|
||||
}
|
||||
|
||||
// The protocol package cannot import core session types. This local structural
|
||||
// result mirrors the wire contract and keeps the package independent of src/.
|
||||
type SessionsPatchResult = {
|
||||
ok: true;
|
||||
path: string;
|
||||
key: string;
|
||||
entry: Record<string, unknown>;
|
||||
resolved?: {
|
||||
modelProvider?: string;
|
||||
model?: string;
|
||||
agentRuntime?: GatewayAgentRuntime;
|
||||
};
|
||||
};
|
||||
|
||||
type GatewayAgentRuntime = {
|
||||
id: string;
|
||||
fallback?: "openclaw" | "none";
|
||||
source: "env" | "agent" | "defaults" | "model" | "provider" | "implicit" | "session-key";
|
||||
};
|
||||
@@ -26,7 +26,7 @@ function extractInteger(
|
||||
const match = pattern.exec(content);
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
`${relativePath}: missing ${label}; keep native Gateway protocol levels in sync with src/gateway/protocol/version.ts.`,
|
||||
`${relativePath}: missing ${label}; keep native Gateway protocol levels in sync with packages/gateway-protocol/src/version.ts.`,
|
||||
);
|
||||
}
|
||||
return Number.parseInt(match[1], 10);
|
||||
@@ -37,7 +37,7 @@ function assertLevelsMatch(relativePath: string, actual: ProtocolLevels): void {
|
||||
return;
|
||||
}
|
||||
throw new Error(
|
||||
`${relativePath}: Gateway protocol level mismatch: expected min=${expectedLevels.min} max=${expectedLevels.max} from src/gateway/protocol/version.ts, got min=${actual.min} max=${actual.max}. Update the native constants/generated artifacts before shipping.`,
|
||||
`${relativePath}: Gateway protocol level mismatch: expected min=${expectedLevels.min} max=${expectedLevels.max} from packages/gateway-protocol/src/version.ts, got min=${actual.min} max=${actual.max}. Update the native constants/generated artifacts before shipping.`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ describe("native Gateway protocol levels", () => {
|
||||
it("match the TypeScript source of truth", async () => {
|
||||
if (MIN_CLIENT_PROTOCOL_VERSION > PROTOCOL_VERSION) {
|
||||
throw new Error(
|
||||
`src/gateway/protocol/version.ts: MIN_CLIENT_PROTOCOL_VERSION (${MIN_CLIENT_PROTOCOL_VERSION}) must not exceed PROTOCOL_VERSION (${PROTOCOL_VERSION}).`,
|
||||
`packages/gateway-protocol/src/version.ts: MIN_CLIENT_PROTOCOL_VERSION (${MIN_CLIENT_PROTOCOL_VERSION}) must not exceed PROTOCOL_VERSION (${PROTOCOL_VERSION}).`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
INVALID_EXEC_SECRET_REF_IDS,
|
||||
VALID_EXEC_SECRET_REF_IDS,
|
||||
} from "../../test-utils/secret-ref-test-vectors.js";
|
||||
} from "../../../src/test-utils/secret-ref-test-vectors.js";
|
||||
import { SecretInputSchema, SecretRefSchema } from "./schema/primitives.js";
|
||||
|
||||
describe("gateway protocol SecretRef schema", () => {
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./schema/primitives.js";
|
||||
export * from "./schema/agent.js";
|
||||
export * from "./schema/agents-models-skills.js";
|
||||
export * from "./schema/artifacts.js";
|
||||
@@ -1,8 +1,22 @@
|
||||
import { Value } from "typebox/value";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { AgentInternalEvent } from "../../../agents/internal-events.js";
|
||||
import { AgentParamsSchema } from "./agent.js";
|
||||
|
||||
type AgentInternalEvent = {
|
||||
type: "task_completion";
|
||||
source: string;
|
||||
childSessionKey: string;
|
||||
childSessionId: string;
|
||||
announceType: string;
|
||||
taskLabel: string;
|
||||
status: "ok" | "error";
|
||||
statusLabel: string;
|
||||
result: string;
|
||||
attachments?: unknown[];
|
||||
mediaUrls?: string[];
|
||||
replyInstruction?: string;
|
||||
};
|
||||
|
||||
function makeAgentParamsWithInternalEvent(event: AgentInternalEvent) {
|
||||
return {
|
||||
message: "A music generation task finished. Process the completion update now.",
|
||||
@@ -1,11 +1,16 @@
|
||||
import { Type } from "typebox";
|
||||
import {
|
||||
AGENT_INTERNAL_EVENT_SOURCES,
|
||||
AGENT_INTERNAL_EVENT_STATUSES,
|
||||
AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION,
|
||||
} from "../../../agents/internal-event-contract.js";
|
||||
import { InputProvenanceSchema, NonEmptyString, SessionLabelString } from "./primitives.js";
|
||||
|
||||
const AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION = "task_completion";
|
||||
const AGENT_INTERNAL_EVENT_SOURCES = [
|
||||
"subagent",
|
||||
"cron",
|
||||
"image_generation",
|
||||
"video_generation",
|
||||
"music_generation",
|
||||
] as const;
|
||||
const AGENT_INTERNAL_EVENT_STATUSES = ["ok", "timeout", "error", "unknown"] as const;
|
||||
|
||||
export const AgentGeneratedAttachmentSchema = Type.Object(
|
||||
{
|
||||
type: Type.Optional(Type.String({ enum: ["image", "audio", "video", "file"] })),
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Type } from "typebox";
|
||||
import {
|
||||
MAX_PLUGIN_APPROVAL_TIMEOUT_MS,
|
||||
PLUGIN_APPROVAL_DESCRIPTION_MAX_LENGTH,
|
||||
PLUGIN_APPROVAL_TITLE_MAX_LENGTH,
|
||||
} from "../../../infra/plugin-approvals.js";
|
||||
import { NonEmptyString } from "./primitives.js";
|
||||
|
||||
const MAX_PLUGIN_APPROVAL_TIMEOUT_MS = 600_000;
|
||||
const PLUGIN_APPROVAL_TITLE_MAX_LENGTH = 80;
|
||||
const PLUGIN_APPROVAL_DESCRIPTION_MAX_LENGTH = 256;
|
||||
|
||||
export const PluginApprovalRequestParamsSchema = Type.Object(
|
||||
{
|
||||
pluginId: Type.Optional(NonEmptyString),
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Type } from "typebox";
|
||||
import { ENV_SECRET_REF_ID_RE } from "../../../config/types.secrets.js";
|
||||
import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES } from "../client-info.js";
|
||||
import {
|
||||
EXEC_SECRET_REF_ID_JSON_SCHEMA_PATTERN,
|
||||
FILE_SECRET_REF_ID_ABSOLUTE_JSON_SCHEMA_PATTERN,
|
||||
FILE_SECRET_REF_ID_INVALID_ESCAPE_JSON_SCHEMA_PATTERN,
|
||||
SECRET_PROVIDER_ALIAS_PATTERN,
|
||||
SINGLE_VALUE_FILE_REF_ID,
|
||||
} from "../../../secrets/ref-contract.js";
|
||||
import { INPUT_PROVENANCE_KIND_VALUES } from "../../../sessions/input-provenance.js";
|
||||
import { SESSION_LABEL_MAX_LENGTH } from "../../../sessions/session-label.js";
|
||||
import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES } from "../client-info.js";
|
||||
} from "../secret-ref-contract.js";
|
||||
|
||||
const ENV_SECRET_REF_ID_RE = /^[A-Z][A-Z0-9_]{0,127}$/;
|
||||
const INPUT_PROVENANCE_KIND_VALUES = ["external_user", "inter_session", "internal_system"] as const;
|
||||
const SESSION_LABEL_MAX_LENGTH = 512;
|
||||
|
||||
export const NonEmptyString = Type.String({ minLength: 1 });
|
||||
export const CHAT_SEND_SESSION_KEY_MAX_LENGTH = 512;
|
||||
7
packages/gateway-protocol/src/secret-ref-contract.ts
Normal file
7
packages/gateway-protocol/src/secret-ref-contract.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export const SINGLE_VALUE_FILE_REF_ID = "value";
|
||||
|
||||
export const SECRET_PROVIDER_ALIAS_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
|
||||
export const FILE_SECRET_REF_ID_ABSOLUTE_JSON_SCHEMA_PATTERN = "^/";
|
||||
export const FILE_SECRET_REF_ID_INVALID_ESCAPE_JSON_SCHEMA_PATTERN = "~(?:[^01]|$)";
|
||||
export const EXEC_SECRET_REF_ID_JSON_SCHEMA_PATTERN =
|
||||
"^(?!.*(?:^|/)\\.{1,2}(?:/|$))[A-Za-z0-9][A-Za-z0-9._:/#-]{0,255}$";
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildTalkConfigResponse } from "../../config/talk.js";
|
||||
import { buildTalkConfigResponse } from "../../../src/config/talk.js";
|
||||
import { validateTalkConfigResult } from "./index.js";
|
||||
|
||||
type ExpectedSelection = {
|
||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -1743,6 +1743,24 @@ importers:
|
||||
specifier: 2.9.0
|
||||
version: 2.9.0
|
||||
|
||||
packages/gateway-client:
|
||||
dependencies:
|
||||
'@openclaw/gateway-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../gateway-protocol
|
||||
ipaddr.js:
|
||||
specifier: 2.4.0
|
||||
version: 2.4.0
|
||||
ws:
|
||||
specifier: 8.21.0
|
||||
version: 8.21.0
|
||||
|
||||
packages/gateway-protocol:
|
||||
dependencies:
|
||||
typebox:
|
||||
specifier: 1.1.38
|
||||
version: 1.1.38
|
||||
|
||||
packages/memory-host-sdk: {}
|
||||
|
||||
packages/plugin-package-contract: {}
|
||||
|
||||
@@ -49,7 +49,8 @@ const FAST_INSTALL_SMOKE_SCOPE_RE =
|
||||
/^(Dockerfile$|\.npmrc$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|scripts\/ci-changed-scope\.mjs$|scripts\/postinstall-bundled-plugins\.mjs$|scripts\/e2e\/(?:Dockerfile(?:\.qr-import)?|agents-delete-shared-workspace-docker\.sh|gateway-network-docker\.sh)$|extensions\/[^/]+\/(?:package\.json|openclaw\.plugin\.json)$|\.github\/workflows\/install-smoke\.yml$|\.github\/actions\/setup-node-env\/action\.yml$)/;
|
||||
const FULL_INSTALL_SMOKE_SCOPE_RE =
|
||||
/^(Dockerfile$|\.npmrc$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|scripts\/ci-changed-scope\.mjs$|scripts\/install(?:-cli)?\.sh$|scripts\/install\.ps1$|scripts\/test-install-sh-docker\.sh$|scripts\/docker\/|scripts\/e2e\/(?:Dockerfile(?:\.qr-import)?|qr-import-docker\.sh|bun-global-install-smoke\.sh)$|\.github\/workflows\/(?:install-smoke|website-installer-sync)\.yml$|\.github\/actions\/setup-node-env\/action\.yml$)/;
|
||||
const FAST_INSTALL_SMOKE_RUNTIME_SCOPE_RE = /^src\/(?:channels|gateway|plugin-sdk|plugins)\//;
|
||||
const FAST_INSTALL_SMOKE_RUNTIME_SCOPE_RE =
|
||||
/^(?:src\/(?:channels|gateway|plugin-sdk|plugins)\/|packages\/gateway-(?:client|protocol)\/src\/)/;
|
||||
const NODE_FAST_PLUGIN_CONTRACT_SCOPE_RE =
|
||||
/^(src\/plugins\/contracts\/(?:inventory\/bundled-capability-metadata|registry|tts-contract-suites)\.ts$|scripts\/test-projects(?:\.test-support)?\.mjs$|test\/scripts\/test-projects\.test\.ts$)/;
|
||||
const NODE_FAST_CI_ROUTING_SCOPE_RE =
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createArgReader, createGatewayWsClient, resolveGatewayUrl } from "./gateway-ws-client.ts";
|
||||
import {
|
||||
MIN_CLIENT_PROTOCOL_VERSION,
|
||||
PROTOCOL_VERSION,
|
||||
} from "../../src/gateway/protocol/version.ts";
|
||||
} from "../../packages/gateway-protocol/src/version.js";
|
||||
import { createArgReader, createGatewayWsClient, resolveGatewayUrl } from "./gateway-ws-client.ts";
|
||||
|
||||
function writeStdoutLine(message: string): void {
|
||||
process.stdout.write(`${message}\n`);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createArgReader, createGatewayWsClient, resolveGatewayUrl } from "./gateway-ws-client.ts";
|
||||
import {
|
||||
MIN_CLIENT_PROTOCOL_VERSION,
|
||||
PROTOCOL_VERSION,
|
||||
} from "../../src/gateway/protocol/version.ts";
|
||||
} from "../../packages/gateway-protocol/src/version.js";
|
||||
import { createArgReader, createGatewayWsClient, resolveGatewayUrl } from "./gateway-ws-client.ts";
|
||||
|
||||
function writeStdoutLine(message = ""): void {
|
||||
process.stdout.write(`${message}\n`);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
MIN_CLIENT_PROTOCOL_VERSION,
|
||||
PROTOCOL_VERSION,
|
||||
ProtocolSchemas,
|
||||
} from "../src/gateway/protocol/schema.js";
|
||||
} from "../packages/gateway-protocol/src/schema.js";
|
||||
|
||||
type JsonSchema = {
|
||||
type?: string | string[];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { promises as fs } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { ProtocolSchemas } from "../src/gateway/protocol/schema.js";
|
||||
import { ProtocolSchemas } from "../packages/gateway-protocol/src/schema.js";
|
||||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, "..");
|
||||
|
||||
@@ -4,7 +4,18 @@ import {
|
||||
BUNDLED_PLUGIN_ROOT_DIR,
|
||||
} from "./lib/bundled-plugin-paths.mjs";
|
||||
|
||||
export const runNodeSourceRoots = ["src", BUNDLED_PLUGIN_ROOT_DIR];
|
||||
const RUN_NODE_PACKAGE_SOURCE_ROOTS = [
|
||||
// Gateway runtime code now lives in package sources, but pnpm dev/watch still
|
||||
// runs the root dist entrypoint. Treat these package roots like src/.
|
||||
"packages/gateway-client/src",
|
||||
"packages/gateway-protocol/src",
|
||||
];
|
||||
|
||||
export const runNodeSourceRoots = [
|
||||
"src",
|
||||
...RUN_NODE_PACKAGE_SOURCE_ROOTS,
|
||||
BUNDLED_PLUGIN_ROOT_DIR,
|
||||
];
|
||||
export const runNodeConfigFiles = ["tsconfig.json", "package.json", "tsdown.config.ts"];
|
||||
export const runNodeWatchedPaths = [...runNodeSourceRoots, ...runNodeConfigFiles];
|
||||
export const extensionRestartMetadataFiles = new Set(["openclaw.plugin.json", "package.json"]);
|
||||
@@ -50,6 +61,11 @@ const isRelevantRunNodePath = (repoPath, isRelevantBundledPluginPath) => {
|
||||
if (normalizedPath.startsWith("src/")) {
|
||||
return !isIgnoredSourcePath(normalizedPath.slice("src/".length));
|
||||
}
|
||||
for (const sourceRoot of RUN_NODE_PACKAGE_SOURCE_ROOTS) {
|
||||
if (normalizedPath.startsWith(`${sourceRoot}/`)) {
|
||||
return !isIgnoredSourcePath(normalizedPath.slice(sourceRoot.length + 1));
|
||||
}
|
||||
}
|
||||
if (normalizedPath.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
|
||||
return isRelevantBundledPluginPath(normalizedPath.slice(BUNDLED_PLUGIN_PATH_PREFIX.length));
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
import { Readable, Writable } from "node:stream";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { resolveGatewayClientBootstrap } from "../gateway/client-bootstrap.js";
|
||||
import { startGatewayClientWhenEventLoopReady } from "../gateway/client-start-readiness.js";
|
||||
import { GatewayClient } from "../gateway/client.js";
|
||||
import {
|
||||
GATEWAY_CLIENT_CAPS,
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../gateway/protocol/client-info.js";
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { resolveGatewayClientBootstrap } from "../gateway/client-bootstrap.js";
|
||||
import { startGatewayClientWhenEventLoopReady } from "../gateway/client-start-readiness.js";
|
||||
import { GatewayClient } from "../gateway/client.js";
|
||||
import { isMainModule } from "../infra/is-main.js";
|
||||
import { routeLogsToStderr } from "../logging/console.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { CancelNotification, PromptRequest, PromptResponse } from "@agentclientprotocol/sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import { createInMemorySessionStore } from "./session.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
import { createAcpConnection, createAcpGateway } from "./translator.test-helpers.js";
|
||||
|
||||
@@ -4,8 +4,8 @@ import type {
|
||||
PromptRequest,
|
||||
} from "@agentclientprotocol/sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import { createInMemoryAcpEventLedger, type AcpEventLedger } from "./event-ledger.js";
|
||||
import { createInMemorySessionStore } from "./session.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { CancelNotification } from "@agentclientprotocol/sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import { createInMemorySessionStore } from "./session.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
import { promptAgent } from "./translator.prompt-harness.test-support.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PromptRequest } from "@agentclientprotocol/sdk";
|
||||
import { expect, vi } from "vitest";
|
||||
import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import { createInMemorySessionStore } from "./session.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
import { createAcpConnection, createAcpGateway } from "./translator.test-helpers.js";
|
||||
|
||||
@@ -6,8 +6,8 @@ import type {
|
||||
SetSessionModeRequest,
|
||||
} from "@agentclientprotocol/sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import { createInMemorySessionStore } from "./session.js";
|
||||
import { AcpGatewayAgent } from "./translator.js";
|
||||
import { createAcpConnection, createAcpGateway } from "./translator.test-helpers.js";
|
||||
|
||||
@@ -33,9 +33,9 @@ import type {
|
||||
ToolCallLocation,
|
||||
ToolKind,
|
||||
} from "@agentclientprotocol/sdk";
|
||||
import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
|
||||
import { BASE_THINKING_LEVELS } from "../auto-reply/thinking.shared.js";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
import type { EventFrame } from "../gateway/protocol/index.js";
|
||||
import type { GatewaySessionRow, SessionsListResult } from "../gateway/session-utils.js";
|
||||
import {
|
||||
createFixedWindowRateLimiter,
|
||||
|
||||
@@ -198,7 +198,7 @@ describe("buildEmbeddedRunPayloads tool-error warnings", () => {
|
||||
it("does not replay raw-looking accumulated tool output when final answer text is available", () => {
|
||||
const payloads = buildPayloads({
|
||||
assistantTexts: [
|
||||
"/root/openclaw/src/gateway/protocol/schema/protocol-schemas.ts:181: PluginControlUiDescriptorSchema,",
|
||||
"/root/openclaw/packages/gateway-protocol/src/schema/protocol-schemas.ts:181: PluginControlUiDescriptorSchema,",
|
||||
"The schema export is fixed.",
|
||||
],
|
||||
lastAssistant: {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type {
|
||||
SessionsListParams,
|
||||
SessionsResolveParams,
|
||||
} from "../../../packages/gateway-protocol/src/index.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { CallGatewayOptions } from "../../gateway/call.js";
|
||||
import type { SessionsListParams, SessionsResolveParams } from "../../gateway/protocol/index.js";
|
||||
import type { ReadSessionMessagesAsyncOptions } from "../../gateway/session-utils.fs.js";
|
||||
import type { SessionsListResult } from "../../gateway/session-utils.types.js";
|
||||
import type { SessionsResolveResult } from "../../gateway/sessions-resolve.js";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../../packages/gateway-protocol/src/client-info.js";
|
||||
import { getRuntimeConfig, resolveGatewayPort } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
@@ -7,7 +11,6 @@ import {
|
||||
type OperatorScope,
|
||||
} from "../../gateway/method-scopes.js";
|
||||
import { getOperatorApprovalRuntimeToken } from "../../gateway/operator-approval-runtime-token.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../gateway/protocol/client-info.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { Type, type TSchema } from "typebox";
|
||||
import {
|
||||
GATEWAY_CLIENT_IDS,
|
||||
GATEWAY_CLIENT_MODES,
|
||||
} from "../../../packages/gateway-protocol/src/client-info.js";
|
||||
import type { SourceReplyDeliveryMode } from "../../auto-reply/get-reply-options.types.js";
|
||||
import type { InboundEventKind } from "../../channels/inbound-event/kind.js";
|
||||
import {
|
||||
@@ -21,7 +25,6 @@ import { getScopedChannelsCommandSecretTargets } from "../../cli/command-secret-
|
||||
import { resolveMessageSecretScope } from "../../cli/message-secret-scope.js";
|
||||
import { getRuntimeConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES } from "../../gateway/protocol/client-info.js";
|
||||
import { getToolResult, runMessageAction } from "../../infra/outbound/message-action-runner.js";
|
||||
import { resolveAllowedMessageActions } from "../../infra/outbound/outbound-policy.js";
|
||||
import { stringifyRouteThreadId } from "../../plugin-sdk/channel-route.js";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import crypto from "node:crypto";
|
||||
import { Type } from "typebox";
|
||||
import { readConnectPairingRequiredMessage } from "../../../packages/gateway-protocol/src/connect-error-details.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { OperatorScope } from "../../gateway/method-scopes.js";
|
||||
import { readConnectPairingRequiredMessage } from "../../gateway/protocol/connect-error-details.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import { resolveNodePairApprovalScopes } from "../../infra/node-pairing-authz.js";
|
||||
import type { GatewayMessageChannel } from "../../utils/message-channel.js";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
import {
|
||||
GATEWAY_CLIENT_IDS,
|
||||
normalizeGatewayClientId,
|
||||
} from "../../gateway/protocol/client-info.js";
|
||||
} from "../../../packages/gateway-protocol/src/client-info.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import {
|
||||
listSpawnedSessionKeys,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import type { TSchema } from "typebox";
|
||||
import type {
|
||||
GatewayClientMode,
|
||||
GatewayClientName,
|
||||
} from "../../../packages/gateway-protocol/src/client-info.js";
|
||||
import type { AgentTool, AgentToolResult } from "../../agents/runtime/index.js";
|
||||
import type { ReplyPayload } from "../../auto-reply/reply-payload.js";
|
||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import type { MarkdownTableMode } from "../../config/types.base.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { GatewayClientMode, GatewayClientName } from "../../gateway/protocol/client-info.js";
|
||||
import type { MessagePresentation } from "../../interactive/payload.js";
|
||||
import type { OutboundMediaAccess } from "../../media/load-options.js";
|
||||
import type { PollInput } from "../../polls.js";
|
||||
|
||||
@@ -5,6 +5,10 @@ import path from "node:path";
|
||||
import { Readable } from "node:stream";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import type { Command } from "commander";
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { resolveAgentDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import {
|
||||
listProfilesForProvider,
|
||||
@@ -32,7 +36,6 @@ import { callGateway, randomIdempotencyKey } from "../gateway/call.js";
|
||||
import { buildGatewayConnectionDetailsWithResolvers } from "../gateway/connection-details.js";
|
||||
import { isLoopbackHost } from "../gateway/net.js";
|
||||
import { ADMIN_SCOPE } from "../gateway/operator-scopes.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import { generateImage, listRuntimeImageGenerationProviders } from "../image-generation/runtime.js";
|
||||
import type {
|
||||
ImageGenerationBackground,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { validateSecretsResolveResult } from "../../packages/gateway-protocol/src/index.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { resolveSecretInputRef } from "../config/types.secrets.js";
|
||||
import { callGateway } from "../gateway/call.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import { validateSecretsResolveResult } from "../gateway/protocol/index.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { resolveManifestContractOwnerPluginId } from "../plugins/plugin-registry.js";
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import {
|
||||
readConnectPairingRequiredMessage,
|
||||
type ConnectPairingRequiredDetails,
|
||||
} from "../../packages/gateway-protocol/src/connect-error-details.js";
|
||||
import {
|
||||
buildGatewayConnectionDetails,
|
||||
callGateway,
|
||||
@@ -5,11 +13,6 @@ import {
|
||||
} from "../gateway/call.js";
|
||||
import { ADMIN_SCOPE, PAIRING_SCOPE, type OperatorScope } from "../gateway/method-scopes.js";
|
||||
import { isLoopbackHost } from "../gateway/net.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import {
|
||||
readConnectPairingRequiredMessage,
|
||||
type ConnectPairingRequiredDetails,
|
||||
} from "../gateway/protocol/connect-error-details.js";
|
||||
import {
|
||||
approveDevicePairing,
|
||||
formatDevicePairingForbiddenMessage,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import type { Command } from "commander";
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../../packages/gateway-protocol/src/client-info.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../gateway/protocol/client-info.js";
|
||||
import { parseTimeoutMsWithFallback } from "../parse-timeout.js";
|
||||
import { withProgress } from "../progress.js";
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { callGateway } from "../gateway/call.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import type { GatewayRpcOpts } from "./gateway-rpc.types.js";
|
||||
import { parseTimeoutMsWithFallback } from "./parse-timeout.js";
|
||||
import { withProgress } from "./progress.js";
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type { Command } from "commander";
|
||||
import type {
|
||||
GatewayClientMode,
|
||||
GatewayClientName,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import type { OperatorScope } from "../gateway/operator-scopes.js";
|
||||
import type { GatewayClientMode, GatewayClientName } from "../gateway/protocol/client-info.js";
|
||||
import type { DeviceIdentity } from "../infra/device-identity.js";
|
||||
import { createLazyImportLoader } from "../shared/lazy-promise.js";
|
||||
import type { GatewayRpcOpts } from "./gateway-rpc.types.js";
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { setTimeout as delay } from "node:timers/promises";
|
||||
import type { Command } from "commander";
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { readConnectPairingRequiredMessage } from "../../packages/gateway-protocol/src/connect-error-details.js";
|
||||
import {
|
||||
buildGatewayConnectionDetails,
|
||||
isGatewayTransportError,
|
||||
type GatewayConnectionDetails,
|
||||
} from "../gateway/call.js";
|
||||
import { isLoopbackHost } from "../gateway/net.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import { readConnectPairingRequiredMessage } from "../gateway/protocol/connect-error-details.js";
|
||||
import { computeBackoff } from "../infra/backoff.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { parseStrictPositiveInteger } from "../infra/parse-finite-number.js";
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../../packages/gateway-protocol/src/client-info.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
import type { OperatorScope } from "../../gateway/method-scopes.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../gateway/protocol/client-info.js";
|
||||
import { parseTimeoutMsWithFallback } from "../parse-timeout.js";
|
||||
import { withProgress } from "../progress.js";
|
||||
import type { NodesRpcOpts } from "./types.js";
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { listAgentIds, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { CliDeps } from "../cli/deps.types.js";
|
||||
@@ -13,7 +17,6 @@ import {
|
||||
type GatewayRequestFunction,
|
||||
} from "../gateway/call.js";
|
||||
import { ADMIN_SCOPE } from "../gateway/operator-scopes.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import { parseStrictNonNegativeInteger } from "../infra/parse-finite-number.js";
|
||||
import { routeLogsToStderr } from "../logging/console.js";
|
||||
import {
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function maybeRepairUiProtocolFreshness(
|
||||
return;
|
||||
}
|
||||
|
||||
const schemaPath = path.join(root, "src/gateway/protocol/schema.ts");
|
||||
const schemaPath = path.join(root, "packages/gateway-protocol/src/schema.ts");
|
||||
const uiHealth = await resolveControlUiDistIndexHealth({
|
||||
root,
|
||||
argv1: process.argv[1],
|
||||
@@ -92,7 +92,7 @@ export async function maybeRepairUiProtocolFreshness(
|
||||
"log",
|
||||
`--since=${uiMtimeIso}`,
|
||||
"--format=%h %s",
|
||||
"src/gateway/protocol/schema.ts",
|
||||
"packages/gateway-protocol/src/schema.ts",
|
||||
],
|
||||
{ timeoutMs: 5000 },
|
||||
).catch(() => null);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { CHANNEL_MESSAGE_ACTION_NAMES } from "../channels/plugins/message-action-names.js";
|
||||
import type { ChannelMessageActionName } from "../channels/plugins/types.public.js";
|
||||
@@ -8,7 +12,6 @@ import { resolveMessageSecretScope } from "../cli/message-secret-scope.js";
|
||||
import { createOutboundSendDeps, type CliDeps } from "../cli/outbound-send-deps.js";
|
||||
import { withProgress } from "../cli/progress.js";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import type { OutboundSendDeps } from "../infra/outbound/deliver.js";
|
||||
import { runMessageAction } from "../infra/outbound/message-action-runner.js";
|
||||
import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ConnectPairingRequiredReason } from "../gateway/protocol/connect-error-details.js";
|
||||
import type { ConnectPairingRequiredReason } from "../../packages/gateway-protocol/src/connect-error-details.js";
|
||||
import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js";
|
||||
import type { resolveOsSummary } from "../infra/os-summary.js";
|
||||
import type { PluginCompatibilityNotice } from "../plugins/status.js";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { areRuntimeModelRefsEquivalent } from "../agents/model-runtime-aliases.js";
|
||||
import {
|
||||
buildPairingConnectRecoveryTitle,
|
||||
describePairingConnectRequirement,
|
||||
type ConnectPairingRequiredReason,
|
||||
} from "../gateway/protocol/connect-error-details.js";
|
||||
} from "../../packages/gateway-protocol/src/connect-error-details.js";
|
||||
import { areRuntimeModelRefsEquivalent } from "../agents/model-runtime-aliases.js";
|
||||
import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js";
|
||||
import type { Tone } from "../memory-host-sdk/status.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { withProgress } from "../cli/progress.js";
|
||||
import {
|
||||
normalizePairingConnectRequestId,
|
||||
readConnectPairingRequiredMessage,
|
||||
readPairingConnectErrorDetails,
|
||||
type ConnectPairingRequiredReason,
|
||||
} from "../gateway/protocol/connect-error-details.js";
|
||||
} from "../../packages/gateway-protocol/src/connect-error-details.js";
|
||||
import { withProgress } from "../cli/progress.js";
|
||||
import { readRestartSentinel } from "../infra/restart-sentinel.js";
|
||||
import { type RuntimeEnv } from "../runtime.js";
|
||||
import { createLazyImportLoader } from "../shared/lazy-promise.js";
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { existsSync } from "node:fs";
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
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-target.js";
|
||||
import type { GatewayProbeResult, probeGateway as probeGatewayFn } from "../gateway/probe.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../gateway/protocol/client-info.js";
|
||||
import type { MemoryProviderStatus } from "../memory-host-sdk/engine-storage.js";
|
||||
import { defaultSlotIdForKey } from "../plugins/slots.js";
|
||||
import { createLazyImportLoader } from "../shared/lazy-promise.js";
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import type { SessionsPatchParams, SessionsPatchResult } from "../gateway/protocol/index.js";
|
||||
import type {
|
||||
SessionsPatchParams,
|
||||
SessionsPatchResult,
|
||||
} from "../../packages/gateway-protocol/src/index.js";
|
||||
import { buildAgentMainSessionKey } from "../routing/session-key.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user