Skip to content

Commit cd11099

Browse files
acailicclaude
andcommitted
feat: add Failure Clustering, Multi-Agent Coordination panels and fix Inspect tab layout
- Enhanced FailureClusterPanel with severity heatmap, relative-size bar charts, and analysis-derived cluster data when dedicated array is empty - New MultiAgentCoordinationPanel with speaker topology, turn-by-turn timeline, coordination metrics, escalation highlights, and evidence grounding - Fixed Inspect tab presentation layout with workspace--inspect class, responsive multi-column grid, scrollable overflow, and DecisionTree max-height Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7413e14 commit cd11099

4 files changed

Lines changed: 777 additions & 31 deletions

File tree

frontend/src/App.css

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,40 @@ button {
486486
}
487487
}
488488

489+
/* Inspect tab: full-width workspace with proper panel layout */
490+
.workspace--inspect {
491+
grid-template-columns: 1fr;
492+
overflow-y: auto;
493+
max-height: calc(100vh - 12rem);
494+
}
495+
496+
.workspace--inspect .main-stage {
497+
overflow-y: visible;
498+
}
499+
500+
/* Inspect grid: responsive multi-column layout for panels */
501+
.workspace--inspect .inspect-grid {
502+
display: grid;
503+
grid-template-columns: repeat(auto-fill, minmax(min(100%, 28rem), 1fr));
504+
gap: 1rem;
505+
}
506+
507+
/* Primary panel spans full width */
508+
.workspace--inspect .inspect-grid > .panel--primary {
509+
grid-column: 1 / -1;
510+
}
511+
512+
/* Secondary panels flow naturally */
513+
.workspace--inspect .inspect-grid > .panel--secondary {
514+
min-width: 0;
515+
}
516+
517+
/* DecisionTree max-height to prevent cutoff */
518+
.workspace--inspect .timeline-panel {
519+
max-height: 400px;
520+
overflow-y: auto;
521+
}
522+
489523
/* Panel hierarchy: subtle (default) < secondary < primary */
490524
.panel {
491525
border-radius: 1.4rem;
@@ -1745,6 +1779,11 @@ pre {
17451779
grid-template-columns: 1fr;
17461780
}
17471781

1782+
/* Inspect grid: 2 columns on tablet */
1783+
.workspace--inspect .inspect-grid {
1784+
grid-template-columns: repeat(2, 1fr);
1785+
}
1786+
17481787
.trace-layout,
17491788
.inspectors-grid,
17501789
.conversation-list,
@@ -1807,6 +1846,11 @@ pre {
18071846
gap: 0.75rem;
18081847
}
18091848

1849+
/* Inspect grid: single column on mobile */
1850+
.workspace--inspect .inspect-grid {
1851+
grid-template-columns: 1fr;
1852+
}
1853+
18101854
/* Ensure all rails stack vertically */
18111855
.session-rail,
18121856
.detail-rail,
@@ -4417,3 +4461,266 @@ pre {
44174461
.conversation-panel .shift-to {
44184462
color: var(--accent);
44194463
}
4464+
4465+
/* ============================================================================
4466+
MULTI-AGENT COORDINATION PANEL STYLES
4467+
============================================================================ */
4468+
4469+
.coordination-panel {
4470+
animation: fadeInUp 200ms ease;
4471+
}
4472+
4473+
.coordination-metrics {
4474+
display: grid;
4475+
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
4476+
gap: 0.75rem;
4477+
padding: 0.75rem 0;
4478+
margin-bottom: 1rem;
4479+
}
4480+
4481+
.coordination-metric {
4482+
display: flex;
4483+
flex-direction: column;
4484+
align-items: center;
4485+
text-align: center;
4486+
padding: 0.5rem;
4487+
border-radius: 0.6rem;
4488+
background: color-mix(in oklch, var(--panel), var(--bg-strong) 25%);
4489+
}
4490+
4491+
.coordination-metric .metric-label {
4492+
font-size: 0.65rem;
4493+
margin-bottom: 0.25rem;
4494+
}
4495+
4496+
.coordination-metric strong {
4497+
font-size: 1.1rem;
4498+
font-variant-numeric: tabular-nums;
4499+
}
4500+
4501+
.coordination-metric small {
4502+
font-size: 0.6rem;
4503+
color: var(--muted);
4504+
margin-top: 0.1rem;
4505+
}
4506+
4507+
/* Speaker Topology */
4508+
.speaker-topology {
4509+
padding: 0.75rem 0;
4510+
margin-bottom: 1rem;
4511+
}
4512+
4513+
.speaker-bars {
4514+
display: flex;
4515+
flex-direction: column;
4516+
gap: 0.4rem;
4517+
}
4518+
4519+
.speaker-bar-row {
4520+
display: grid;
4521+
grid-template-columns: 1fr 2fr;
4522+
gap: 0.5rem;
4523+
align-items: center;
4524+
}
4525+
4526+
.speaker-name {
4527+
font-size: 0.7rem;
4528+
font-weight: 500;
4529+
color: var(--muted);
4530+
overflow: hidden;
4531+
text-overflow: ellipsis;
4532+
white-space: nowrap;
4533+
}
4534+
4535+
.speaker-bar-container {
4536+
position: relative;
4537+
display: flex;
4538+
align-items: center;
4539+
height: 0.6rem;
4540+
background: color-mix(in oklch, var(--bg-strong), var(--muted) 15%);
4541+
border-radius: 999px;
4542+
overflow: hidden;
4543+
}
4544+
4545+
.speaker-bar {
4546+
height: 100%;
4547+
background: var(--accent);
4548+
border-radius: 999px;
4549+
transition: width 300ms ease;
4550+
min-width: 2px;
4551+
}
4552+
4553+
.speaker-turn-count {
4554+
position: absolute;
4555+
right: 0.4rem;
4556+
font-size: 0.55rem;
4557+
font-weight: 600;
4558+
color: var(--text);
4559+
text-shadow: 0 0 2px color-mix(in oklch, var(--panel), white 50%);
4560+
}
4561+
4562+
/* Turn Timeline Strip */
4563+
.turn-timeline {
4564+
padding: 0.75rem 0;
4565+
margin-bottom: 1rem;
4566+
}
4567+
4568+
.turn-strip {
4569+
display: flex;
4570+
gap: 2px;
4571+
align-items: center;
4572+
margin: 0.5rem 0;
4573+
flex-wrap: wrap;
4574+
}
4575+
4576+
.turn-cell {
4577+
position: relative;
4578+
width: 8px;
4579+
height: 16px;
4580+
border-radius: 2px;
4581+
background: var(--node-default);
4582+
transition: transform 150ms ease;
4583+
}
4584+
4585+
.turn-cell:hover {
4586+
transform: scale(1.3);
4587+
z-index: 1;
4588+
}
4589+
4590+
.turn-cell.escalation {
4591+
background: var(--danger);
4592+
}
4593+
4594+
.turn-cell.policy-shift {
4595+
background: var(--warning);
4596+
}
4597+
4598+
.turn-indicator {
4599+
position: absolute;
4600+
top: 50%;
4601+
left: 50%;
4602+
transform: translate(-50%, -50%);
4603+
font-size: 0.5rem;
4604+
color: white;
4605+
font-weight: 700;
4606+
}
4607+
4608+
.turn-ellipsis {
4609+
width: auto;
4610+
min-width: 24px;
4611+
padding: 0 0.25rem;
4612+
font-size: 0.55rem;
4613+
color: var(--muted);
4614+
background: transparent;
4615+
display: flex;
4616+
align-items: center;
4617+
justify-content: center;
4618+
}
4619+
4620+
.turn-legend {
4621+
display: flex;
4622+
flex-wrap: wrap;
4623+
gap: 0.5rem;
4624+
margin-top: 0.4rem;
4625+
}
4626+
4627+
.legend-item {
4628+
display: flex;
4629+
align-items: center;
4630+
gap: 0.25rem;
4631+
font-size: 0.65rem;
4632+
}
4633+
4634+
.legend-dot {
4635+
width: 8px;
4636+
height: 8px;
4637+
border-radius: 50%;
4638+
}
4639+
4640+
.legend-indicator {
4641+
font-size: 0.7rem;
4642+
}
4643+
4644+
/* Policy Pills */
4645+
.coordination-policies {
4646+
padding: 0.75rem 0;
4647+
}
4648+
4649+
.policy-pills {
4650+
display: flex;
4651+
flex-wrap: wrap;
4652+
gap: 0.35rem;
4653+
margin-top: 0.4rem;
4654+
}
4655+
4656+
.policy-pill {
4657+
display: inline-block;
4658+
padding: 0.25rem 0.5rem;
4659+
border-radius: 999px;
4660+
background: color-mix(in oklch, var(--accent), white 85%);
4661+
border: 1px solid color-mix(in oklch, var(--accent), white 50%);
4662+
font-size: 0.65rem;
4663+
font-weight: 500;
4664+
color: var(--accent-deep);
4665+
}
4666+
4667+
/* ============================================================================
4668+
ENHANCED FAILURE CLUSTER PANEL STYLES
4669+
============================================================================ */
4670+
4671+
.cluster-bar-chart {
4672+
display: flex;
4673+
gap: 2px;
4674+
height: 6px;
4675+
margin-bottom: 1rem;
4676+
padding: 0 0.75rem;
4677+
}
4678+
4679+
.cluster-bar {
4680+
height: 100%;
4681+
border-radius: 999px;
4682+
transition: width 300ms ease, opacity 200ms ease;
4683+
}
4684+
4685+
.cluster-bar:hover {
4686+
opacity: 0.8;
4687+
}
4688+
4689+
.cluster-event-detail {
4690+
display: flex;
4691+
justify-content: space-between;
4692+
align-items: center;
4693+
margin-top: 0.5rem;
4694+
padding-top: 0.5rem;
4695+
border-top: 1px solid var(--panel-border);
4696+
}
4697+
4698+
.cluster-event-detail small {
4699+
font-size: 0.6rem;
4700+
color: var(--muted);
4701+
text-transform: uppercase;
4702+
letter-spacing: 0.05em;
4703+
}
4704+
4705+
/* ============================================================================
4706+
MEDIA QUERIES
4707+
============================================================================ */
4708+
4709+
@media (max-width: 768px) {
4710+
.coordination-metrics {
4711+
grid-template-columns: repeat(3, 1fr);
4712+
}
4713+
4714+
.speaker-bar-row {
4715+
grid-template-columns: 1fr 1.5fr;
4716+
}
4717+
4718+
.turn-strip {
4719+
gap: 1px;
4720+
}
4721+
4722+
.turn-cell {
4723+
width: 6px;
4724+
height: 12px;
4725+
}
4726+
}

frontend/src/App.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { DriftAlertsPanel } from './components/DriftAlertsPanel'
1010
import { FailureClusterPanel } from './components/FailureClusterPanel'
1111
import { LLMViewer } from './components/LLMViewer'
1212
import { LiveDashboard } from './components/LiveDashboard'
13+
import { MultiAgentCoordinationPanel } from './components/MultiAgentCoordinationPanel'
1314
import { PolicyDiffView } from './components/PolicyDiffView'
1415
import { SearchPanel } from './components/SearchPanel'
1516
import { SessionComparisonPanel } from './components/SessionComparisonPanel'
@@ -509,7 +510,7 @@ function App() {
509510
{activeTab === 'analytics' && <AnalyticsTab />}
510511

511512
{activeTab === 'inspect' && (
512-
<main className="workspace">
513+
<main className="workspace workspace--inspect">
513514
<section className="main-stage">
514515
{!selectedSessionId ? (
515516
<EmptyState
@@ -659,7 +660,10 @@ function App() {
659660
clusters={failureClusters}
660661
onSelectSession={setSelectedSessionId}
661662
selectedSessionId={selectedSessionId}
663+
analysisClusters={bundle?.analysis.failure_clusters ?? []}
664+
events={mergedSessionEvents}
662665
/>
666+
<MultiAgentCoordinationPanel bundle={bundle} />
663667
</div>
664668
</section>
665669
</main>

0 commit comments

Comments
 (0)