补齐 Code Agent 长会话生命周期控制

This commit is contained in:
Code Queue Review
2026-05-24 04:07:22 +00:00
parent 12d4847d09
commit 033a9da400
15 changed files with 1016 additions and 190 deletions
+11 -5
View File
@@ -2192,6 +2192,9 @@ function defaultTopologyIsM3Only() {
function trustedRecordGroups({ html, app, styles }) {
const source = `${html}\n${app}\n${styles}`;
const failedRecordsStayBlocked =
/message\.status === "failed" \? "blocked" : "source"/u.test(app) ||
/\["failed",\s*"timeout",\s*"canceled",\s*"error"\]\.includes\(message\.status\) \? "blocked" : "source"/u.test(app);
return (
/id=["']records-list["']/u.test(html) &&
/function\s+renderRecords\s*\(/u.test(app) &&
@@ -2219,7 +2222,7 @@ function trustedRecordGroups({ html, app, styles }) {
/gateSummary\.auditEvents\.slice\(0,\s*4\)\.map/u.test(app) &&
/gateSummary\.evidenceRecords\.map/u.test(app) &&
/safeFailureReason\(message\.error\.message\)/u.test(app) &&
/message\.status === "failed" \? "blocked" : "source"/u.test(app) &&
failedRecordsStayBlocked &&
!/message\.status === "completed"\s*\?\s*"dev-live"/u.test(app)
);
}
@@ -2326,7 +2329,7 @@ function hasStableRouteControls({ html, styles }) {
/\.(?:status-dot|state-tag|badge)[^{]*\{[^}]*max-width:\s*100%;[^}]*line-height:\s*1\.25;[^}]*white-space:\s*normal;[^}]*overflow-wrap:\s*anywhere;/su.test(styles) &&
/\.probe-card\s*\{[^}]*min-width:\s*0;/su.test(styles) &&
/\.probe-card strong\s*\{[^}]*line-height:\s*1\.2;[^}]*overflow-wrap:\s*anywhere;/su.test(styles) &&
/@media\s*\(max-width:\s*860px\)[\s\S]*?\.message-trace,\s*\n\s*\.message-m3-evidence\s*\{[\s\S]*?grid-column:\s*1;/u.test(styles)
/@media\s*\(max-width:\s*860px\)[\s\S]*?\.message-trace,\s*\n\s*\.message-m3-evidence(?:,\s*\n\s*\.message-actions)?\s*\{[\s\S]*?grid-column:\s*1;/u.test(styles)
);
}
@@ -2569,7 +2572,10 @@ function hasCodeAgentStatusSummaryContract({ html, app, styles, codeAgentStatus
}
function hasCodeAgentConversationUxStates({ app, styles }) {
const submitBody = functionBody(app, "initCommandBar");
const submitBody = `${functionBody(app, "initCommandBar")}\n${functionBody(app, "submitAgentMessage")}`;
const statusToneContract =
/status === "completed" \? "dev-live" : status === "failed" \|\| status === "blocked" \? "blocked" : status === "running" \? "pending" : "source"/u.test(app) ||
/status === "completed" \? "dev-live" : \["failed",\s*"blocked",\s*"timeout",\s*"canceled",\s*"error"\]\.includes\(status\) \? "blocked" : status === "running" \? "pending" : "source"/u.test(app);
return (
/function\s+classifyCodeAgentCompletion\s*\(/u.test(app) &&
/function\s+isSourceFixtureChatResult\s*\(/u.test(app) &&
@@ -2607,7 +2613,7 @@ function hasCodeAgentConversationUxStates({ app, styles }) {
!/message-attribution\s*\{/u.test(styles) &&
!/message-evidence\s*\{/u.test(styles) &&
/width:\s*min\(100%,\s*780px\)/u.test(styles) &&
/status === "completed" \? "dev-live" : status === "failed" \|\| status === "blocked" \? "blocked" : status === "running" \? "pending" : "source"/u.test(app) &&
statusToneContract &&
!/sourceKind:\s*"SOURCE"[\s\S]{0,160}status:\s*"completed"/u.test(app)
);
}
@@ -2667,7 +2673,7 @@ function m3RenderedWorkbenchNotM5Fixture(app) {
}
function functionBody(source, functionName) {
const match = source.match(new RegExp(`function\\s+${escapeRegExp(functionName)}\\s*\\([^)]*\\)\\s*\\{`, "u"));
const match = source.match(new RegExp(`(?:async\\s+)?function\\s+${escapeRegExp(functionName)}\\s*\\([^)]*\\)\\s*\\{`, "u"));
if (!match) return "";
let depth = 0;
for (let index = match.index + match[0].length - 1; index < source.length; index += 1) {
+1
View File
@@ -334,6 +334,7 @@ export function checkFrontendNoDirectRuntimeCalls({ appSource, htmlSource = "",
"/v1/diagnostics/gate",
"/v1/live-builds",
"/v1/agent/chat",
"/v1/agent/chat/cancel",
"/v1/m3/io",
"/v1/m3/status",
"/json-rpc"