Skip to content

feat: add History tab to resume prior agent sessions from disk @W-22434464@#205

Open
marcelinollano wants to merge 21 commits into
mainfrom
ml/W-22434464-navigate-history
Open

feat: add History tab to resume prior agent sessions from disk @W-22434464@#205
marcelinollano wants to merge 21 commits into
mainfrom
ml/W-22434464-navigate-history

Conversation

@marcelinollano
Copy link
Copy Markdown
Collaborator

@marcelinollano marcelinollano commented May 13, 2026

What does this PR do?

Adds a new History tab to the Agentforce DX webview that lists prior cached agent sessions and lets you resume them. Also rounds out the post-session UX so a just-stopped session behaves like a history entry (Resume + Clear), and renders the new GuardrailsStep in the tracer.

History tab

  • Reads sessions from .sfdx/agents/<storageKey>/sessions/ (same on-disk format as the sf CLI plugin), so the list works regardless of which tool wrote the session.
  • Each row shows a session-type badge (Simulation / Live Test), the first user message, and a compressed timestamp.
  • Clicking a row loads that session's transcript and traces into the chat without starting a session — toolbar Start button flips to Resume, live-mode toggle syncs to the previewed session's type, new Clear Chat Session action drops the loaded conversation.
  • If a session is already active when a row is clicked, the SDK session is ended first with a Stopping… spinner, then the previewed conversation renders.

Stop-then-resume flow

  • After a normal Stop on a running session, the session is marked previewable on sessionEnded (no chat reload). Toolbar transitions Stop → Resume directly with no flicker through Start, and Clear Chat Session becomes available.
  • Stop button keeps its label across the optimistic stop window (the prior optimistic update used to flash Start while disabled).
  • Mode switch and agent change end the current session with a restarting flag so the next start does not accidentally route through resume.

Tracer

  • New GuardrailsStep rendered with display name "Guardrails Check", a Codicon shield icon, and the adherence level (e.g. HIGH) as the timeline description.
  • Clicking the step opens the detail panel with generatedResponse and instructionAdherence.

What issues does this PR fix or reference?

@W-22434464@ — [AFDX] [UX] Navigate history
@W-22497762@ — agent preview session lifecycle continuity (merged from main)

Functionality Before

  • Webview only ever surfaced the most recent session. Switching agents or restarting wiped chat/tracer state with no way to revisit prior runs that were already on disk.
  • After Stop, the toolbar showed Start with the messages still on screen and no path to clear or resume.
  • Stop and history-row clicks could flash the wrong button label mid-transition.
  • GuardrailsStep events were not surfaced in the tracer.

Functionality After

  • New History tab with a clock icon, lists all on-disk sessions for the selected agent.
  • Resume reuses the existing agent instance, restores transcript + traces, and skips the canned welcome message.
  • Optimistic UI: clicking a row immediately shows a Resuming session… spinner and disables input — no flicker through the "no session" toolbar state.
  • After Stop, the just-ended session is treated like a history entry: button shows Resume, Clear Chat Session is available.
  • Stop label persists across the stopping transition, and history-row clicks during an active session keep the Stop label until the previewed session lands.
  • GuardrailsStep renders in the tracer with a shield icon, level badge, and clickable detail panel.

Testing Setup Notes

  1. Open a project with an authoring bundle.
  2. Start a Simulation, send a few messages, hit Stop.
    • Toolbar should transition Stop SimulationResume Simulation without flashing Start.
    • Clear Chat Session action should appear in the toolbar.
  3. Click Resume Simulation — chat continues with full context, send another message and confirm a response.
  4. Open the History tab — the just-finished session and any prior sessions appear, newest first, with badge + first-message + timestamp.
  5. Click another row → resumes that session in place; click the same row again → no-op.
  6. Click a row while a session is active → toolbar shows Stopping… spinner, then preview lands and toolbar shows Resume with the new session's mode.
  7. Click Clear Chat Session → chat clears, button reverts to Start Simulation / Live Test SplitButton.
  8. Switch mode (Simulate ↔ Live) on an active session → session restarts cleanly in the new mode (no resume).
  9. Repeat with a Live Test and a Published agent — badges reflect the session type.
  10. Send a message that triggers Guardrails — confirm the Guardrails Check step appears in the tracer with the shield icon and adherence level (e.g. HIGH); clicking it opens the detail panel showing generatedResponse and instructionAdherence.

Tests

  • sessionHistoryService.test.ts — disk-read fallback chain (5 cases).
  • sessionManager.test.tsresumeSession happy path / end-previous / error / no-webview, and endSession resumable-preview flow (simulated/live/published, restarting flag, ordering).
  • webviewMessageHandlers.test.tslistSessions, previewSession flows, and endSession restarting flag wiring.
  • SessionHistory.test.tsx — placeholder, list rendering, empty state, click-to-resume, onPreviewStart callback, no-eager-mode-flip.
  • App.sessionLifecycle.test.tsx — Stop label persistence, history-row stopping transition, sessionEnded preview flip, setConversation handler flows.
  • AgentSelector.test.tsx — Stop label across isStopPending for script and published agents.
  • AgentTracer.helpers.test.tsxGuardrailsStep display name, description, detail data, clickability.

