190 lines
6.0 KiB
JavaScript
190 lines
6.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { classifyCodeAgentStatusSummary } from "./code-agent-status.mjs";
|
|
|
|
const liveRevision = Object.freeze({
|
|
healthLive: {
|
|
ok: true,
|
|
status: 200,
|
|
data: {
|
|
serviceId: "hwlab-cloud-api",
|
|
status: "ok",
|
|
commitId: "7de6edd2c41f54e4265e822d2593fa67057fa41a"
|
|
}
|
|
}
|
|
});
|
|
|
|
test("summarizes long-lived Code Agent as green with current deployment revision only", () => {
|
|
const summary = classifyCodeAgentStatusSummary({
|
|
live: liveRevision,
|
|
availability: {
|
|
status: "codex-stdio-feasible",
|
|
ready: true,
|
|
provider: "codex-stdio",
|
|
mode: "codex-stdio",
|
|
backend: "hwlab-cloud-api/codex-stdio",
|
|
capabilityLevel: "long-lived-codex-stdio-session",
|
|
sessionMode: "codex-mcp-stdio-long-lived",
|
|
session: {
|
|
status: "idle",
|
|
lastTraceId: "trc_ready"
|
|
},
|
|
longLivedSessionGate: {
|
|
status: "pass"
|
|
},
|
|
codexStdioFeasibility: {
|
|
canStartLongLivedCodexStdio: true
|
|
}
|
|
}
|
|
});
|
|
|
|
assert.equal(summary.kind, "long-lived-session");
|
|
assert.equal(summary.label, "长会话可用");
|
|
assert.equal(summary.tone, "ok");
|
|
assert.equal(summary.codeAgentStatus, "codex-stdio-feasible");
|
|
assert.equal(summary.providerModeBackend, "codex-stdio / codex-stdio / hwlab-cloud-api/codex-stdio");
|
|
assert.equal(summary.capabilityLevel, "long-lived-codex-stdio-session");
|
|
assert.equal(summary.sessionSummary, "codex-mcp-stdio-long-lived / idle");
|
|
assert.equal(summary.readinessBlockers.length, 0);
|
|
assert.equal(summary.lastTraceId, "trc_ready");
|
|
assert.equal(summary.deploymentRevision, "7de6edd2c41f");
|
|
assert.equal(Object.keys(summary.fields).includes("sourceMain"), false);
|
|
});
|
|
|
|
test("maps degraded readonly session tools to warning, not green", () => {
|
|
const summary = classifyCodeAgentStatusSummary({
|
|
availability: {
|
|
status: "partial",
|
|
ready: false,
|
|
provider: "codex-readonly-runner",
|
|
backend: "hwlab-cloud-api/controlled-readonly-session-registry",
|
|
capabilityLevel: "read-only-session-tools",
|
|
sessionMode: "controlled-readonly-session-registry",
|
|
session: {
|
|
status: "idle",
|
|
lastTraceId: "trc_readonly"
|
|
},
|
|
runner: {
|
|
kind: "hwlab-readonly-runner",
|
|
writeCapable: false
|
|
},
|
|
blockers: [
|
|
{ code: "stdio_protocol_not_wired" }
|
|
]
|
|
}
|
|
});
|
|
|
|
assert.equal(summary.kind, "read-only-session-tools");
|
|
assert.equal(summary.label, "只读会话工具");
|
|
assert.equal(summary.tone, "warn");
|
|
assert.equal(summary.readinessBlockers.includes("stdio_protocol_not_wired"), true);
|
|
assert.equal(summary.lastTraceId, "trc_readonly");
|
|
});
|
|
|
|
test("maps text fallback to warning with safe labels", () => {
|
|
const summary = classifyCodeAgentStatusSummary({
|
|
availability: {
|
|
status: "available",
|
|
ready: true,
|
|
provider: "openai-responses",
|
|
mode: "openai",
|
|
backend: "hwlab-cloud-api/openai-responses",
|
|
capabilityLevel: "text-chat-only",
|
|
runner: {
|
|
kind: "openai-responses-fallback"
|
|
}
|
|
}
|
|
});
|
|
|
|
assert.equal(summary.kind, "fallback-text-chat-only");
|
|
assert.equal(summary.label, "文本备用通道");
|
|
assert.equal(summary.tone, "warn");
|
|
assert.equal(summary.provider, "openai-responses");
|
|
assert.equal(summary.capabilityLevel, "text-chat-only");
|
|
});
|
|
|
|
test("maps stateless one-shot runner separately from long-lived sessions", () => {
|
|
const summary = classifyCodeAgentStatusSummary({
|
|
latestMessage: {
|
|
status: "completed",
|
|
provider: "codex-cli",
|
|
backend: "hwlab-cloud-api/codex-cli",
|
|
capabilityLevel: "text-chat-only",
|
|
sessionMode: "ephemeral-one-shot",
|
|
runner: {
|
|
kind: "codex-cli-one-shot-ephemeral"
|
|
},
|
|
runnerLimitations: ["one-shot", "not-durable-session"],
|
|
traceId: "trc_one_shot"
|
|
}
|
|
});
|
|
|
|
assert.equal(summary.kind, "stateless-one-shot");
|
|
assert.equal(summary.label, "一次性执行");
|
|
assert.equal(summary.tone, "warn");
|
|
assert.equal(summary.sessionMode, "ephemeral-one-shot");
|
|
assert.equal(summary.lastTraceId, "trc_one_shot");
|
|
});
|
|
|
|
test("maps HWLAB Skill CLI API control to distinct green state when ready", () => {
|
|
const summary = classifyCodeAgentStatusSummary({
|
|
latestMessage: {
|
|
status: "completed",
|
|
provider: "hwlab-skill-cli",
|
|
backend: "hwlab-cloud-api/hwlab-agent-runtime-skill-cli",
|
|
capabilityLevel: "hwlab-api-control-ready",
|
|
sessionMode: "controlled-m3-io-skill-cli",
|
|
session: {
|
|
status: "idle",
|
|
lastTraceId: "trc_skill"
|
|
},
|
|
toolCalls: [
|
|
{
|
|
type: "skill-cli",
|
|
route: "/v1/m3/io",
|
|
status: "completed",
|
|
controlReady: true
|
|
}
|
|
],
|
|
providerTrace: {
|
|
controlReady: true
|
|
}
|
|
}
|
|
});
|
|
|
|
assert.equal(summary.kind, "skill-cli-api-control");
|
|
assert.equal(summary.label, "HWLAB Skill CLI 控制");
|
|
assert.equal(summary.tone, "ok");
|
|
assert.equal(summary.provider, "hwlab-skill-cli");
|
|
assert.equal(summary.capabilityLevel, "hwlab-api-control-ready");
|
|
});
|
|
|
|
test("maps blockers to blocked tone and redacts secret-like fields", () => {
|
|
const summary = classifyCodeAgentStatusSummary({
|
|
availability: {
|
|
status: "blocked",
|
|
ready: false,
|
|
provider: "openai-responses",
|
|
backend: "Secret hwlab-code-agent-provider should not show",
|
|
capabilityLevel: "blocked",
|
|
reason: "OPENAI_API_KEY_missing",
|
|
error: {
|
|
code: "provider_unavailable",
|
|
providerStatus: 503
|
|
},
|
|
missingEnv: ["OPENAI_API_KEY"],
|
|
traceId: "trc_blocked"
|
|
}
|
|
});
|
|
|
|
assert.equal(summary.kind, "blocked");
|
|
assert.equal(summary.label, "服务受阻");
|
|
assert.equal(summary.tone, "blocked");
|
|
assert.equal(summary.backend, "已隐藏");
|
|
assert.equal(summary.readinessBlockers.includes("provider_config_blocked"), true);
|
|
assert.equal(summary.readinessBlockers.includes("provider_unavailable"), true);
|
|
assert.equal(summary.readinessBlockers.includes("provider_http_503"), true);
|
|
assert.equal(summary.lastTraceId, "trc_blocked");
|
|
});
|