fix: block code agent non-2xx readiness

This commit is contained in:
Code Queue Review
2026-05-23 02:39:41 +00:00
parent 892a0276bd
commit 6961baedb7
8 changed files with 722 additions and 157 deletions
+72 -8
View File
@@ -396,6 +396,9 @@ async function sendAgentMessage(message, conversationId, traceId = nextProtocolI
});
if (!response.ok) {
if (isBlockedAgentResponse(response.data, response.status)) {
return normalizeBlockedAgentResult(response.data, response.status, traceId, response.error);
}
const error = new Error(response.error || "Code Agent 请求失败");
error.traceId = traceId;
throw error;
@@ -441,9 +444,27 @@ async function fetchJson(path, options = {}) {
signal: controller.signal
});
const text = await response.text();
const data = text ? JSON.parse(text) : null;
let data = null;
try {
data = text ? JSON.parse(text) : null;
} catch (error) {
if (response.ok) throw error;
return {
ok: false,
path,
status: response.status,
data: null,
error: `${path} HTTP ${response.status}:响应不是 JSON`
};
}
if (!response.ok) {
throw new Error(`${path} HTTP ${response.status}${messageFromPayload(data)}`);
return {
ok: false,
path,
status: response.status,
data,
error: `${path} HTTP ${response.status}${messageFromPayload(data)}`
};
}
return { ok: true, path, status: response.status, data };
} catch (error) {
@@ -1456,7 +1477,9 @@ function classifyCodeAgentCompletion(result) {
function failureMessage(result) {
if (result?.error?.code === "provider_unavailable" || result?.availability?.status === "blocked") {
const availability = result.availability ?? codeAgentAvailabilityFromResult(result);
const availability = result.error?.providerStatus || result.availability?.status !== "blocked"
? codeAgentAvailabilityFromResult(result)
: result.availability ?? codeAgentAvailabilityFromResult(result);
const missing = Array.isArray(result.error?.missingEnv) && result.error.missingEnv.length > 0
? ` 当前缺口:${result.error.missingEnv.join("、")}`
: "";
@@ -1612,25 +1635,66 @@ function messageFromPayload(payload) {
return payload.error?.message || payload.error?.code || payload.message || JSON.stringify(payload).slice(0, 160);
}
function normalizeBlockedAgentResult(payload, httpStatus, traceId, fallbackMessage) {
const { reply, ...safePayload } = payload;
const providerStatus = payload.error?.providerStatus ?? httpStatus;
const error = {
...(payload.error && typeof payload.error === "object" ? payload.error : {}),
code: payload.error?.code ?? "provider_unavailable",
message: payload.error?.message ?? fallbackMessage ?? `Code Agent provider HTTP ${httpStatus}`,
providerStatus
};
return {
...safePayload,
status: "failed",
traceId: payload.traceId || traceId,
error,
availability: payload.availability ?? codeAgentAvailabilityFromResult({ error })
};
}
function isBlockedAgentResponse(payload, httpStatus) {
return Boolean(
payload &&
typeof payload === "object" &&
(
isHttpNon2xxStatus(httpStatus) ||
isHttpNon2xxStatus(payload.error?.providerStatus) ||
payload.status === "blocked" ||
payload.error?.code === "provider_unavailable" ||
payload.availability?.status === "blocked"
)
);
}
function isHttpNon2xxStatus(value) {
return typeof value === "number" && Number.isInteger(value) && (value < 200 || value > 299);
}
function codeAgentAvailabilityFrom(live) {
return live?.restIndex?.data?.codeAgent ?? live?.healthLive?.data?.codeAgent ?? null;
}
function codeAgentAvailabilityFromResult(result) {
const missingEnv = Array.isArray(result?.error?.missingEnv) ? result.error.missingEnv : [];
const providerStatus = result?.error?.providerStatus;
const credentialBlocked = missingEnv.includes("OPENAI_API_KEY");
return {
status: "blocked",
blocker: "凭证缺口",
blocker: credentialBlocked ? "凭证缺口" : "provider_unavailable",
reason: result?.error?.code ?? "provider_unavailable",
summary: "真实后端已接入,但当前 DEV provider Secret hwlab-code-agent-provider/openai-api-key 未注入,因此不能返回真实回复。",
missingEnv: result?.error?.missingEnv ?? [],
secretRefs: [
summary: providerStatus
? `真实后端已接入,但当前 provider 上游返回 HTTP ${providerStatus};本次保持 BLOCKED/provider_unavailable,不会冒充真实 Code Agent 回复。`
: "真实后端已接入,但当前 DEV provider Secret hwlab-code-agent-provider/openai-api-key 未注入,因此不能返回真实回复。",
missingEnv,
secretRefs: credentialBlocked ? [
{
env: "OPENAI_API_KEY",
secretName: "hwlab-code-agent-provider",
secretKey: "openai-api-key",
redacted: true
}
]
] : []
};
}
+4
View File
@@ -320,6 +320,10 @@ assert.doesNotMatch(html, /主流程[\s\S]*添加草稿/u);
assert.match(app, /sendAgentMessage/);
assert.match(app, /fetchJson\("\/v1\/agent\/chat"/);
assert.match(app, /Code Agent 调用失败/);
assert.match(app, /normalizeBlockedAgentResult/);
assert.match(app, /isBlockedAgentResponse/);
assert.match(app, /isHttpNon2xxStatus/);
assert.match(app, /providerStatus/);
assert.match(app, /codeAgentAvailability/);
assert.match(app, /codeAgentAvailabilityFrom/);
assert.match(app, /latestCompletedAgentMessage/);