fix: allow v02 gateway protocol environment

This commit is contained in:
Codex
2026-05-29 15:40:20 +08:00
parent dc6a0b1bc6
commit 2fe1c89686
6 changed files with 18 additions and 9 deletions
+3 -1
View File
@@ -472,7 +472,7 @@ test("cloud api internal device-pod gateway dispatch is service-only and fail-cl
test("cloud api internal device-pod gateway dispatch uses gateway poll result", async () => {
const server = createCloudApiServer({
env: { HWLAB_ACCESS_CONTROL_REQUIRED: "1" },
env: { HWLAB_ACCESS_CONTROL_REQUIRED: "1", HWLAB_ENVIRONMENT: "v02" },
now: () => "2026-05-28T00:00:00.000Z"
});
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
@@ -503,6 +503,7 @@ test("cloud api internal device-pod gateway dispatch uses gateway poll result",
const queued = await postJson(port, "/v1/gateway/poll", { gatewayId: "gtw_devicepod_test", gatewaySessionId: "gws_devicepod_test" });
assert.equal(queued.status, 200);
assert.equal(queued.body.type, "request");
assert.equal(queued.body.request.meta.environment, "v02");
assert.equal(queued.body.request.method, "hardware.invoke.shell");
assert.equal(queued.body.request.params.input.command, "node tools/device-host-cli.mjs health");
@@ -527,6 +528,7 @@ test("cloud api internal device-pod gateway dispatch uses gateway poll result",
const dispatch = await dispatchPromise;
assert.equal(dispatch.status, 200);
assert.equal(dispatch.body.meta.environment, "v02");
assert.equal(dispatch.body.result.status, "completed");
assert.equal(dispatch.body.result.dispatch.stdout, "host cli ok");
} finally {
+2 -2
View File
@@ -1,6 +1,6 @@
import { randomUUID } from "node:crypto";
import { ENVIRONMENT_DEV, JSON_RPC_VERSION } from "../protocol/index.mjs";
import { ENVIRONMENT_DEV, JSON_RPC_VERSION, isProtocolEnvironment } from "../protocol/index.mjs";
import { CLOUD_API_SERVICE_ID } from "../audit/index.mjs";
const DEFAULT_STALE_MS = 30000;
@@ -188,7 +188,7 @@ export function createGatewayShellRequest({ id, params = {}, meta = {} }) {
traceId: meta.traceId ?? params.traceId ?? `trc_gateway_shell_${randomUUID()}`,
actorId: meta.actorId,
serviceId: CLOUD_API_SERVICE_ID,
environment: ENVIRONMENT_DEV
environment: isProtocolEnvironment(meta.environment) ? meta.environment : ENVIRONMENT_DEV
}
};
}
+1 -1
View File
@@ -207,7 +207,7 @@ test("cloud-api runtime accepts register/report/invoke and exposes audit/evidenc
projectId: "prj_01J00000000000000000000010",
gatewaySessionId: "gws_01J00000000000000000000010",
gatewayId: "gtw_01J00000000000000000000010",
serviceId: "hwlab-gateway-simu",
serviceId: "hwlab-gateway",
endpoint: "http://127.0.0.1:7101"
});
assert.equal(gateway.registered, true);
+2 -1
View File
@@ -5,6 +5,7 @@ import {
ERROR_CODES,
HwlabProtocolError,
JSON_RPC_VERSION,
isProtocolEnvironment,
validateRequest,
validateResponse
} from "../protocol/index.mjs";
@@ -215,7 +216,7 @@ export function createResponseMeta(requestMeta = {}) {
const meta = {
traceId: requestMeta.traceId || `trc_${randomUUID()}`,
serviceId: CLOUD_API_SERVICE_ID,
environment: ENVIRONMENT_DEV
environment: isProtocolEnvironment(requestMeta.environment) ? requestMeta.environment : ENVIRONMENT_DEV
};
if (requestMeta.actorId) {
+1 -1
View File
@@ -551,7 +551,7 @@ async function handleInternalDevicePodGatewayDispatch(request, response, options
summary: dispatch.message ?? dispatch.stderr ?? dispatch.status ?? result.status ?? "gateway dispatch failed"
}
},
requestMeta: { traceId, serviceId: "hwlab-device-pod" }
requestMeta: { traceId, serviceId: "hwlab-device-pod", environment: runtimeEnvironment(options.env ?? process.env) }
}));
}
+9 -3
View File
@@ -1,4 +1,6 @@
export const ENVIRONMENT_DEV = "dev";
export const ENVIRONMENT_V02 = "v02";
export const PROTOCOL_ENVIRONMENTS = Object.freeze([ENVIRONMENT_DEV, ENVIRONMENT_V02]);
export const DEV_ENDPOINT = "http://74.48.78.17:16667";
export const DEV_FRONTEND_ENDPOINT = "http://74.48.78.17:16666";
export const JSON_RPC_VERSION = "2.0";
@@ -307,6 +309,10 @@ export function isFrozenServiceId(serviceId) {
return SERVICE_IDS.includes(serviceId);
}
export function isProtocolEnvironment(environment) {
return PROTOCOL_ENVIRONMENTS.includes(environment);
}
export function isProtocolId(value) {
return typeof value === "string" && protocolIdPattern.test(value);
}
@@ -321,7 +327,7 @@ export function validateMeta(meta) {
if (!isFrozenServiceId(meta.serviceId)) {
throw new Error(`unknown serviceId ${JSON.stringify(meta.serviceId)}`);
}
if (meta.environment !== ENVIRONMENT_DEV) {
if (!isProtocolEnvironment(meta.environment)) {
throw new Error(`unsupported environment ${JSON.stringify(meta.environment)}`);
}
}
@@ -445,8 +451,8 @@ function assertProtocolField(kind, field, value) {
if (timestampFieldNames.has(field) && Number.isNaN(Date.parse(value))) {
throw new Error(`${kind}.${field} must be an RFC 3339 timestamp`);
}
if (field === "environment" && value !== ENVIRONMENT_DEV) {
throw new Error(`${kind}.environment must be ${ENVIRONMENT_DEV}`);
if (field === "environment" && !isProtocolEnvironment(value)) {
throw new Error(`${kind}.environment must be one of ${PROTOCOL_ENVIRONMENTS.join(", ")}`);
}
if (field === "serviceId" && !isFrozenServiceId(value)) {
throw new Error(`${kind}.serviceId is not a frozen service id`);