fix: tighten sentinel quick verify waits
This commit is contained in:
@@ -343,7 +343,13 @@ async function processCommand(command) {
|
||||
case "preflight": return preflightSummary();
|
||||
case "goto": return withObserverSync(await gotoTarget(command.path || command.url || targetPath), "goto");
|
||||
case "newSession": return withObserverSync(await createSessionFromUi(), "newSession");
|
||||
case "sendPrompt": return withObserverSync(await sendPrompt(String(command.text || "")), "sendPrompt");
|
||||
case "sendPrompt": return withObserverSync(await sendPrompt(String(command.text || ""), {
|
||||
expectedAction: "turn",
|
||||
responsePath: "/v1/agent/chat",
|
||||
alternateResponsePaths: ["/v1/agent/chat/steer"],
|
||||
noActiveReason: "send-no-turn-composer",
|
||||
throwOnActionMismatch: true,
|
||||
}), "sendPrompt");
|
||||
case "steer": return withObserverSync(await sendPrompt(String(command.text || ""), { expectedAction: "steer", responsePath: "/v1/agent/chat/steer", noActiveReason: "steer-no-active-turn" }), "steer");
|
||||
case "cancel": return withObserverSync(await cancelRunningTurn(), "cancel");
|
||||
case "selectProvider": return withObserverSync(await selectProvider(String(command.provider || command.value || command.text || "")), "selectProvider");
|
||||
@@ -1168,7 +1174,7 @@ async function sendPrompt(text, options = {}) {
|
||||
if (composer.action !== options.expectedAction || composer.disabled === true) {
|
||||
await clearComposerEditor(editor).catch(() => {});
|
||||
const sideEffect = await waitForPromptSideEffect(beforeEvidence, 200).catch(() => promptSideEffectSnapshot());
|
||||
return {
|
||||
const blocked = {
|
||||
beforeUrl,
|
||||
afterUrl: currentPageUrl(),
|
||||
textHash: sha256Text(text),
|
||||
@@ -1191,13 +1197,20 @@ async function sendPrompt(text, options = {}) {
|
||||
pageId,
|
||||
valuesRedacted: true
|
||||
};
|
||||
if (options.throwOnActionMismatch === true) {
|
||||
const error = new Error("sendPrompt composer action mismatch: expected " + options.expectedAction + " actual " + (composer.action || "null"));
|
||||
error.details = blocked;
|
||||
throw error;
|
||||
}
|
||||
return blocked;
|
||||
}
|
||||
}
|
||||
const acceptedResponsePaths = [responsePath, ...(Array.isArray(options.alternateResponsePaths) ? options.alternateResponsePaths : [])];
|
||||
const chatResponsePromise = page.waitForResponse((response) => {
|
||||
const request = response.request();
|
||||
if (request.method().toUpperCase() !== "POST") return false;
|
||||
try {
|
||||
return new URL(response.url()).pathname === responsePath;
|
||||
return acceptedResponsePaths.includes(new URL(response.url()).pathname);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
@@ -1230,8 +1243,14 @@ async function sendPrompt(text, options = {}) {
|
||||
throw error;
|
||||
}
|
||||
const chatStatus = chatResponse.status();
|
||||
let chatUrlPath = responsePath;
|
||||
try {
|
||||
chatUrlPath = new URL(chatResponse.url()).pathname;
|
||||
} catch {
|
||||
chatUrlPath = responsePath;
|
||||
}
|
||||
if (chatStatus < 200 || chatStatus >= 300) {
|
||||
throw new Error("sendPrompt observed POST " + responsePath + " HTTP " + chatStatus + " " + chatResponse.statusText());
|
||||
throw new Error("sendPrompt observed POST " + chatUrlPath + " HTTP " + chatStatus + " " + chatResponse.statusText());
|
||||
}
|
||||
let chatPayload = null;
|
||||
let chatPayloadError = null;
|
||||
@@ -1240,12 +1259,6 @@ async function sendPrompt(text, options = {}) {
|
||||
} catch (error) {
|
||||
chatPayloadError = errorSummary(error);
|
||||
}
|
||||
let chatUrlPath = responsePath;
|
||||
try {
|
||||
chatUrlPath = new URL(chatResponse.url()).pathname;
|
||||
} catch {
|
||||
chatUrlPath = responsePath;
|
||||
}
|
||||
const payloadText = chatPayload ? JSON.stringify(chatPayload) : "";
|
||||
const traceId = payloadText.match(/\btrc_[A-Za-z0-9_-]+\b/u)?.[0] || null;
|
||||
const otelTraceId = typeof chatPayload?.otelTrace?.traceId === "string" && /^[0-9a-f]{32}$/u.test(chatPayload.otelTrace.traceId)
|
||||
@@ -2496,6 +2509,9 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
const routeSessionMatch = url.match(/\/workbench\/sessions\/([^/?#]+)/u);
|
||||
const activeSession = document.querySelector('[data-active="true"][data-session-id], [aria-selected="true"][data-session-id], .active[data-session-id]');
|
||||
const activeSessionId = activeSession ? activeSession.getAttribute("data-session-id") : null;
|
||||
const commandInput = document.querySelector("#command-input");
|
||||
const commandSubmit = document.querySelector('#command-send, #command-submit, [data-testid="command-submit"], [data-testid="composer-submit"], [data-testid="send-command"]');
|
||||
const composerWarning = document.querySelector(".composer-warning");
|
||||
const messageSelector = 'article.message-card, .message-card[data-message-id], article[data-message-id]';
|
||||
const stableTraceSelector = 'li.trace-render-row[data-row-id], li.trace-render-row[data-testid="trace-render-row"], [data-testid="trace-render-row"][data-row-id]';
|
||||
const fallbackTraceSelector = '[data-testid*="trace" i], [class*="trace" i], [data-trace-id], [data-testid*="event" i]';
|
||||
@@ -2573,6 +2589,19 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
sessionRail,
|
||||
diagnostics,
|
||||
turns,
|
||||
composer: {
|
||||
inputPresent: visible(commandInput),
|
||||
inputDisabled: Boolean(commandInput?.disabled) || commandInput?.getAttribute("aria-disabled") === "true",
|
||||
warningPresent: visible(composerWarning),
|
||||
warningText: trim(composerWarning?.textContent || "", 160),
|
||||
submitPresent: visible(commandSubmit),
|
||||
submitDisabled: Boolean(commandSubmit?.disabled) || commandSubmit?.getAttribute("aria-disabled") === "true",
|
||||
submitAction: commandSubmit?.getAttribute("data-action") || null,
|
||||
submitText: trim(commandSubmit?.textContent || "", 80),
|
||||
submitTestId: commandSubmit?.getAttribute("data-testid") || null,
|
||||
activeStatus: activeSession?.getAttribute("data-status") || null,
|
||||
valuesRedacted: true
|
||||
},
|
||||
projectManagement: collectProjectManagement(),
|
||||
pageProvenance: {
|
||||
url: location.href,
|
||||
|
||||
Reference in New Issue
Block a user