912 tests total (429 backend + 483 frontend), all passing.

🤖 Generated with Claude Code

marcelinollano and others added 3 commits May 13, 2026 00:38
Surfaces a new History tab in the agent webview that lists prior cached
sessions read from .sfdx/agents/<key>/sessions/, the same on-disk format
the sf CLI plugin uses. Clicking a row reattaches the agent via
SDK resumeSession(sessionId), restores the transcript and traces, and
hands control back to the Preview tab without restarting if the chosen
session is already active.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@marcelinollano marcelinollano changed the title feat: add History tab to resume prior agent sessions from disk feat: add History tab to resume prior agent sessions from disk @W-22434464@ May 13, 2026
@marcelinollano marcelinollano marked this pull request as ready for review May 13, 2026 09:47
@marcelinollano marcelinollano requested a review from npiccolo May 13, 2026 16:30
Copy link
Copy Markdown
Contributor

@npiccolo npiccolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual testing ✅

Setup: Extension Development Host launched from ml/W-22434464-navigate-history, agent script project afdx-pro-code-testdrive opened in the test window.

History tab
New clock icon tab appears next to Agent Preview and Agent Tracer. Sessions are listed newest first with correct Simulation badge, first user message, and formatted timestamp.

Resume session
Clicking a row switches to Preview with the transcript restored. Clicking the same row again is a no-op — no restart, jumps straight back to Preview.

Multiple sessions
After running a second simulation, both sessions appear in History newest first with correct entries.

Tab switching regression
Switching between Agent Preview → Agent Tracer → History → Agent Preview keeps the agent selector populated throughout with no loading state.

Automated tests: npm run test:backend (397/397) and npm run test:frontend (392/392) all pass.

LGTM ✅

@npiccolo npiccolo requested a review from jshackell-sfdc May 14, 2026 01:39
@jshackell-sfdc
Copy link
Copy Markdown
Contributor

@marcelinollano , i think you tagged me to review something, but there's a lot of code here and I'm not sure where the public-facing text is. Maybe you can @mention me on the specific lines? Thx.

@npiccolo
Copy link
Copy Markdown
Contributor

npiccolo commented May 14, 2026

@marcelinollano , i think you tagged me to review something, but there's a lot of code here and I'm not sure where the public-facing text is. Maybe you can @mention me on the specific lines? Thx.

I tagged you @jshackell-sfdc because I saw the story has a green border on the sprint board =D
And as I was reviewing this and did not see you as reviewer, I've added you =D

…e-history

# Conflicts:
#	webview/src/App.tsx
Clicking a History row now loads that session's transcript and traces
into the chat without starting a session. The Start button flips to
Resume, the live-mode toggle syncs to the previewed session's type, and
a new Clear Loaded Session toolbar action drops the loaded conversation.
If a session is already active when a row is clicked, the SDK session is
ended first with a Stopping... spinner, then the previewed conversation
is rendered. Also moves the toolbar order so Refresh sits leftmost,
followed by Activate, Save Chat History, and Clear, and removes the
Create Agent button from the empty agent toolbar.
The pre-init getDefaultConnection fallback reads ~/.sfdx and resolves a
real Connection on developer machines with cached sf orgs, causing the
test that expects rejection to fail locally. Mock ConfigAggregator and
Org so the test passes regardless of host environment.
Multiple symptoms during the mid-session History click stem from the
same race between the empty setConversation, sessionStarting, and the
SDK round-trip:

- Reorder backend messages so sessionStarting precedes the empty
  setConversation, and update the webview's isSessionStartingRef
  synchronously inside the listener so it sees the new value before
  setConversation runs.
- Flip sessionActive context to false at the start of the stop so
  toolbar actions gated on it (Start Debug Mode, Stop, etc.) hide
  immediately instead of after the round-trip.
- Hide Activate Version and Clear Loaded Session in the error state.
- Suppress the empty-state placeholder while the spinner is showing.
…e-history

# Conflicts:
#	test/services/coreExtensionService.test.ts
#	webview/src/App.tsx
#	webview/src/components/AgentPreview/AgentSelector.tsx
Toolbar Stop button no longer flickers through Start when stopping. After
a normal stop, the just-ended session is marked as previewable so the
toolbar shows Resume and Clear without reloading the chat. Also covers
the same flicker on history-row clicks during an active session.
Mode switch and agent change end the current session before starting a
new one. Without a restart signal, the just-ended session was marked
previewable, causing the next startSession to route through resumeSession
and resume the prior session instead of starting fresh in the new mode.
Add a sessionStopping context flag set during SDK teardown so view/title
icons can no longer be triggered between sessionActive=false and the
SDK's end completing. Hide the chat transcript and surface a unified
"Stopping session..." spinner while a stop is in flight, disable the
Stop button and tab navigation, and reorder the live-test toolbar so
Restart Options appear before Debug.
@npiccolo npiccolo self-requested a review May 18, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants