fix: align Code Agent heavy request timeouts
This commit is contained in:
@@ -4,7 +4,7 @@ import { createCloudApiServer } from "../../internal/cloud/server.mjs";
|
||||
const host = process.env.HWLAB_CLOUD_API_HOST || "0.0.0.0";
|
||||
const port = Number.parseInt(process.env.HWLAB_CLOUD_API_PORT || process.env.PORT || "6667", 10);
|
||||
const commitId = process.env.HWLAB_COMMIT_ID || process.env.HWLAB_GIT_SHA;
|
||||
const codeAgentTimeoutMs = parseTimeout(process.env.HWLAB_CODE_AGENT_TIMEOUT_MS, 120000, {
|
||||
const codeAgentTimeoutMs = parseTimeout(process.env.HWLAB_CODE_AGENT_TIMEOUT_MS, 150000, {
|
||||
min: 1000,
|
||||
max: 300000
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ import { createServer } from "node:http";
|
||||
|
||||
const serviceId = "hwlab-edge-proxy";
|
||||
const upstream = process.env.HWLAB_EDGE_UPSTREAM || "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667";
|
||||
const proxyTimeoutMs = parseTimeout(process.env.HWLAB_EDGE_PROXY_TIMEOUT_MS, 150000, {
|
||||
const proxyTimeoutMs = parseTimeout(process.env.HWLAB_EDGE_PROXY_TIMEOUT_MS, 180000, {
|
||||
min: 1000,
|
||||
max: 300000
|
||||
});
|
||||
|
||||
+3
-3
@@ -204,7 +204,7 @@
|
||||
"HWLAB_M3_PATCH_PANEL_URL": "http://hwlab-patch-panel.hwlab-dev.svc.cluster.local:7301",
|
||||
"HWLAB_CODE_AGENT_PROVIDER": "codex-stdio",
|
||||
"HWLAB_CODE_AGENT_MODEL": "gpt-5.5",
|
||||
"HWLAB_CODE_AGENT_TIMEOUT_MS": "120000",
|
||||
"HWLAB_CODE_AGENT_TIMEOUT_MS": "150000",
|
||||
"HWLAB_CODE_AGENT_OPENAI_BASE_URL": "http://172.26.26.227:17680/v1/responses",
|
||||
"HWLAB_CODE_AGENT_HWLAB_API_BASE_URL": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667",
|
||||
"HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED": "1",
|
||||
@@ -228,7 +228,7 @@
|
||||
"env": {
|
||||
"HWLAB_ENVIRONMENT": "dev",
|
||||
"HWLAB_API_BASE_URL": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667",
|
||||
"HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS": "150000",
|
||||
"HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS": "180000",
|
||||
"HWLAB_COMMIT_ID": "3df89fe",
|
||||
"HWLAB_IMAGE": "127.0.0.1:5000/hwlab/hwlab-cloud-web:3df89fe",
|
||||
"HWLAB_IMAGE_TAG": "3df89fe"
|
||||
@@ -366,7 +366,7 @@
|
||||
"env": {
|
||||
"HWLAB_EDGE_LISTEN": "0.0.0.0:6667",
|
||||
"HWLAB_EDGE_UPSTREAM": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667",
|
||||
"HWLAB_EDGE_PROXY_TIMEOUT_MS": "150000"
|
||||
"HWLAB_EDGE_PROXY_TIMEOUT_MS": "180000"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
},
|
||||
{
|
||||
"name": "HWLAB_CODE_AGENT_TIMEOUT_MS",
|
||||
"value": "120000"
|
||||
"value": "150000"
|
||||
},
|
||||
{
|
||||
"name": "HWLAB_CODE_AGENT_OPENAI_BASE_URL",
|
||||
@@ -249,7 +249,7 @@
|
||||
},
|
||||
{
|
||||
"name": "HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS",
|
||||
"value": "150000"
|
||||
"value": "180000"
|
||||
},
|
||||
{
|
||||
"name": "HWLAB_COMMIT_ID",
|
||||
@@ -826,7 +826,7 @@
|
||||
},
|
||||
{
|
||||
"name": "HWLAB_EDGE_PROXY_TIMEOUT_MS",
|
||||
"value": "150000"
|
||||
"value": "180000"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
|
||||
@@ -38,7 +38,7 @@ import {
|
||||
runM3IoSkillCommand
|
||||
} from "../../skills/hwlab-agent-runtime/scripts/src/m3-io-skill-client.mjs";
|
||||
|
||||
const DEFAULT_CODE_AGENT_TIMEOUT_MS = 120000;
|
||||
const DEFAULT_CODE_AGENT_TIMEOUT_MS = 150000;
|
||||
const DEFAULT_CODEX_COMMAND = "codex";
|
||||
const DEFAULT_MODEL = DEV_CODE_AGENT_PROVIDER_CONTRACT.model;
|
||||
const DEFAULT_PROJECT_ID = "prj_hwlab-cloud-workbench";
|
||||
|
||||
@@ -955,7 +955,7 @@ export function createCodexMcpJsonLineClient({ command = DEFAULT_CODEX_STDIO_COM
|
||||
return Array.isArray(result?.tools) ? result.tools.map((tool) => tool?.name).filter(Boolean) : [];
|
||||
}
|
||||
|
||||
async function callTool(name, args = {}, timeoutMs = 120000) {
|
||||
async function callTool(name, args = {}, timeoutMs = 150000) {
|
||||
return request("tools/call", {
|
||||
name,
|
||||
arguments: args
|
||||
@@ -2365,7 +2365,7 @@ function hasEnvValue(env, name) {
|
||||
}
|
||||
|
||||
function effectiveTimeout(timeoutMs) {
|
||||
return Number.isInteger(timeoutMs) && timeoutMs > 0 ? timeoutMs : 120000;
|
||||
return Number.isInteger(timeoutMs) && timeoutMs > 0 ? timeoutMs : 150000;
|
||||
}
|
||||
|
||||
function dropEmpty(value) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createServer, request as httpRequest } from "node:http";
|
||||
import { buildMetadataFromEnv } from "../build-metadata.mjs";
|
||||
import { DEV_ENDPOINT, ENVIRONMENT_DEV } from "../protocol/index.mjs";
|
||||
|
||||
const DEFAULT_PROXY_TIMEOUT_MS = 150000;
|
||||
const DEFAULT_PROXY_TIMEOUT_MS = 180000;
|
||||
|
||||
export function parsePort(value, fallback) {
|
||||
const parsed = Number.parseInt(value ?? "", 10);
|
||||
|
||||
@@ -258,9 +258,11 @@ test("compact commander summary exposes canPublish/canApply and dry-run devLiveC
|
||||
cloudWebDistFreshness: { status: "pass", mismatches: [] },
|
||||
codeAgentTimeoutReadiness: {
|
||||
status: "pass",
|
||||
frontendTimeoutMs: 35000,
|
||||
backendTimeoutMs: 120000,
|
||||
frontendTimeoutMs: 180000,
|
||||
backendTimeoutMs: 150000,
|
||||
requiredFrontendTimeoutMs: 35000,
|
||||
requiredBackendTimeoutMs: 150000,
|
||||
transportWaitsForBackend: true,
|
||||
summary: "ready"
|
||||
},
|
||||
runtimeReport: {
|
||||
@@ -290,9 +292,11 @@ test("compact summary blocks publish on stale Cloud Web source dist", () => {
|
||||
cloudWebDistFreshness: { status: "blocked", mismatches: ["index.html"] },
|
||||
codeAgentTimeoutReadiness: {
|
||||
status: "pass",
|
||||
frontendTimeoutMs: 35000,
|
||||
backendTimeoutMs: 120000,
|
||||
frontendTimeoutMs: 180000,
|
||||
backendTimeoutMs: 150000,
|
||||
requiredFrontendTimeoutMs: 35000,
|
||||
requiredBackendTimeoutMs: 150000,
|
||||
transportWaitsForBackend: true,
|
||||
summary: "ready"
|
||||
},
|
||||
runtimeReport: {
|
||||
@@ -322,8 +326,10 @@ test("compact summary separates Code Agent timeout and durable runtime blockers
|
||||
codeAgentTimeoutReadiness: {
|
||||
status: "blocked",
|
||||
frontendTimeoutMs: 4500,
|
||||
backendTimeoutMs: 120000,
|
||||
backendTimeoutMs: 150000,
|
||||
requiredFrontendTimeoutMs: 35000,
|
||||
requiredBackendTimeoutMs: 150000,
|
||||
transportWaitsForBackend: false,
|
||||
summary: "Code Agent browser timeout is too short."
|
||||
},
|
||||
runtimeReport: {
|
||||
@@ -357,6 +363,38 @@ test("compact summary separates Code Agent timeout and durable runtime blockers
|
||||
assert.ok(summary.blockedReasons.some((item) => item.id === "runtime-durable:runtime_durable_adapter_query_blocked"));
|
||||
});
|
||||
|
||||
test("compact summary blocks publish when Code Agent transport timeout does not exceed backend timeout", () => {
|
||||
const result = readiness();
|
||||
const summary = buildCommanderReadinessSummary({
|
||||
readiness: result,
|
||||
targetRef: "origin/main",
|
||||
generatedFromCommit: targetSha,
|
||||
explicitLive: false,
|
||||
cloudWebDistFreshness: { status: "pass", mismatches: [] },
|
||||
codeAgentTimeoutReadiness: {
|
||||
status: "blocked",
|
||||
frontendTimeoutMs: 150000,
|
||||
backendTimeoutMs: 150000,
|
||||
requiredFrontendTimeoutMs: 35000,
|
||||
requiredBackendTimeoutMs: 150000,
|
||||
transportWaitsForBackend: false,
|
||||
summary: "Code Agent timeout layering is unsafe."
|
||||
},
|
||||
runtimeReport: {
|
||||
runtimeIdentity: {
|
||||
ready: true,
|
||||
runtime: { durable: true, ready: true },
|
||||
readiness: { ready: true, durability: { ready: true } }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(summary.canPublish, false);
|
||||
assert.equal(summary.canApply, false);
|
||||
assert.equal(summary.codeAgentTimeoutReadiness.transportWaitsForBackend, false);
|
||||
assert.ok(summary.blockedReasons.some((item) => item.id === "code-agent-timeout-readiness"));
|
||||
});
|
||||
|
||||
test("compact summary keeps provider-secret blockers out of publish but blocks apply", () => {
|
||||
const result = readiness();
|
||||
const summary = buildCommanderReadinessSummary({
|
||||
@@ -367,9 +405,11 @@ test("compact summary keeps provider-secret blockers out of publish but blocks a
|
||||
cloudWebDistFreshness: { status: "pass", mismatches: [] },
|
||||
codeAgentTimeoutReadiness: {
|
||||
status: "pass",
|
||||
frontendTimeoutMs: 35000,
|
||||
backendTimeoutMs: 120000,
|
||||
frontendTimeoutMs: 180000,
|
||||
backendTimeoutMs: 150000,
|
||||
requiredFrontendTimeoutMs: 35000,
|
||||
requiredBackendTimeoutMs: 150000,
|
||||
transportWaitsForBackend: true,
|
||||
summary: "ready"
|
||||
},
|
||||
edgeReport: {
|
||||
|
||||
@@ -314,7 +314,7 @@ const runtimeKind = process.env.HWLAB_ARTIFACT_KIND || "health-placeholder";
|
||||
const entrypoint = process.env.HWLAB_SERVICE_ENTRYPOINT || "";
|
||||
const port = Number.parseInt(process.env.PORT || process.env.HWLAB_PORT || "8080", 10);
|
||||
const cloudApiBaseUrl = process.env.HWLAB_API_BASE_URL || "";
|
||||
const cloudApiProxyTimeoutMs = parseTimeout(process.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS, 150000, {
|
||||
const cloudApiProxyTimeoutMs = parseTimeout(process.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS, 180000, {
|
||||
min: 1000,
|
||||
max: 300000
|
||||
});
|
||||
|
||||
@@ -89,7 +89,7 @@ test("source/default workbench report cannot claim DEV-LIVE and documents the co
|
||||
});
|
||||
|
||||
test("Code Agent browser failure classifier emits Chinese timeout/provider/browser categories with traceId", () => {
|
||||
const timeout = classifyCodeAgentBrowserFailure(new Error("request timed out after 150000ms"), { traceId: "trc_timeout" });
|
||||
const timeout = classifyCodeAgentBrowserFailure(new Error("request timed out after 180000ms"), { traceId: "trc_timeout" });
|
||||
assert.equal(timeout.category, "timeout");
|
||||
assert.match(timeout.chineseSummary, /超时/u);
|
||||
assert.match(timeout.chineseSummary, /trc_timeout/u);
|
||||
|
||||
@@ -21,7 +21,8 @@ const expectedBlockedGuardCommand = `${guardCommand} --expect-blocked`;
|
||||
const digestPattern = /^sha256:[a-f0-9]{64}$/u;
|
||||
const commitPattern = /^[a-f0-9]{7,40}$/u;
|
||||
const minCodeAgentFrontendTimeoutMs = 35000;
|
||||
const defaultCodeAgentBackendTimeoutMs = 120000;
|
||||
const defaultCodeAgentBackendTimeoutMs = 150000;
|
||||
const minCodeAgentBackendTimeoutMs = 150000;
|
||||
|
||||
export function normalizeCommit(value) {
|
||||
if (typeof value !== "string") return "unknown";
|
||||
@@ -388,6 +389,8 @@ export function buildCommanderReadinessSummary({
|
||||
frontendTimeoutMs: null,
|
||||
backendTimeoutMs: defaultCodeAgentBackendTimeoutMs,
|
||||
requiredFrontendTimeoutMs: minCodeAgentFrontendTimeoutMs,
|
||||
requiredBackendTimeoutMs: minCodeAgentBackendTimeoutMs,
|
||||
transportWaitsForBackend: false,
|
||||
summary: "Code Agent timeout readiness was not inspected."
|
||||
};
|
||||
const runtimeDurable = classifyRuntimeDurableBlocker(runtimeReport, readiness.runtime);
|
||||
@@ -920,15 +923,18 @@ async function inspectCodeAgentTimeoutReadiness(repoRoot) {
|
||||
const frontendTimeoutMs = numericSourceConstant(appSource, "DEFAULT_CODE_AGENT_TIMEOUT_MS");
|
||||
const backendTimeoutMs = numericSourceConstant(chatSource, "DEFAULT_CODE_AGENT_TIMEOUT_MS");
|
||||
const frontendReady = Number.isInteger(frontendTimeoutMs) && frontendTimeoutMs >= minCodeAgentFrontendTimeoutMs;
|
||||
const backendReady = Number.isInteger(backendTimeoutMs) && backendTimeoutMs >= minCodeAgentFrontendTimeoutMs;
|
||||
const backendReady = Number.isInteger(backendTimeoutMs) && backendTimeoutMs >= minCodeAgentBackendTimeoutMs;
|
||||
const transportWaitsForBackend = Number.isInteger(frontendTimeoutMs) && Number.isInteger(backendTimeoutMs) && frontendTimeoutMs > backendTimeoutMs;
|
||||
return {
|
||||
status: frontendReady && backendReady ? "pass" : "blocked",
|
||||
status: frontendReady && backendReady && transportWaitsForBackend ? "pass" : "blocked",
|
||||
frontendTimeoutMs,
|
||||
backendTimeoutMs,
|
||||
requiredFrontendTimeoutMs: minCodeAgentFrontendTimeoutMs,
|
||||
summary: frontendReady && backendReady
|
||||
? "Code Agent browser/backend timeout budget is ready for provider latency."
|
||||
: "Code Agent browser timeout is too short for provider-backed replies; long requests can be misclassified as failed."
|
||||
requiredBackendTimeoutMs: minCodeAgentBackendTimeoutMs,
|
||||
transportWaitsForBackend,
|
||||
summary: frontendReady && backendReady && transportWaitsForBackend
|
||||
? "Code Agent browser/backend timeout budget is ready: browser transport waits for the structured backend result."
|
||||
: "Code Agent timeout layering is unsafe; long requests can be misclassified before cloud-api returns a structured result."
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
||||
const expectedPorts = Object.freeze({ frontend: 16666, api: 16667 });
|
||||
const codeAgentBackendTimeoutMs = "150000";
|
||||
const codeAgentTransportTimeoutMs = "180000";
|
||||
const legacyPublicPorts = new Set([6666, 6667]);
|
||||
const duplicateMappingAllowed = new Set(["hwlab-box-simu", "hwlab-gateway-simu"]);
|
||||
const tomlBareKeyPattern = /^[A-Za-z0-9_-]+$/u;
|
||||
@@ -232,7 +234,7 @@ function validateSource(ctx, manifest) {
|
||||
expectEqual(ctx, cloudApi?.env?.HWLAB_PUBLIC_ENDPOINT, endpoints.api?.url, "$.services.hwlab-cloud-api.env.HWLAB_PUBLIC_ENDPOINT", "cloud API public endpoint env");
|
||||
validateCloudApiDbSource(ctx, cloudApi?.env ?? {});
|
||||
validateCloudApiCodeAgentSource(ctx, cloudApi?.env ?? {});
|
||||
validateCodeAgentProxyTimeoutSource(ctx, { cloudWeb, edgeProxy });
|
||||
validateCodeAgentProxyTimeoutSource(ctx, { cloudApi, cloudWeb, edgeProxy });
|
||||
validateM3PatchPanelSource(ctx, patchPanel);
|
||||
expectEqual(ctx, cli?.env?.HWLAB_CLI_ENDPOINT, endpoints.api?.url, "$.services.hwlab-cli.env.HWLAB_CLI_ENDPOINT", "CLI endpoint env");
|
||||
expectEqual(ctx, tunnelClient?.env?.HWLAB_FRP_PUBLIC_PORT, String(expectedPorts.api), "$.services.hwlab-tunnel-client.env.HWLAB_FRP_PUBLIC_PORT", "tunnel API public port env");
|
||||
@@ -377,7 +379,7 @@ function validateCloudApiCodeAgentSource(ctx, env) {
|
||||
const contract = DEV_CODE_AGENT_PROVIDER_CONTRACT;
|
||||
expectEqual(ctx, env.HWLAB_CODE_AGENT_PROVIDER, contract.codeAgentProvider, "$.services.hwlab-cloud-api.env.HWLAB_CODE_AGENT_PROVIDER", "cloud API Code Agent provider");
|
||||
expectEqual(ctx, env.HWLAB_CODE_AGENT_MODEL, contract.model, "$.services.hwlab-cloud-api.env.HWLAB_CODE_AGENT_MODEL", "cloud API Code Agent model");
|
||||
expectEqual(ctx, env.HWLAB_CODE_AGENT_TIMEOUT_MS, "120000", "$.services.hwlab-cloud-api.env.HWLAB_CODE_AGENT_TIMEOUT_MS", "cloud API Code Agent hard timeout budget");
|
||||
expectEqual(ctx, env.HWLAB_CODE_AGENT_TIMEOUT_MS, codeAgentBackendTimeoutMs, "$.services.hwlab-cloud-api.env.HWLAB_CODE_AGENT_TIMEOUT_MS", "cloud API Code Agent hard timeout budget");
|
||||
expectEqual(
|
||||
ctx,
|
||||
env.HWLAB_CODE_AGENT_OPENAI_BASE_URL,
|
||||
@@ -410,9 +412,26 @@ function validateCloudApiCodeAgentSource(ctx, env) {
|
||||
expectEqual(ctx, env.OPENAI_API_KEY, codeAgentSecretRefPlaceholder(), "$.services.hwlab-cloud-api.env.OPENAI_API_KEY", "cloud API Code Agent OpenAI Secret reference");
|
||||
}
|
||||
|
||||
function validateCodeAgentProxyTimeoutSource(ctx, { cloudWeb, edgeProxy }) {
|
||||
expectEqual(ctx, cloudWeb?.env?.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS, "150000", "$.services.hwlab-cloud-web.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS", "Cloud Web same-origin Code Agent proxy timeout budget");
|
||||
expectEqual(ctx, edgeProxy?.env?.HWLAB_EDGE_PROXY_TIMEOUT_MS, "150000", "$.services.hwlab-edge-proxy.env.HWLAB_EDGE_PROXY_TIMEOUT_MS", "edge proxy Code Agent timeout budget");
|
||||
function validateCodeAgentProxyTimeoutSource(ctx, { cloudApi, cloudWeb, edgeProxy }) {
|
||||
expectEqual(ctx, cloudWeb?.env?.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS, codeAgentTransportTimeoutMs, "$.services.hwlab-cloud-web.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS", "Cloud Web same-origin Code Agent proxy timeout budget");
|
||||
expectEqual(ctx, edgeProxy?.env?.HWLAB_EDGE_PROXY_TIMEOUT_MS, codeAgentTransportTimeoutMs, "$.services.hwlab-edge-proxy.env.HWLAB_EDGE_PROXY_TIMEOUT_MS", "edge proxy Code Agent timeout budget");
|
||||
const backendTimeoutMs = cloudApi?.env?.HWLAB_CODE_AGENT_TIMEOUT_MS;
|
||||
expect(
|
||||
ctx,
|
||||
Number.parseInt(cloudWeb?.env?.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS ?? "0", 10) > Number.parseInt(backendTimeoutMs ?? "0", 10),
|
||||
"code_agent_timeout_layering",
|
||||
"$.services.hwlab-cloud-web.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS",
|
||||
"Cloud Web proxy must wait longer than cloud-api so structured Code Agent timeout wins",
|
||||
{ expected: `>${backendTimeoutMs}`, actual: cloudWeb?.env?.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS }
|
||||
);
|
||||
expect(
|
||||
ctx,
|
||||
Number.parseInt(edgeProxy?.env?.HWLAB_EDGE_PROXY_TIMEOUT_MS ?? "0", 10) > Number.parseInt(backendTimeoutMs ?? "0", 10),
|
||||
"code_agent_timeout_layering",
|
||||
"$.services.hwlab-edge-proxy.env.HWLAB_EDGE_PROXY_TIMEOUT_MS",
|
||||
"Edge proxy must wait longer than cloud-api so structured Code Agent timeout wins",
|
||||
{ expected: `>${backendTimeoutMs}`, actual: edgeProxy?.env?.HWLAB_EDGE_PROXY_TIMEOUT_MS }
|
||||
);
|
||||
}
|
||||
|
||||
function renderPlan(source) {
|
||||
@@ -553,7 +572,7 @@ function validateCloudApiCodeAgentArtifacts(ctx, workloads) {
|
||||
const env = new Map((container?.env ?? []).map((entry) => [entry.name, entry]));
|
||||
expectEqual(ctx, env.get("HWLAB_CODE_AGENT_PROVIDER")?.value, contract.codeAgentProvider, "deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.HWLAB_CODE_AGENT_PROVIDER", "cloud API workload Code Agent provider");
|
||||
expectEqual(ctx, env.get("HWLAB_CODE_AGENT_MODEL")?.value, contract.model, "deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.HWLAB_CODE_AGENT_MODEL", "cloud API workload Code Agent model");
|
||||
expectEqual(ctx, env.get("HWLAB_CODE_AGENT_TIMEOUT_MS")?.value, "120000", "deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.HWLAB_CODE_AGENT_TIMEOUT_MS", "cloud API workload Code Agent hard timeout budget");
|
||||
expectEqual(ctx, env.get("HWLAB_CODE_AGENT_TIMEOUT_MS")?.value, codeAgentBackendTimeoutMs, "deploy/k8s/base/workloads.yaml.hwlab-cloud-api.env.HWLAB_CODE_AGENT_TIMEOUT_MS", "cloud API workload Code Agent hard timeout budget");
|
||||
expectEqual(
|
||||
ctx,
|
||||
env.get("HWLAB_CODE_AGENT_OPENAI_BASE_URL")?.value,
|
||||
@@ -591,8 +610,25 @@ function validateCodeAgentProxyTimeoutArtifacts(ctx, workloads) {
|
||||
const workloadItems = mapByServiceId(listItems(workloads));
|
||||
const cloudWebEnv = new Map((workloadItems.get("hwlab-cloud-web")?.spec?.template?.spec?.containers?.[0]?.env ?? []).map((entry) => [entry.name, entry.value]));
|
||||
const edgeProxyEnv = new Map((workloadItems.get("hwlab-edge-proxy")?.spec?.template?.spec?.containers?.[0]?.env ?? []).map((entry) => [entry.name, entry.value]));
|
||||
expectEqual(ctx, cloudWebEnv.get("HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS"), "150000", "deploy/k8s/base/workloads.yaml.hwlab-cloud-web.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS", "Cloud Web workload same-origin Code Agent proxy timeout budget");
|
||||
expectEqual(ctx, edgeProxyEnv.get("HWLAB_EDGE_PROXY_TIMEOUT_MS"), "150000", "deploy/k8s/base/workloads.yaml.hwlab-edge-proxy.env.HWLAB_EDGE_PROXY_TIMEOUT_MS", "edge proxy workload Code Agent timeout budget");
|
||||
const cloudApiEnv = new Map((workloadItems.get("hwlab-cloud-api")?.spec?.template?.spec?.containers?.[0]?.env ?? []).map((entry) => [entry.name, entry.value]));
|
||||
expectEqual(ctx, cloudWebEnv.get("HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS"), codeAgentTransportTimeoutMs, "deploy/k8s/base/workloads.yaml.hwlab-cloud-web.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS", "Cloud Web workload same-origin Code Agent proxy timeout budget");
|
||||
expectEqual(ctx, edgeProxyEnv.get("HWLAB_EDGE_PROXY_TIMEOUT_MS"), codeAgentTransportTimeoutMs, "deploy/k8s/base/workloads.yaml.hwlab-edge-proxy.env.HWLAB_EDGE_PROXY_TIMEOUT_MS", "edge proxy workload Code Agent timeout budget");
|
||||
expect(
|
||||
ctx,
|
||||
Number.parseInt(cloudWebEnv.get("HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS") ?? "0", 10) > Number.parseInt(cloudApiEnv.get("HWLAB_CODE_AGENT_TIMEOUT_MS") ?? "0", 10),
|
||||
"code_agent_timeout_layering",
|
||||
"deploy/k8s/base/workloads.yaml.hwlab-cloud-web.env.HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS",
|
||||
"Cloud Web workload proxy timeout must exceed cloud-api Code Agent timeout",
|
||||
{ expected: `>${cloudApiEnv.get("HWLAB_CODE_AGENT_TIMEOUT_MS")}`, actual: cloudWebEnv.get("HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS") }
|
||||
);
|
||||
expect(
|
||||
ctx,
|
||||
Number.parseInt(edgeProxyEnv.get("HWLAB_EDGE_PROXY_TIMEOUT_MS") ?? "0", 10) > Number.parseInt(cloudApiEnv.get("HWLAB_CODE_AGENT_TIMEOUT_MS") ?? "0", 10),
|
||||
"code_agent_timeout_layering",
|
||||
"deploy/k8s/base/workloads.yaml.hwlab-edge-proxy.env.HWLAB_EDGE_PROXY_TIMEOUT_MS",
|
||||
"Edge workload proxy timeout must exceed cloud-api Code Agent timeout",
|
||||
{ expected: `>${cloudApiEnv.get("HWLAB_CODE_AGENT_TIMEOUT_MS")}`, actual: edgeProxyEnv.get("HWLAB_EDGE_PROXY_TIMEOUT_MS") }
|
||||
);
|
||||
}
|
||||
|
||||
async function buildPlan() {
|
||||
|
||||
@@ -20,7 +20,7 @@ const webRoot = path.join(repoRoot, "web/hwlab-cloud-web");
|
||||
const defaultLiveUrl = "http://74.48.78.17:16666/";
|
||||
const helpOwner = "codex_1779444232735_1";
|
||||
const legacyFailureWindowMs = 4500;
|
||||
const codeAgentLongTimeoutMs = 150000;
|
||||
const codeAgentLongTimeoutMs = 180000;
|
||||
const localAgentFixtureDelayMs = 5200;
|
||||
const codeAgentE2ePrompts = Object.freeze([
|
||||
{
|
||||
@@ -2565,7 +2565,7 @@ function hasCodeAgentLongTimeoutContract(files) {
|
||||
const app = files.app;
|
||||
return (
|
||||
/DEFAULT_API_TIMEOUT_MS\s*=\s*4500/u.test(app) &&
|
||||
/DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*150000/u.test(app) &&
|
||||
/DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*180000/u.test(app) &&
|
||||
/async function sendAgentMessage[\s\S]*?fetchJson\("\/v1\/agent\/chat"[\s\S]*?timeoutMs:\s*CODE_AGENT_TIMEOUT_MS/u.test(app) &&
|
||||
/timeoutMs\s*=\s*API_TIMEOUT_MS/u.test(functionBody(app, "fetchJson")) &&
|
||||
/timeoutName\s*=\s*path/u.test(functionBody(app, "fetchJson")) &&
|
||||
@@ -2619,7 +2619,7 @@ function hasCodeAgentConversationUxStates({ app, styles }) {
|
||||
/字段缺失:证据不足/u.test(app) &&
|
||||
/当前不能执行/u.test(app) &&
|
||||
/DEFAULT_API_TIMEOUT_MS\s*=\s*4500/u.test(app) &&
|
||||
/DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*150000/u.test(app) &&
|
||||
/DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*180000/u.test(app) &&
|
||||
/timeoutMs:\s*CODE_AGENT_TIMEOUT_MS/u.test(app) &&
|
||||
/HWLAB_CLOUD_WEB_CONFIG/u.test(app) &&
|
||||
/失败时会保留输入供重试/u.test(app) &&
|
||||
|
||||
@@ -1639,7 +1639,7 @@ function parseTimeout(value) {
|
||||
if (!Number.isInteger(parsed) || parsed <= 0) {
|
||||
throw new Error("--timeout-ms must be a positive integer");
|
||||
}
|
||||
return Math.min(parsed, 120000);
|
||||
return Math.min(parsed, 180000);
|
||||
}
|
||||
|
||||
function worstStatus(statuses) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
} from "./code-agent-m3-evidence.mjs";
|
||||
|
||||
const DEFAULT_API_TIMEOUT_MS = 4500;
|
||||
const DEFAULT_CODE_AGENT_TIMEOUT_MS = 150000;
|
||||
const DEFAULT_CODE_AGENT_TIMEOUT_MS = 180000;
|
||||
const API_TIMEOUT_MS = resolveTimeoutMs("apiTimeoutMs", DEFAULT_API_TIMEOUT_MS, { min: 500, max: 30000 });
|
||||
const CODE_AGENT_TIMEOUT_MS = resolveTimeoutMs("codeAgentTimeoutMs", DEFAULT_CODE_AGENT_TIMEOUT_MS, { min: 50, max: 300000 });
|
||||
const rpcReadMethods = Object.freeze([
|
||||
|
||||
@@ -383,7 +383,7 @@ assert.match(app, /renderRecords\(state\.liveSurface\)/);
|
||||
assert.match(app, /traceId: error\.traceId \|\| traceId/);
|
||||
assert.match(app, /error\.traceId = (?:traceId|response\.data\?\.traceId \|\| traceId)/);
|
||||
assert.match(app, /DEFAULT_API_TIMEOUT_MS\s*=\s*4500/);
|
||||
assert.match(app, /DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*150000/);
|
||||
assert.match(app, /DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*180000/);
|
||||
assert.match(app, /async function sendAgentMessage[\s\S]*?timeoutMs:\s*CODE_AGENT_TIMEOUT_MS/);
|
||||
assert.match(functionBody(app, "fetchJson"), /timeoutMs\s*=\s*API_TIMEOUT_MS/);
|
||||
for (const hardwareTerm of [
|
||||
@@ -878,7 +878,7 @@ assert.match(app, /createdAt/);
|
||||
assert.match(app, /updatedAt/);
|
||||
assert.match(app, /error\?\.message/);
|
||||
assert.match(app, /DEFAULT_API_TIMEOUT_MS\s*=\s*4500/);
|
||||
assert.match(app, /DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*150000/);
|
||||
assert.match(app, /DEFAULT_CODE_AGENT_TIMEOUT_MS\s*=\s*180000/);
|
||||
assert.match(app, /CODE_AGENT_TIMEOUT_MS/);
|
||||
assert.match(app, /timeoutMs:\s*CODE_AGENT_TIMEOUT_MS/);
|
||||
assert.match(app, /HWLAB_CLOUD_WEB_CONFIG/);
|
||||
|
||||
Reference in New Issue
Block a user