Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 90 additions & 26 deletions apps/decodex/src/orchestrator/operator_dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,30 @@ <h2 id="recent-title">Run History</h2>
.replace(/\b\w/g, (character) => character.toUpperCase());
}

function sentenceToken(value) {
return humanizeToken(value).toLowerCase();
}

function normalizedDisplayText(value) {
return String(value || "")
.toLowerCase()
.replace(/[^a-z0-9]+/g, " ")
.trim();
}

function displayTextRepeats(left, right) {
const normalizedLeft = normalizedDisplayText(left);
const normalizedRight = normalizedDisplayText(right);

return Boolean(
normalizedLeft &&
normalizedRight &&
(normalizedLeft === normalizedRight ||
normalizedLeft.includes(normalizedRight) ||
normalizedRight.includes(normalizedLeft)),
);
}

function compactStateToken(value) {
if (!value) {
return "none";
Expand Down Expand Up @@ -4022,6 +4046,14 @@ <h2 id="recent-title">Run History</h2>
return humanizeToken(lane.classification);
}

function postReviewBlockerStatus(lane, blockerScope) {
if (lane.review_decision && blockerScope === "Review") {
return `review ${compactStateToken(lane.review_decision)}`;
}

return "needs attention";
}

function toneForQueuedCandidate(candidate) {
if (candidate.display_classification === "owned_active") {
return "tone-run";
Expand Down Expand Up @@ -4129,28 +4161,28 @@ <h2 id="recent-title">Run History</h2>

function queuedCandidateReasonText(candidate) {
if (candidate.display_classification === "owned_active") {
return "Running Lane Claim";
return "running lane claim";
}
if (
candidate.attention?.worktree_has_tracked_changes &&
candidate.attention?.retry_budget_attempt_count != null
) {
return "Partial Patch Retained";
return "partial patch retained";
}
if (candidate.attention?.thread_status === "systemError") {
return "App-Server Error";
return "app-server error";
}
if (candidate.attention?.last_event_type === "item/tool/call") {
return "Tool Call Stalled";
return "tool call stalled";
}
if (candidate.attention?.attention_error_class) {
return humanizeToken(candidate.attention.attention_error_class);
return sentenceToken(candidate.attention.attention_error_class);
}
if (candidate.reason === "issue_needs_attention") {
return "Needs Attention";
return "needs attention";
}
if (candidate.attention?.retry_budget_attempt_count != null) {
return "Auto Retry Paused";
return "auto retry paused";
}
if (candidate.reason === "global_concurrency_exhausted") {
return "";
Expand All @@ -4159,7 +4191,32 @@ <h2 id="recent-title">Run History</h2>
return "";
}

return humanizeToken(candidate.reason);
return sentenceToken(candidate.reason);
}

function queuedCandidateInlineReason(candidate) {
const reason = queuedCandidateReasonText(candidate);
if (!reason) {
return "";
}

if (
candidate.attention?.attention_error_class &&
displayTextRepeats(reason, sentenceToken(candidate.attention.attention_error_class))
) {
return "";
}
if (
candidate.attention?.worktree_has_tracked_changes &&
displayTextRepeats(reason, "patch retained")
) {
return "";
}
if (displayTextRepeats(candidate.attention?.summary, reason)) {
return "";
}

return reason;
}

function queuedCandidateNeedsAttention(candidate) {
Expand Down Expand Up @@ -4573,7 +4630,7 @@ <h2 id="recent-title">Run History</h2>
facts.push(["Auto retry", autoRetryBlockedReasonText(attention.auto_retry_blocked_reason)]);
}
if (attention.attention_error_class) {
facts.push(["Cause", humanizeToken(attention.attention_error_class)]);
facts.push(["Cause", sentenceToken(attention.attention_error_class)]);
}
if (attention.worktree_has_tracked_changes) {
facts.push(["Patch", "retained"]);
Expand Down Expand Up @@ -4609,7 +4666,7 @@ <h2 id="recent-title">Run History</h2>
return "needs-attention label set";
}

return `blocked by ${humanizeToken(reason)}`;
return `blocked by ${sentenceToken(reason)}`;
}

function statusLabel(label, tone) {
Expand Down Expand Up @@ -5061,7 +5118,10 @@ <h2 id="recent-title">Run History</h2>
const bits = [statusLabel(humanizeToken(run.status), tone)];

if (run.wait_reason) {
bits.push(inlineStatusFact("Wait", humanizeToken(run.wait_reason)));
const waitReason = sentenceToken(run.wait_reason);
if (!displayTextRepeats(recentRunSummary(run, lane), waitReason)) {
bits.push(inlineStatusFact("Wait", waitReason));
}
}
if (run.continuation_pending) {
bits.push(inlineStatusFact("Continuation", "Pending"));
Expand Down Expand Up @@ -6747,7 +6807,6 @@ <h2 id="recent-title">Run History</h2>
return facts;
}

facts.push(["History", humanizeToken(outcome.ledger_status)]);
if (outcome.pr_url) {
facts.push(["PR", outcome.pr_url]);
}
Expand All @@ -6757,9 +6816,6 @@ <h2 id="recent-title">Run History</h2>
if (outcome.branch) {
facts.push(["Branch", outcome.branch]);
}
if (outcome.closeout_status) {
facts.push(["Closeout", humanizeToken(outcome.closeout_status)]);
}
if (outcome.needs_attention_reason) {
facts.push(["Attention", outcome.needs_attention_reason]);
}
Expand Down Expand Up @@ -7186,7 +7242,7 @@ <h2 id="recent-title">Run History</h2>
summary: run.next_retry_at
? `Retry scheduled for ${formatTimestamp(run.next_retry_at)}.`
: `Waiting on ${humanizeToken(run.wait_reason || run.phase).toLowerCase()}.`,
status: run.wait_reason ? `wait ${humanizeToken(run.wait_reason)}` : `phase ${humanizeToken(run.phase)}`,
status: "waiting",
facts: [
["Codex thread", runThreadSummary(run)],
["Thread flags", runThreadFlagSummary(run)],
Expand Down Expand Up @@ -7234,7 +7290,7 @@ <h2 id="recent-title">Run History</h2>
issue: issueKey,
title: postReviewBlockerTitle(lane),
summary: "",
status: lane.review_decision && blockerScope === "Review" ? `review ${compactStateToken(lane.review_decision)}` : humanizeToken(lane.classification),
status: postReviewBlockerStatus(lane, blockerScope),
facts: [
["Checks", compactStateToken(lane.check_state)],
["Threads", lane.unresolved_review_threads == null ? "none" : String(lane.unresolved_review_threads)],
Expand Down Expand Up @@ -7910,7 +7966,7 @@ <h2 id="recent-title">Run History</h2>
? candidate.blocker_identifiers.join(", ")
: "NONE";
const summary = summarizeQueuedCandidate(candidate);
const reason = queuedCandidateReasonText(candidate);
const reason = queuedCandidateInlineReason(candidate);

return `
<article class="action-card ${tone}">
Expand Down Expand Up @@ -8044,14 +8100,18 @@ <h4>${escapeHtml(item.title)}</h4>
const summary = activeRunSummary(run);

if (run.wait_reason && !runWaitReasonShowsExecutionProgress(run)) {
statusBits.push(inlineStatusFact("Wait", humanizeToken(run.wait_reason)));
const waitReason = sentenceToken(run.wait_reason);
if (!displayTextRepeats(summary, waitReason)) {
statusBits.push(inlineStatusFact("Wait", waitReason));
}
}
if (runTelemetryMissing(run)) {
statusBits.push(
runHasChildAgentActivity(run)
? inlineStatusFact("Metadata", "Pending")
: inlineStatusFact("Telemetry", "Missing"),
);
const telemetryFact = runHasChildAgentActivity(run)
? ["Metadata", "Pending"]
: ["Telemetry", "Missing"];
if (!displayTextRepeats(summary, telemetryFact.join(" "))) {
statusBits.push(inlineStatusFact(telemetryFact[0], telemetryFact[1]));
}
}
if (
!runStoppedProcessNeedsAttention(run) &&
Expand All @@ -8060,10 +8120,14 @@ <h4>${escapeHtml(item.title)}</h4>
statusBits.push(inlineStatusFact("Agent", "Done"));
}
if (run.interactive_requested && !runStoppedProcessNeedsAttention(run)) {
statusBits.push(inlineStatusFact("Operator", "Input"));
if (!displayTextRepeats(summary, "operator input")) {
statusBits.push(inlineStatusFact("Operator", "Input"));
}
}
if (run.continuation_pending) {
statusBits.push(inlineStatusFact("Continuation", "Pending"));
if (!displayTextRepeats(summary, "continuation pending")) {
statusBits.push(inlineStatusFact("Continuation", "Pending"));
}
}
const attemptNumber = attemptNumberFromRun(run);
const stopControl = renderRunStopControl(run);
Expand Down
31 changes: 24 additions & 7 deletions apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ fn operator_dashboard_child_bucket_rows_split_time_bars_from_event_diagnostics()
assert!(!response.contains("Queue ownership"));
assert!(response.contains("attention.worktree_path"));
assert!(response.contains("candidate.attention?.attention_error_class"));
assert!(response.contains("facts.push([\"Cause\", humanizeToken(attention.attention_error_class)]);"));
assert!(response.contains("facts.push([\"Cause\", sentenceToken(attention.attention_error_class)]);"));
assert!(response.contains("queued attention"));
assert!(response.contains("worktree.ownership_reason"));
assert!(response.contains("const hygiene = worktree.hygiene;"));
Expand Down Expand Up @@ -387,6 +387,13 @@ fn operator_dashboard_active_run_status_copy_stays_concise() {
assert!(response.contains("Stopped agent process"));
assert!(response.contains("attention stopped"));
assert!(response.contains("inlineStatusFact(\"Agent\", \"Done\")"));
assert!(response.contains("const waitReason = sentenceToken(run.wait_reason);"));
assert!(response.contains("if (!displayTextRepeats(summary, waitReason))"));
assert!(response.contains("displayTextRepeats(summary, \"operator input\")"));
assert!(response.contains("status: \"waiting\","));
assert!(!response.contains(
"status: run.wait_reason ? `wait ${humanizeToken(run.wait_reason)}`"
));
assert!(!response.contains("Running through ${focus}"));
assert!(!response.contains("Running through model execution."));
assert!(!response.contains("Time is going to ${focus}."));
Expand Down Expand Up @@ -941,10 +948,15 @@ fn operator_dashboard_projects_keep_status_summary_compact() {
assert!(response.contains("return priority == null ? \"NONE\" : `P${priority}`;"));
assert!(response.contains("function queuedCandidateSummaryIsNoise(summary)"));
assert!(response.contains("normalized.includes(\"systemerror\")"));
assert!(response.contains("function sentenceToken(value)"));
assert!(response.contains("function displayTextRepeats(left, right)"));
assert!(response.contains("function inlineStatusFact(label, value)"));
assert!(response.contains("titleCaseLabel(label)"));
assert!(response.contains("const summary = summarizeQueuedCandidate(candidate);"));
assert!(response.contains("const reason = queuedCandidateReasonText(candidate);"));
assert!(response.contains("const reason = queuedCandidateInlineReason(candidate);"));
assert!(response.contains("bits.push(inlineStatusFact(\"History\", humanizeToken(outcome.ledger_status)))"));
assert!(!response.contains("facts.push([\"History\", humanizeToken(outcome.ledger_status)])"));
assert!(!response.contains("facts.push([\"Closeout\", humanizeToken(outcome.closeout_status)])"));
assert!(response.contains("<div class=\"grid two card-facts\">"));
assert!(!response.contains("queue-facts"));
assert!(response.contains("cardField(\"State\", formatDetailToken(candidate.state))"));
Expand Down Expand Up @@ -1099,9 +1111,11 @@ fn operator_dashboard_review_cards_omit_static_summary_copy() {
let response = dashboard_response();

assert!(response.contains("summary: \"\",\n\t\t\t\t\t\t\tstatus: `run ${humanizeToken(activeRun.phase)}`"));
assert!(response.contains("summary: \"\",\n\t\t\t\t\t\t\tstatus: lane.review_decision"));
assert!(response.contains("function postReviewBlockerStatus(lane, blockerScope)"));
assert!(response.contains("status: postReviewBlockerStatus(lane, blockerScope)"));
assert!(response.contains("summary: \"\",\n\t\t\t\t\t\t\tstatus: lane.check_state"));
assert!(response.contains("summary: \"\",\n\t\t\t\t\t\t\tstatus: lane.mergeable"));
assert!(!response.contains("status: lane.review_decision && blockerScope === \"Review\""));
assert!(
response.contains("${item.summary ? `<p class=\"row-summary\">${escapeHtml(item.summary)}</p>` : \"\"}")
);
Expand Down Expand Up @@ -1207,7 +1221,7 @@ fn operator_dashboard_prioritizes_needs_attention_reason_over_retry_count() {
.next()
.expect("queued candidate reason function should have an end");

assert!(reason_text.contains("return \"Needs Attention\";"));
assert!(reason_text.contains("return \"needs attention\";"));
assert!(
response.contains("facts.push([\"Attempt status\", humanizeToken(attention.attempt_status)]);")
);
Expand All @@ -1218,18 +1232,21 @@ fn operator_dashboard_prioritizes_needs_attention_reason_over_retry_count() {
"facts.push([\"Auto retry\", autoRetryBlockedReasonText(attention.auto_retry_blocked_reason)]);"
));
assert!(response.contains("return \"needs-attention label set\";"));
assert!(reason_text.contains("return \"Auto Retry Paused\";"));
assert!(reason_text.contains("return \"auto retry paused\";"));
assert!(response.contains("function queuedCandidateInlineReason(candidate)"));
assert!(response.contains("displayTextRepeats(reason, sentenceToken(candidate.attention.attention_error_class))"));
assert!(response.contains("displayTextRepeats(reason, \"patch retained\")"));
assert!(!response.contains("return \"blocked by needs-attention\";"));
assert!(!reason_text.contains("return \"Retry budget held\";"));
assert!(!response.contains(
"facts.push([\"Retry\", String(attention.retry_budget_attempt_count)]);"
));
assert!(
reason_text
.find("return \"Needs Attention\";")
.find("return \"needs attention\";")
.expect("needs-attention reason should exist")
< reason_text
.find("return \"Auto Retry Paused\";")
.find("return \"auto retry paused\";")
.expect("retry-budget reason should exist")
);
}
Expand Down