feat: harden code queue runtime UX
- add queue merge controls and no-cache overview loading\n- improve runtime probes, judge retries, and task trace rendering\n- extend CLI/E2E/docs coverage for code queue and user services
This commit is contained in:
@@ -561,6 +561,42 @@ function requireQueueId(args: string[], command: string): string {
|
||||
return raw.trim();
|
||||
}
|
||||
|
||||
function optionValue(args: string[], names: string[]): string | undefined {
|
||||
for (const name of names) {
|
||||
const index = args.indexOf(name);
|
||||
if (index === -1) continue;
|
||||
const raw = args[index + 1];
|
||||
if (raw === undefined || raw.trim().length === 0) throw new Error(`${name} requires a non-empty value`);
|
||||
return raw.trim();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function positionalArgs(args: string[]): string[] {
|
||||
const positions: string[] = [];
|
||||
for (let index = 0; index < args.length; index += 1) {
|
||||
const value = args[index] ?? "";
|
||||
if (value.startsWith("--")) {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
positions.push(value);
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
function requireMergeSourceQueueId(args: string[], command: string): string {
|
||||
const raw = optionValue(args, ["--source", "--from", "--queue"]) ?? positionalArgs(args)[0];
|
||||
if (raw === undefined || raw.trim().length === 0) throw new Error(`${command} requires source queue id, for example: codex queue merge old --into default`);
|
||||
return raw.trim();
|
||||
}
|
||||
|
||||
function requireMergeTargetQueueId(args: string[], command: string): string {
|
||||
const raw = optionValue(args, ["--into", "--target", "--to"]) ?? positionalArgs(args)[1];
|
||||
if (raw === undefined || raw.trim().length === 0) throw new Error(`${command} requires target queue id, for example: codex queue merge old --into default`);
|
||||
return raw.trim();
|
||||
}
|
||||
|
||||
function codeQueues(): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch("/api/microservices/code-queue/proxy/api/queues"));
|
||||
}
|
||||
@@ -569,6 +605,10 @@ function codexCreateQueue(queueId: string): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch("/api/microservices/code-queue/proxy/api/queues", { method: "POST", body: { queueId } }));
|
||||
}
|
||||
|
||||
function codexMergeQueue(sourceQueueId: string, targetQueueId: string): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch(`/api/microservices/code-queue/proxy/api/queues/${encodeURIComponent(targetQueueId)}/merge`, { method: "POST", body: { sourceQueueId } }));
|
||||
}
|
||||
|
||||
function codexMoveTask(taskId: string, queueId: string): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/move`, { method: "POST", body: { queueId } }));
|
||||
}
|
||||
@@ -588,10 +628,14 @@ export async function runCodeQueueCommand(_config: UniDeskConfig, args: string[]
|
||||
const sub = taskIdArg ?? "list";
|
||||
if (sub === "list") return codeQueues();
|
||||
if (sub === "create") return codexCreateQueue(requireQueueId(args.slice(2), "queue create"));
|
||||
if (sub === "merge") {
|
||||
const mergeArgs = args.slice(2);
|
||||
return codexMergeQueue(requireMergeSourceQueueId(mergeArgs, "queue merge"), requireMergeTargetQueueId(mergeArgs, "queue merge"));
|
||||
}
|
||||
}
|
||||
if (action === "move") {
|
||||
const taskId = requireTaskId(taskIdArg, "codex move");
|
||||
return codexMoveTask(taskId, requireQueueId(args.slice(2), "codex move"));
|
||||
}
|
||||
throw new Error("codex command must be one of: task, summary, show, output, queues, queue list, queue create, move");
|
||||
throw new Error("codex command must be one of: task, summary, show, output, queues, queue list, queue create, queue merge, move");
|
||||
}
|
||||
|
||||
+175
-1
@@ -119,6 +119,7 @@ const FRONTEND_CHECK_NAMES = [
|
||||
"frontend:todo-note-integrated-visible",
|
||||
"frontend:findjob-integrated-visible",
|
||||
"frontend:code-queue-integrated-visible",
|
||||
"frontend:code-queue-enqueue-await-smoke",
|
||||
"frontend:code-queue-summary-mobile-wrap",
|
||||
"frontend:code-queue-initial-prompt-full-expand",
|
||||
"frontend:code-queue-trace-full-load",
|
||||
@@ -540,6 +541,151 @@ function providerGatewayPackageVersion(): string {
|
||||
}
|
||||
}
|
||||
|
||||
function isCodeQueueTaskEnqueueRequest(url: string, method: string): boolean {
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
return method === "POST" && parsed.pathname === "/api/code-queue-direct/api/tasks";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function runCodeQueueEnqueueAwaitSmoke(page: Page): Promise<any> {
|
||||
const marker = `e2e-await-enqueue-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`;
|
||||
const prompt = [
|
||||
`Code Queue await enqueue smoke ${marker}`,
|
||||
"",
|
||||
"This task is created by the frontend E2E smoke test to verify that the enqueue submit path awaits the backend response before unlocking the form.",
|
||||
].join("\n");
|
||||
let delayedPostCount = 0;
|
||||
const routePattern = "**/api/code-queue-direct/api/tasks**";
|
||||
const routeHandler = async (route: any, request: any): Promise<void> => {
|
||||
if (!isCodeQueueTaskEnqueueRequest(request.url(), request.method())) {
|
||||
await route.continue();
|
||||
return;
|
||||
}
|
||||
delayedPostCount += 1;
|
||||
await new Promise((resolve) => setTimeout(resolve, 900));
|
||||
await route.continue();
|
||||
};
|
||||
|
||||
await page.route(routePattern, routeHandler);
|
||||
try {
|
||||
await page.getByTestId("code-queue-filter-select").selectOption("__all__").catch(() => undefined);
|
||||
await page.getByTestId("code-queue-id-select").selectOption("default").catch(() => undefined);
|
||||
await page.getByTestId("codex-max-attempts-input").fill("1");
|
||||
await page.getByTestId("codex-repeat-count-input").fill("1");
|
||||
await page.locator('[data-testid="code-queue-task-form"] textarea').fill(prompt);
|
||||
await page.waitForFunction(() => {
|
||||
const button = document.querySelector('[data-testid="codex-enqueue-button"]') as HTMLButtonElement | null;
|
||||
return button !== null && !button.disabled && (button.textContent || "").includes("入队");
|
||||
}, undefined, { timeout: 5000 });
|
||||
|
||||
const requestPromise = page.waitForRequest((request) => isCodeQueueTaskEnqueueRequest(request.url(), request.method()), { timeout: 10000 });
|
||||
const responsePromise = page.waitForResponse((response) => isCodeQueueTaskEnqueueRequest(response.url(), response.request().method()), { timeout: 30000 });
|
||||
await page.getByTestId("codex-enqueue-button").click();
|
||||
const request = await requestPromise;
|
||||
await page.waitForSelector('[data-testid="codex-submit-wait"]', { timeout: 5000 });
|
||||
const duringAwait = await page.evaluate(() => {
|
||||
const form = document.querySelector('[data-testid="code-queue-task-form"]') as HTMLElement | null;
|
||||
const wait = document.querySelector('[data-testid="codex-submit-wait"]') as HTMLElement | null;
|
||||
const button = document.querySelector('[data-testid="codex-enqueue-button"]') as HTMLButtonElement | null;
|
||||
const textarea = document.querySelector('[data-testid="code-queue-task-form"] textarea') as HTMLTextAreaElement | null;
|
||||
return {
|
||||
formBusy: form?.getAttribute("aria-busy") === "true",
|
||||
waitVisible: Boolean(wait && wait.offsetParent !== null && (wait.textContent || "").includes("正在提交")),
|
||||
buttonDisabled: Boolean(button?.disabled),
|
||||
buttonText: button?.textContent || "",
|
||||
textareaDisabled: Boolean(textarea?.disabled),
|
||||
};
|
||||
});
|
||||
const response = await responsePromise;
|
||||
const responseBody = await response.json().catch((error: unknown) => ({ parseError: error instanceof Error ? error.message : String(error) }));
|
||||
const taskId = String(responseBody?.tasks?.[0]?.id || "");
|
||||
await page.waitForFunction((id) => {
|
||||
const form = document.querySelector('[data-testid="code-queue-task-form"]') as HTMLElement | null;
|
||||
const notice = document.querySelector('[data-testid="codex-create-success"]') as HTMLElement | null;
|
||||
return form?.getAttribute("aria-busy") === "false" && (notice?.textContent || "").includes(String(id));
|
||||
}, taskId, { timeout: 30000 });
|
||||
const afterAwait = await page.evaluate((id) => {
|
||||
const form = document.querySelector('[data-testid="code-queue-task-form"]') as HTMLElement | null;
|
||||
const wait = document.querySelector('[data-testid="codex-submit-wait"]') as HTMLElement | null;
|
||||
const button = document.querySelector('[data-testid="codex-enqueue-button"]') as HTMLButtonElement | null;
|
||||
const textarea = document.querySelector('[data-testid="code-queue-task-form"] textarea') as HTMLTextAreaElement | null;
|
||||
const notice = document.querySelector('[data-testid="codex-create-success"]') as HTMLElement | null;
|
||||
const card = document.querySelector(`[data-testid="codex-task-${CSS.escape(String(id))}"]`) as HTMLElement | null;
|
||||
return {
|
||||
formBusy: form?.getAttribute("aria-busy") === "true",
|
||||
waitMissing: wait === null,
|
||||
buttonDisabled: Boolean(button?.disabled),
|
||||
textareaDisabled: Boolean(textarea?.disabled),
|
||||
textareaEmpty: (textarea?.value || "") === "",
|
||||
noticeText: notice?.textContent || "",
|
||||
cardVisible: Boolean(card && card.offsetParent !== null),
|
||||
};
|
||||
}, taskId);
|
||||
const storedTask = await page.evaluate(async (id) => {
|
||||
const response = await fetch(`/api/code-queue-direct/api/tasks/${encodeURIComponent(String(id))}?meta=1`, { credentials: "same-origin" });
|
||||
const text = await response.text();
|
||||
let body: any = null;
|
||||
try { body = text ? JSON.parse(text) : null; } catch { body = { text }; }
|
||||
return { ok: response.ok, status: response.status, body };
|
||||
}, taskId);
|
||||
const interrupt = await page.evaluate(async (id) => {
|
||||
const response = await fetch(`/api/code-queue-direct/api/tasks/${encodeURIComponent(String(id))}/interrupt`, {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: "{}",
|
||||
});
|
||||
const text = await response.text();
|
||||
let body: any = null;
|
||||
try { body = text ? JSON.parse(text) : null; } catch { body = { text }; }
|
||||
return { ok: response.ok, status: response.status, body };
|
||||
}, taskId);
|
||||
const requestBody = (() => {
|
||||
try {
|
||||
return request.postDataJSON();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
await page.getByTestId("codex-max-attempts-input").fill("99").catch(() => undefined);
|
||||
return {
|
||||
checked: true,
|
||||
marker,
|
||||
delayedPostCount,
|
||||
requestBody,
|
||||
responseStatus: response.status(),
|
||||
responseOk: response.ok(),
|
||||
responseBody: {
|
||||
ok: responseBody?.ok === true,
|
||||
taskIds: Array.isArray(responseBody?.tasks) ? responseBody.tasks.map((task: any) => String(task?.id || "")).filter(Boolean) : [],
|
||||
},
|
||||
taskId,
|
||||
duringAwait,
|
||||
afterAwait,
|
||||
storedTask: {
|
||||
ok: storedTask.ok,
|
||||
status: storedTask.status,
|
||||
id: String(storedTask.body?.task?.id || ""),
|
||||
queueId: String(storedTask.body?.task?.queueId || ""),
|
||||
promptIncludesMarker: String(storedTask.body?.task?.prompt || "").includes(marker),
|
||||
displayPromptIncludesMarker: String(storedTask.body?.task?.displayPrompt || "").includes(marker),
|
||||
taskStatus: String(storedTask.body?.task?.status || ""),
|
||||
},
|
||||
interrupt: {
|
||||
ok: interrupt.ok,
|
||||
status: interrupt.status,
|
||||
taskStatus: String(interrupt.body?.task?.status || ""),
|
||||
error: typeof interrupt.body?.error === "string" ? interrupt.body.error : "",
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
await page.unroute(routePattern, routeHandler).catch(() => undefined);
|
||||
}
|
||||
}
|
||||
|
||||
function runPsql(config: UniDeskConfig, sql: string): { ok: boolean; stdout: string; stderr: string; exitCode: number | null } {
|
||||
const result = runCommand([
|
||||
"docker",
|
||||
@@ -1082,6 +1228,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
const needFindJob = wants("frontend:findjob-integrated-visible");
|
||||
const needCodeQueue = wantsAny([
|
||||
"frontend:code-queue-integrated-visible",
|
||||
"frontend:code-queue-enqueue-await-smoke",
|
||||
"frontend:code-queue-summary-mobile-wrap",
|
||||
"frontend:code-queue-initial-prompt-full-expand",
|
||||
"frontend:code-queue-trace-full-load",
|
||||
@@ -1175,6 +1322,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
let codeQueueSummaryMobileMetrics: any = { checked: false, summaryCount: 0, ok: false };
|
||||
let codeQueuePromptDefaultEmpty = false;
|
||||
let codeQueueSubmitGuard: any = { batchRowVisible: false, disabledBeforeConfirm: false, enabledAfterConfirm: false, waitElementMissingBeforeSubmit: false };
|
||||
let codeQueueEnqueueAwaitSmoke: any = { checked: false };
|
||||
let codeQueueScrollbarMetrics: any = { transcriptThin: false, toolHorizontalHidden: true };
|
||||
let codexInitialPromptFullMetrics: any = { candidateFound: false };
|
||||
let codexTraceFullMetrics: any = { candidateFound: false };
|
||||
@@ -1478,6 +1626,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
codeQueueSubmitQueueControl = await page.evaluate(() => {
|
||||
const select = document.querySelector('[data-testid="code-queue-id-select"]') as HTMLSelectElement | null;
|
||||
const button = document.querySelector('[data-testid="codex-create-queue-button"]') as HTMLButtonElement | null;
|
||||
const mergeButton = document.querySelector('[data-testid="codex-merge-queue-button"]') as HTMLButtonElement | null;
|
||||
const prompt = document.querySelector('[data-testid="code-queue-task-form"] textarea') as HTMLTextAreaElement | null;
|
||||
const provider = document.querySelector('[data-testid="codex-provider-select"]') as HTMLSelectElement | null;
|
||||
const cwd = document.querySelector('[data-testid="codex-cwd-input"]') as HTMLInputElement | null;
|
||||
@@ -1488,6 +1637,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
tagName: select?.tagName.toLowerCase() || "",
|
||||
optionCount: select?.options.length ?? 0,
|
||||
createButtonVisible: Boolean(button && button.offsetParent !== null),
|
||||
mergeButtonVisible: Boolean(mergeButton && mergeButton.offsetParent !== null),
|
||||
oldInputMissing: document.querySelector('[data-testid="code-queue-id-input"]') === null,
|
||||
promptDefaultEmpty: (prompt?.value || "") === "",
|
||||
providerValue: provider?.value || "",
|
||||
@@ -1530,6 +1680,9 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
})),
|
||||
};
|
||||
await page.locator('[data-testid="codex-clear-input-button"]').click();
|
||||
if (wants("frontend:code-queue-enqueue-await-smoke")) {
|
||||
codeQueueEnqueueAwaitSmoke = await runCodeQueueEnqueueAwaitSmoke(page);
|
||||
}
|
||||
codeQueueOptions = await page.locator('[data-testid="code-queue-filter-select"] option').evaluateAll((options) => options.map((option) => (option as HTMLOptionElement).textContent || ""));
|
||||
codeQueueSwitchMetrics = await page.locator('[data-testid="code-queue-filter-select"] option').evaluateAll((options) => ({
|
||||
optionCount: options.length,
|
||||
@@ -1936,6 +2089,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
codeQueueSubmitQueueControl = await page.evaluate(() => {
|
||||
const select = document.querySelector('[data-testid="code-queue-id-select"]') as HTMLSelectElement | null;
|
||||
const button = document.querySelector('[data-testid="codex-create-queue-button"]') as HTMLButtonElement | null;
|
||||
const mergeButton = document.querySelector('[data-testid="codex-merge-queue-button"]') as HTMLButtonElement | null;
|
||||
const prompt = document.querySelector('[data-testid="code-queue-task-form"] textarea') as HTMLTextAreaElement | null;
|
||||
const provider = document.querySelector('[data-testid="codex-provider-select"]') as HTMLSelectElement | null;
|
||||
const cwd = document.querySelector('[data-testid="codex-cwd-input"]') as HTMLInputElement | null;
|
||||
@@ -1946,6 +2100,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
tagName: select?.tagName.toLowerCase() || "",
|
||||
optionCount: select?.options.length ?? 0,
|
||||
createButtonVisible: Boolean(button && button.offsetParent !== null),
|
||||
mergeButtonVisible: Boolean(mergeButton && mergeButton.offsetParent !== null),
|
||||
oldInputMissing: document.querySelector('[data-testid="code-queue-id-input"]') === null,
|
||||
promptDefaultEmpty: (prompt?.value || "") === "",
|
||||
providerValue: provider?.value || "",
|
||||
@@ -2428,7 +2583,26 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
addSelectedCheck(checks, options, "frontend:microservice-catalog-visible", microserviceCatalogTextLower.includes("findjob") && microserviceCatalogTextLower.includes("pipeline") && microserviceCatalogTextLower.includes("todo note") && microserviceCatalogTextLower.includes("met nonlinear") && microserviceCatalogTextLower.includes("claudeqq") && microserviceCatalogTextLower.includes("code queue") && microserviceCatalogText.includes("D601") && microserviceCatalogText.includes(config.providerGateway.id) && microserviceCatalogTextLower.includes("private") && microserviceCatalogText.includes("https://gitee.com/Lyon1998/findjob") && microserviceCatalogText.includes("https://github.com/pikasTech/pipeline") && microserviceCatalogText.includes("https://github.com/pikasTech/met_nonlinear") && microserviceCatalogText.includes("https://gitee.com/lyon1998/agent_skills") && microserviceCatalogText.includes("https://gitee.com/Lyon1998/todo_note") && microserviceCatalogText.includes("https://github.com/pikasTech/unidesk"), { microserviceCatalogPreview: microserviceCatalogText.slice(0, 2000) });
|
||||
addSelectedCheck(checks, options, "frontend:todo-note-integrated-visible", todoNoteTextLower.includes("todo note 工作台") && todoNoteText.includes("CONSTAR") && todoNoteText.includes("大论文") && todoNoteText.includes("UI E2E smoke task") && todoNoteText.includes("撤销") && todoNoteText.includes("重做") && todoNoteText.includes("全部展开") && todoNoteText.includes("仅 UniDesk frontend 代理访问"), { todoNoteTextPreview: todoNoteText.slice(0, 1400) });
|
||||
addSelectedCheck(checks, options, "frontend:findjob-integrated-visible", findjobTextLower.includes("findjob 工作台".toLowerCase()) && findjobText.includes("岗位总量") && findjobText.includes("D601") && findjobText.includes("近期岗位") && findjobText.includes("仅 UniDesk frontend 代理访问") && /岗位总量\s+\d+/.test(findjobText) && /health\s+ok/i.test(findjobText) && /[1-9]\d*\/[1-9]\d*\s+preview/i.test(findjobText), { findjobTextPreview: findjobText.slice(0, 1200) });
|
||||
addSelectedCheck(checks, options, "frontend:code-queue-integrated-visible", codeQueueTextLower.includes("code queue") && codeQueueText.includes("gpt-5.4-mini") && codeQueueText.includes("gpt-5.4") && codeQueueText.includes("gpt-5.5") && codeQueueText.includes("提交任务") && codeQueueText.includes("执行 Provider") && codeQueueText.includes("入队份数") && codeQueueText.includes("追加 prompt") && codeQueueText.includes("打断") && codeQueueTextLower.includes("查看 queue") && codeQueueText.includes("创建 queue") && codeQueueOptions.some((text) => text.includes("All queues")) && codeQueueTracePlacement.firstChildIsTrace === true && codeQueueTracePlacement.noPageTopStatus === true && codeQueueTracePlacement.filterInsideTracePanel === true && codeQueueTracePlacement.taskSearchVisible === true && codeQueueTracePlacement.traceStatusVisible === true && codeQueueTracePlacement.markAllReadVisible === true && codeQueueGlobalStatus.activeMicroserviceVisible === true && codeQueueSidebarUpdateMetrics.hasRecentUpdateLabel === true && codeQueueHtmlGuard.rootAttrMissing === true && codeQueueHtmlGuard.sourceAttrMissing === true && codeQueueHtmlGuard.sourceNoBasePrompt === true && codeQueueSubmitQueueControl.tagName === "select" && codeQueueSubmitQueueControl.createButtonVisible === true && codeQueueSubmitQueueControl.oldInputMissing === true && codeQueueSubmitQueueControl.providerValue === "main-server" && codeQueueSubmitQueueControl.cwdValue === "/root/unidesk" && Array.isArray(codeQueueSubmitQueueControl.providerOptions) && codeQueueSubmitQueueControl.providerOptions.some((item: any) => item.value === "D601" && String(item.text || "").includes("/home/ubuntu")) && codeQueueSubmitQueueControl.maxAttemptsMax === "99" && codeQueueSubmitQueueControl.maxAttemptsValue === "99" && codeQueueSubmitQueueControl.moveQueueVisible === true && codeQueuePromptDefaultEmpty === true && codeQueueSubmitGuard.batchRowVisible === true && codeQueueSubmitGuard.checkboxVisible === true && codeQueueSubmitGuard.disabledBeforeConfirm === true && codeQueueSubmitGuard.enabledAfterConfirm === true && codeQueueSubmitGuard.waitElementMissingBeforeSubmit === true && codeQueueScrollbarMetrics.transcriptThin === true && codeQueueScrollbarMetrics.toolHorizontalHidden === true && (codeQueueSwitchMetrics.optionCount <= 1 || codeQueueSwitchMetrics.switched === true) && codeQueueTextLower.includes("attempts") && codeQueueText.includes("仅 UniDesk frontend 代理访问") && (codeQueueTaskCount === 0 || codeQueueOutputText.includes("Submitted prompt")), { codeQueueTaskCount, codeQueueOptions, codeQueueSwitchMetrics, codeQueueSubmitQueueControl, codeQueueSubmitGuard, codeQueueScrollbarMetrics, codeQueuePromptDefaultEmpty, codeQueueTracePlacement, codeQueueGlobalStatus, codeQueueSidebarUpdateMetrics, codeQueueHtmlGuard, codeQueueOutputPreview: codeQueueOutputText.slice(0, 900), codeQueueTextPreview: codeQueueText.slice(0, 1400) });
|
||||
addSelectedCheck(checks, options, "frontend:code-queue-integrated-visible", codeQueueTextLower.includes("code queue") && codeQueueText.includes("gpt-5.4-mini") && codeQueueText.includes("gpt-5.4") && codeQueueText.includes("gpt-5.5") && codeQueueText.includes("提交任务") && codeQueueText.includes("执行 Provider") && codeQueueText.includes("入队份数") && codeQueueText.includes("追加 prompt") && codeQueueText.includes("打断") && codeQueueTextLower.includes("查看 queue") && codeQueueText.includes("创建 queue") && codeQueueText.includes("合并 queue") && codeQueueOptions.some((text) => text.includes("All queues")) && codeQueueTracePlacement.firstChildIsTrace === true && codeQueueTracePlacement.noPageTopStatus === true && codeQueueTracePlacement.filterInsideTracePanel === true && codeQueueTracePlacement.taskSearchVisible === true && codeQueueTracePlacement.traceStatusVisible === true && codeQueueTracePlacement.markAllReadVisible === true && codeQueueGlobalStatus.activeMicroserviceVisible === true && codeQueueSidebarUpdateMetrics.hasRecentUpdateLabel === true && codeQueueHtmlGuard.rootAttrMissing === true && codeQueueHtmlGuard.sourceAttrMissing === true && codeQueueHtmlGuard.sourceNoBasePrompt === true && codeQueueSubmitQueueControl.tagName === "select" && codeQueueSubmitQueueControl.createButtonVisible === true && codeQueueSubmitQueueControl.mergeButtonVisible === true && codeQueueSubmitQueueControl.oldInputMissing === true && codeQueueSubmitQueueControl.providerValue === "main-server" && codeQueueSubmitQueueControl.cwdValue === "/root/unidesk" && Array.isArray(codeQueueSubmitQueueControl.providerOptions) && codeQueueSubmitQueueControl.providerOptions.some((item: any) => item.value === "D601" && String(item.text || "").includes("/home/ubuntu")) && codeQueueSubmitQueueControl.maxAttemptsMax === "99" && codeQueueSubmitQueueControl.maxAttemptsValue === "99" && codeQueueSubmitQueueControl.moveQueueVisible === true && codeQueuePromptDefaultEmpty === true && codeQueueSubmitGuard.batchRowVisible === true && codeQueueSubmitGuard.checkboxVisible === true && codeQueueSubmitGuard.disabledBeforeConfirm === true && codeQueueSubmitGuard.enabledAfterConfirm === true && codeQueueSubmitGuard.waitElementMissingBeforeSubmit === true && codeQueueScrollbarMetrics.transcriptThin === true && codeQueueScrollbarMetrics.toolHorizontalHidden === true && (codeQueueSwitchMetrics.optionCount <= 1 || codeQueueSwitchMetrics.switched === true) && codeQueueTextLower.includes("attempts") && codeQueueText.includes("仅 UniDesk frontend 代理访问") && (codeQueueTaskCount === 0 || codeQueueOutputText.includes("Submitted prompt")), { codeQueueTaskCount, codeQueueOptions, codeQueueSwitchMetrics, codeQueueSubmitQueueControl, codeQueueSubmitGuard, codeQueueScrollbarMetrics, codeQueuePromptDefaultEmpty, codeQueueTracePlacement, codeQueueGlobalStatus, codeQueueSidebarUpdateMetrics, codeQueueHtmlGuard, codeQueueOutputPreview: codeQueueOutputText.slice(0, 900), codeQueueTextPreview: codeQueueText.slice(0, 1400) });
|
||||
addSelectedCheck(checks, options, "frontend:code-queue-enqueue-await-smoke",
|
||||
codeQueueEnqueueAwaitSmoke.checked === true
|
||||
&& codeQueueEnqueueAwaitSmoke.delayedPostCount === 1
|
||||
&& codeQueueEnqueueAwaitSmoke.responseOk === true
|
||||
&& codeQueueEnqueueAwaitSmoke.responseStatus === 202
|
||||
&& /^codex_\d+_[A-Za-z0-9_-]+$/u.test(String(codeQueueEnqueueAwaitSmoke.taskId || ""))
|
||||
&& codeQueueEnqueueAwaitSmoke.duringAwait?.formBusy === true
|
||||
&& codeQueueEnqueueAwaitSmoke.duringAwait?.waitVisible === true
|
||||
&& codeQueueEnqueueAwaitSmoke.duringAwait?.buttonDisabled === true
|
||||
&& codeQueueEnqueueAwaitSmoke.duringAwait?.textareaDisabled === true
|
||||
&& codeQueueEnqueueAwaitSmoke.afterAwait?.formBusy === false
|
||||
&& codeQueueEnqueueAwaitSmoke.afterAwait?.waitMissing === true
|
||||
&& codeQueueEnqueueAwaitSmoke.afterAwait?.textareaEmpty === true
|
||||
&& codeQueueEnqueueAwaitSmoke.storedTask?.ok === true
|
||||
&& codeQueueEnqueueAwaitSmoke.storedTask?.id === codeQueueEnqueueAwaitSmoke.taskId
|
||||
&& codeQueueEnqueueAwaitSmoke.storedTask?.queueId === "default"
|
||||
&& codeQueueEnqueueAwaitSmoke.storedTask?.promptIncludesMarker === true
|
||||
&& (codeQueueEnqueueAwaitSmoke.interrupt?.ok === true || codeQueueEnqueueAwaitSmoke.interrupt?.status === 409),
|
||||
{ codeQueueEnqueueAwaitSmoke });
|
||||
addSelectedCheck(checks, options, "frontend:code-queue-summary-mobile-wrap", codeQueueSummaryMobileMetrics.checked === true && (codeQueueSummaryMobileMetrics.summaryCount === 0 || codeQueueSummaryMobileMetrics.ok === true), { codeQueueSummaryMobileMetrics });
|
||||
addSelectedCheck(checks, options, "frontend:code-queue-error-red-markers", codeQueueErrorHighlightMetrics.checked === true && codeQueueErrorHighlightMetrics.candidateFound === true && codeQueueErrorHighlightMetrics.ok === true, { codeQueueErrorHighlightMetrics });
|
||||
addSelectedCheck(checks, options, "frontend:code-queue-initial-prompt-full-expand",
|
||||
|
||||
Reference in New Issue
Block a user