Skip to content

Commit 2e280a1

Browse files
V48 Gate 3 (implementation-only): pre-first-row processing indicator reads the live call chain — no more header/log mismatch at run start
The header tracker latches Phase→Agent→Step pills from store events the moment the run starts, but log rows only appear for COMPLETED LLM/tool calls (F19) — so until the first row lands the log read 'Initializing' + a bare 'Processing' while the header already showed 'SETUP · INPUT COMPREHENSION · PLAN'. The two surfaces now tell one story: /deposit passes its live context into PipelineExecutionLog, and before the first row the processing indicator renders the same sentence the pills describe ('While Depositing, during Setup, agent Input Comprehension is Planning'); once rows stream, the existing last-row stall label takes over unchanged. Verified: uapi 155 suites / 609 tests green (pre-first-row sentence + bare-'Processing' fallback pinned); tsc clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 31a4531 commit 2e280a1

3 files changed

Lines changed: 74 additions & 3 deletions

File tree

uapi/app/deposit/DepositPageClient.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,7 @@ export default function DepositPageClient() {
15341534
userHasScrolled={synthesisLogScrolled}
15351535
setUserHasScrolled={setSynthesisLogScrolled}
15361536
pipelineMode="deposit"
1537+
liveContext={synthesisLiveContext}
15371538
copyData={{
15381539
runId: synthesisRunId,
15391540
status: synthesisStatus,

uapi/components/base/bitcode/execution/pipeline-execution-log.tsx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ interface PipelineRunLogProps {
118118
* the sentence renders without the prefix.
119119
*/
120120
pipelineMode?: SynthesisPipelineMode | null;
121+
/**
122+
* The CURRENT live call chain (the same rolling context the page's header
123+
* tracker renders). Rows only appear for COMPLETED LLM/tool calls, so before
124+
* the first row lands the processing indicator would otherwise read a bare
125+
* 'Processing' while the header already shows Phase→Agent→Step pills — this
126+
* keeps the two surfaces telling one story.
127+
*/
128+
liveContext?: {
129+
phase: string | null;
130+
agent: string | null;
131+
step: string | null;
132+
failsafe: string | null;
133+
generation: string | null;
134+
} | null;
121135
}
122136

123137
// Threshold (in px) below which we switch to compact layout automatically.
@@ -599,7 +613,8 @@ export const PipelineExecutionLog = forwardRef<HTMLDivElement, PipelineRunLogPro
599613
setUserHasScrolled,
600614
compact: compactProp,
601615
copyData,
602-
pipelineMode
616+
pipelineMode,
617+
liveContext
603618
}, ref) => {
604619
// Automatic compact detection via container width
605620
const containerRef = useRef<HTMLDivElement | null>(null);
@@ -1076,9 +1091,17 @@ export const PipelineExecutionLog = forwardRef<HTMLDivElement, PipelineRunLogPro
10761091

10771092
{/* Processing indicator — shows the last known Phase→Agent→Step→Failsafe→
10781093
Thinkings context + elapsed time since the last streamed event, so a
1079-
genuine hang is visible live instead of an unexplained blank gap. */}
1094+
genuine hang is visible live instead of an unexplained blank gap.
1095+
Before the FIRST row lands (rows are completed calls only), fall
1096+
back to the page's live call-chain context so this line and the
1097+
header pills tell one story instead of a bare 'Processing'. */}
10801098
{isProcessing && (() => {
1081-
const { label, likelyStalled } = buildProcessingStallLabel(flatLines[flatLines.length - 1], nowTick, pipelineMode);
1099+
const lastLine = flatLines[flatLines.length - 1];
1100+
if (!lastLine && liveContext) {
1101+
const sentence = describeExecutionContext({ ...liveContext, mode: pipelineMode ?? null });
1102+
if (sentence) return <ProcessingIndicator label={sentence} stalled={false} />;
1103+
}
1104+
const { label, likelyStalled } = buildProcessingStallLabel(lastLine, nowTick, pipelineMode);
10821105
return <ProcessingIndicator label={label} stalled={likelyStalled} />;
10831106
})()}
10841107
</div>

uapi/tests/pipelineExecutionLogTelemetryUx.test.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,53 @@ describe('TelemetryExplainerTrigger — specific section above generic', () => {
453453
// Pill placement — the pills render to the RIGHT of the chevron + title on
454454
// the SAME line (one flex row), not on a row above the title.
455455
// ---------------------------------------------------------------------------
456+
describe('PipelineExecutionLog — pre-first-row processing indicator', () => {
457+
it('reads the live call-chain sentence before any row lands, matching the header pills', () => {
458+
render(
459+
<PipelineExecutionLog
460+
output=""
461+
isProcessing
462+
error={null}
463+
outputDetails={{}}
464+
onRetry={() => {}}
465+
onDismissError={() => {}}
466+
userHasScrolled={false}
467+
setUserHasScrolled={() => {}}
468+
compact
469+
pipelineMode="deposit"
470+
liveContext={{
471+
phase: 'setup',
472+
agent: 'DepositInputComprehensionAgent',
473+
step: 'plan',
474+
failsafe: null,
475+
generation: null,
476+
}}
477+
/>,
478+
);
479+
expect(
480+
screen.getByText('While Depositing, during Setup, agent Input Comprehension is Planning'),
481+
).toBeInTheDocument();
482+
});
483+
484+
it("falls back to bare 'Processing' when no live context exists yet", () => {
485+
render(
486+
<PipelineExecutionLog
487+
output=""
488+
isProcessing
489+
error={null}
490+
outputDetails={{}}
491+
onRetry={() => {}}
492+
onDismissError={() => {}}
493+
userHasScrolled={false}
494+
setUserHasScrolled={() => {}}
495+
compact
496+
pipelineMode="deposit"
497+
/>,
498+
);
499+
expect(screen.getByText('Processing')).toBeInTheDocument();
500+
});
501+
});
502+
456503
describe('PipelineExecutionLog — pills inline with the title line', () => {
457504
const line = 'LLM call observed';
458505
const outputDetails = {

0 commit comments

Comments
 (0)