|
|
|
@@ -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() {
|
|
|
|
|