Supplier Communications prototype (oCFO experiment) - #1088
Draft
petervachon wants to merge 4 commits into
Draft
Conversation
Adds a signal-bar AI confidence chip (high/medium/low/unknown) with min/med/max density variants, a tooltip on every chip, and a popover for factor breakdowns and next-step CTAs, plus an opt-in one-time acquire animation that respects prefers-reduced-motion. The action CTA (nextStep) is required for medium/low confidence per team decision, and optional for high/unknown, enforced via a discriminated union type. Level labels and default explanations resolve through react-i18next under the confidence_signal_* prefix. Registered in registry.json with docs at /components/confidence-signal.
Experiment > Supplier Communication docs page links to a full-screen prototype that opens in its own tab, mounted in a separate React root so it escapes the Nextra docs layout, whose interrupted hydration leaves the subtree display:none. The AP workspace is a three-pane, agent-operated mail client: - shared pane rail, resizable case list, and an editorial case detail - one elevated block per case: the drafted reply, the four-eyes approval stepper, or the compliance escalation. Never two, never zero. - ConfidenceSignal chips, min in list rows and max in the detail. Triggered cases render no chip at all, since they never classified anything. - audit steps tagged by who performed them, so deterministic system-of-record reads do not carry the AI mark AI expression follows /guidelines/ai-toolkit: the mark sits on the compose card and the agent's audit steps, disclosure appears once per case, and the glow stays reserved for the single generated-content surface. A Supplier tab shows the same threads from the supplier's side: an ordinary inbox, no portal and no login. Data is illustrative only. No backend, no network calls, no persistence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three axes, each in its own control, so none of them compete: the rail says what kind of work, the tabs say what state it is in, the date groups say when it arrived. - status tabs (All / Needs you / In flight) above the list. The predicate is needsHuman, not `control !== "auto"`: Harborview reads "Awaiting response" but the PO already went out and reminders run on a schedule, so the next move is the supplier's and it belongs under In flight. - date groups with sticky headers. This needed a real timestamp, so `time` as a display string becomes `receivedAt`, with both the relative label and the bucket derived from it. NOW is a fixed anchor rather than the clock, and it is a Wednesday so day offsets 0-3 land in that calendar week and 4-5 outside it, which makes "Earlier this week" literally true. - the workflow rail loses its Status section, now that the tabs cover it, and collapses behind a filter button in the list pane. Width animates while the inner nav stays pinned so labels do not reflow mid-slide, and it goes inert while hidden so it stays out of the tab order. Styling: rows are glass cards on a muted ground, the rail and list share that ground with no divider between them, and an INBOX label sits on the WORKFLOWS baseline via a shared heading constant. KPI values move up to large bold. The supplier tab gets the same cards, groups and timestamps. It gets no status tabs: there are no control states on that side, and the point of the view is that nothing is asked of the supplier. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…confidence chip - centre the KPI run between the title and the tab group, with an explicit gap: PageHeaderContent sets @3xl:gap-0, which is invisible under justify-between but butts the blocks together once they are centred - "Updated 1 minute ago" plus a Refresh link under the title, using the PageHeaderDescription slot. The text is static like NOW: a live counter would drift away from the fixed timestamps the rest of the demo is anchored to - remove the ConfidenceSignal chip from the list cards. It survives in the case detail at variant="max", so the level thresholds and the no-chip-for-triggered -cases rule are untouched The card's overlay click target stays, but its comment no longer claims the chip's nested button as the reason, since that reason left with the chip. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new Supplier Communication experimental prototype surface to Apollo Vertex (full-screen in a separate tab/root) and brings in the ConfidenceSignal UI component (from the referenced PR) to communicate AI confidence as levels rather than raw scores.
Changes:
- Introduces the Supplier Communication prototype under Experiment → Supplier Communication, including the AP view (workflow rail + case list + case detail) and a supplier-side inbox view.
- Adds demo-only, fixed-time anchored data (
NOW, cases, threads) plus supporting UI components (filters, rails, activity log, action blocks). - Adds the
confidence-signalregistry component + docs and wires translations/registry metadata.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/apollo-vertex/templates/supplier-communication/SupplierCommunicationShell.tsx | New shell-scoped router/query provider wrapper for the prototype. |
| apps/apollo-vertex/templates/supplier-communication/data/supplier-cases.ts | Demo dataset (fixed NOW, cases, workflows, KPIs, supplier threads). |
| apps/apollo-vertex/templates/supplier-communication/components/workflow-rail.tsx | Workflow rail configuration + adapter over shared rail component. |
| apps/apollo-vertex/templates/supplier-communication/components/supplier-inbox.tsx | Supplier-side inbox tab UI (folders, grouped threads, reading pane). |
| apps/apollo-vertex/templates/supplier-communication/components/scroll-pane.ts | Tailwind selector helper intended to fix ScrollArea truncation behavior. |
| apps/apollo-vertex/templates/supplier-communication/components/pane-rail.tsx | Shared collapsible rail implementation used by AP and supplier tabs. |
| apps/apollo-vertex/templates/supplier-communication/components/pane-rail-types.ts | Strongly typed rail section/item models. |
| apps/apollo-vertex/templates/supplier-communication/components/pane-grid.ts | Shared layout constants for the case detail “gutter” and headings. |
| apps/apollo-vertex/templates/supplier-communication/components/control-tone.ts | Central mapping for control-state UI tone + confidence threshold mapping. |
| apps/apollo-vertex/templates/supplier-communication/components/compose-card.tsx | AI-drafted compose action block + disclosure (AiCaveat/AiMark). |
| apps/apollo-vertex/templates/supplier-communication/components/case-time.ts | Fixed-NOW relative time + date grouping utilities for list grouping. |
| apps/apollo-vertex/templates/supplier-communication/components/case-list.tsx | AP case list UI (status tabs, grouping, selection, preview cards). |
| apps/apollo-vertex/templates/supplier-communication/components/case-filters.ts | Workflow/status filtering + needsHuman predicate used by tabs/counts. |
| apps/apollo-vertex/templates/supplier-communication/components/case-detail.tsx | AP case detail pane, including ConfidenceSignal usage and action blocks. |
| apps/apollo-vertex/templates/supplier-communication/components/approval-steps.tsx | Approval workflow stepper component for “four eyes” cases. |
| apps/apollo-vertex/templates/supplier-communication/components/agent-found-panel.tsx | “What the agent found” SoR panel with AI-marked header. |
| apps/apollo-vertex/templates/supplier-communication/components/activity-log.tsx | Provenance/activity log UI with actor markers (agent/person/system). |
| apps/apollo-vertex/templates/supplier-communication/components/action-block.tsx | Single elevated action surface wrapper (AI vs non-AI treatments). |
| apps/apollo-vertex/templates/supplier-communication/communications/CommunicationsPage.tsx | Prototype main page layout (header KPIs + AP/Supplier tabs + resizable panes). |
| apps/apollo-vertex/registry/confidence-signal/confidence-signal.tsx | New ConfidenceSignal component (tooltip + optional popover details/CTAs). |
| apps/apollo-vertex/registry/confidence-signal/confidence-signal-levels.ts | Level config + CTA typing + factor typing + status class map. |
| apps/apollo-vertex/registry/confidence-signal/confidence-signal-factors.tsx | Factor breakdown rows for the popover. |
| apps/apollo-vertex/registry/confidence-signal/confidence-signal-cta.tsx | CTA renderer (button vs anchor via asChild). |
| apps/apollo-vertex/registry/confidence-signal/confidence-signal-chip.tsx | Chip button renderer (bars + label). |
| apps/apollo-vertex/registry/confidence-signal/confidence-signal-bars.tsx | Signal-bars icon (optionally animated acquire sequence). |
| apps/apollo-vertex/registry.json | Registers confidence-signal as a registry UI component. |
| apps/apollo-vertex/locales/en.json | Adds translations/keys for ConfidenceSignal (labels/explanations). |
| apps/apollo-vertex/app/supplier-communication/page.tsx | Mounts the prototype into a separate React root attached to <body>. |
| apps/apollo-vertex/app/experiment/supplier-communication/page.mdx | Adds Experiment landing page + “Open the prototype” link. |
| apps/apollo-vertex/app/experiment/_meta.ts | Adds Experiment nav entry for Supplier Communication. |
| apps/apollo-vertex/app/components/confidence-signal/page.mdx | Adds docs page describing ConfidenceSignal usage and behavior. |
| apps/apollo-vertex/app/components/_meta.ts | Adds Components nav entry for Confidence Signal docs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| * border instead of ellipsing. Forcing that wrapper back to `block` restores | ||
| * the constraint. The `!` is required because Radix sets display inline. | ||
| */ | ||
| export const SCROLL_PANE = "[&_[data-slot=scroll-area-viewport]>div]:block!"; |
Comment on lines
+22
to
+26
| function ConfidenceSignalChip({ | ||
| level, | ||
| label, | ||
| accessibleLabel, | ||
| animateIn = false, |
Comment on lines
+73
to
+77
| <nav | ||
| aria-label={label} | ||
| className={cn(RAIL_WIDTH, "py-4")} | ||
| inert={collapsed} | ||
| > |
Comment on lines
+35
to
+38
| // Date groups say when a case arrived, not whether it needs you, so the dot | ||
| // is carrying its own information again. | ||
| const needsAction = c.control !== "auto"; | ||
|
|
Comment on lines
+7
to
+12
| <a | ||
| href="/supplier-communication" | ||
| target="_blank" | ||
| rel="noreferrer" | ||
| className="not-prose inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground no-underline transition-colors hover:bg-primary/90" | ||
| > |
Comment on lines
+131
to
+136
| <ResizablePanel | ||
| defaultSize="22rem" | ||
| minSize="17rem" | ||
| maxSize="34rem" | ||
| groupResizeBehavior="preserve-pixel-size" | ||
| className="h-full" |
Comment on lines
+73
to
+78
| <ResizablePanel | ||
| defaultSize="20rem" | ||
| minSize="17rem" | ||
| maxSize="34rem" | ||
| groupResizeBehavior="preserve-pixel-size" | ||
| className="h-full" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A demo surface for showing an AP team how agentic supplier email handling works.
It lives under Experiment → Supplier Communication and opens full-screen in
its own tab. Illustrative data only: no backend, no network calls, no persistence.
What it is
An agent-operated mail client for accounts payable, in three panes:
A second tab shows the same threads from the supplier's side: an ordinary
inbox, no portal and no login. The point of that view is what's absent.
The ideas worth reviewing
One elevated block per case, and it's always the thing you can act on. For
most cases that's the drafted reply; for Atlas Precision it's the four-eyes
approval stepper; for Kestrel it's the compliance escalation. Never two, never
zero. Everything above it flattens to rules and eyebrows.
"Needs you" is not "the agent didn't finish". Harborview reads Awaiting
response, but the PO already went out and reminders run on a schedule, so the
next move is the supplier's. The predicate is a named
needsHumanfunction withthe reasoning in a comment, because the obvious guess is
control !== "auto"andthat guess is wrong.
Confidence is a level, not a number. The
ConfidenceSignalchip shows barsrather than a percentage. Cases opened by a monitor or the PO workflow render no
chip at all — they never classified anything, so claiming any confidence about a
judgement that was never made would be worse than saying nothing.
The audit log distinguishes who did what. Agent steps carry the AI mark,
people appear as avatars, deterministic tool calls stay neutral. Classification
and drafting are the agent's; system-of-record reads are not.
AI expression follows
/guidelines/ai-toolkit. The mark sits on the composecard and the agent's audit steps, disclosure appears once per case, and the glow
is reserved for the single generated-content surface.
Notes for reviewers
ConfidenceSignal, authoredby Chloe Daly). It's here so this branch builds standalone. Once feat(apollo-vertex): add ConfidenceSignal component #1034 lands in
main it should drop out on rebase; if you review this before then, skip that
commit.
NOW, not the clock, so the demo doesn'tdrift into everything reading "Older" next month. It's a Wednesday on purpose,
which is what makes "Earlier this week" literally true.
<body>. Nextra'sinterrupted hydration otherwise leaves a full-screen client app stuck
display: none.in the repo and adding one would have broken the no-new-dependencies constraint.
Typecheck, lint, format and build are clean, and layout maths was checked by
calculation, but a human should look at both light and dark before this leaves
draft.
Still open
Badgehas no size variant; the list cards would suit a smaller one. Either acall-site override here or a real
sizevariant on the shared component.happened. Worth confirming that's the line you'd draw too.
🤖 Generated with Claude Code