fix(pilot): Phase 9 review — partial-outcome notes + per-fix script-builder remount
All checks were successful
Mirror to GitHub / mirror (push) Successful in 3s
All checks were successful
Mirror to GitHub / mirror (push) Successful in 3s
Addresses docs/FlowAssist_Migration/Issues/phase-9-review-issues.md. Issue #1 (High): "Applied partially" from the escalation intercept silently dropped because the backend requires notes on applied_partial and the dialog sent none. The catch was silent and the UI advanced into the conclude flow as if the outcome were recorded. - EscalateInterceptDialog now has a two-step flow: clicking the partial choice reveals a notes textarea (autofocused, required non-empty) plus Back / "Record partial & escalate" buttons. - onChoose signature extended to (choice, notes?). - handleInterceptChoice passes notes to patchOutcome; on failure it surfaces a toast and does NOT advance to the conclude modal, so the intercept stays open for retry. Issue #2 (Medium/High): ScriptBuilderTab kept local state across active-fix changes within the same pilot session, so a stale draft could PATCH against a newer fix.id. Added key={activeFix.id} on the mount — forces a clean remount per fix; backend get-or-create (keyed on user+ai_session_id) still returns the same session row, which is the intended resume-on-refresh semantic; but messages/editorBuffer/latestScript local state resets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -656,19 +656,33 @@ export default function AssistantChatPage() {
|
||||
setShowConclude(true)
|
||||
}, [activeFix])
|
||||
|
||||
const handleInterceptChoice = useCallback(async (choice: InterceptChoice) => {
|
||||
const handleInterceptChoice = useCallback(async (choice: InterceptChoice, notes?: string) => {
|
||||
const stored = escalateIntercept
|
||||
setEscalateIntercept(null)
|
||||
if (!stored || !activeChatId) return
|
||||
if (!stored || !activeChatId) {
|
||||
setEscalateIntercept(null)
|
||||
return
|
||||
}
|
||||
const outcomeToSend: FixOutcome =
|
||||
choice === 'never_applied' ? 'dismissed' : choice
|
||||
try {
|
||||
const updated = await sessionSuggestedFixesApi.patchOutcome(
|
||||
activeChatId, stored.fixId, outcomeToSend,
|
||||
activeChatId, stored.fixId, outcomeToSend, notes,
|
||||
)
|
||||
setActiveFix(updated)
|
||||
} catch { /* non-fatal — engineer can still escalate */ }
|
||||
setShowConclude(true)
|
||||
setEscalateIntercept(null)
|
||||
setShowConclude(true)
|
||||
} catch (err) {
|
||||
// applied_partial without notes (or any other 4xx) must surface — the
|
||||
// previous silent catch let engineers believe the partial outcome was
|
||||
// recorded while it was rejected server-side.
|
||||
const message = choice === 'applied_partial'
|
||||
? 'Couldn’t record the partial outcome. Add a short note and try again.'
|
||||
: 'Couldn’t record the outcome before escalating. Try again.'
|
||||
toast.error(message)
|
||||
// Keep the intercept open so the engineer can retry (partial path can
|
||||
// re-enter the notes step from the dialog).
|
||||
if (import.meta.env.DEV) console.warn('[AssistantChat] intercept outcome failed:', err)
|
||||
}
|
||||
}, [activeChatId, escalateIntercept])
|
||||
|
||||
// Phase 8: Resolve click — auto-mark applied_success if in verifying state
|
||||
@@ -1629,7 +1643,12 @@ export default function AssistantChatPage() {
|
||||
so both scroll positions and state are preserved across tab switches. */}
|
||||
{showTabStrip && activeFix && activeChatId && (
|
||||
<div className={cn('flex-1 min-h-0 flex flex-col', chatTab !== 'script_builder' && 'hidden')}>
|
||||
{/* key={activeFix.id} forces a fresh mount when the active
|
||||
fix changes within the same pilot session — otherwise
|
||||
stale messages / editorBuffer / latestScript from the
|
||||
prior fix could submit against the new fix.id. */}
|
||||
<ScriptBuilderTab
|
||||
key={activeFix.id}
|
||||
fix={activeFix}
|
||||
pilotSessionId={activeChatId}
|
||||
onProgressChange={setScriptBuilderHasProgress}
|
||||
|
||||
Reference in New Issue
Block a user