fix: cross-session assistant trigger guard — heartbeat liveness detection

- Replace fixed-timeout stale detection with localStorage heartbeat mechanism
- Heartbeat writes {sid, ts} every 10s; isOwnerAlive checks sid matches AND freshness
- Stop heartbeat when triggered stream completes (useEffect on !isStreaming)
- removeHeartbeatIfOwned: only delete key if it still belongs to this session
  (prevents new owner's heartbeat from being wiped by old session's cleanup)
- Export clearOnboardingHeartbeat with optional sessionId parameter
- hook-triggered route sets/clears hookTriggeredAt alongside hookTriggeredSessionId
- MiniMax model auto-correction: reset model when not in current provider's list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-03-12 17:27:00 +08:00
1 parent 8cce9889eb
commit 2a0451329b
4 files changed
+130 -6

No files matched your search

@@ -11,7 +11,13 @@ export async function POST(request: NextRequest) {
const { sessionId } = await request.json();
const state = loadState(workspacePath);
// '__clear__' sentinel clears the field (used after onboarding/checkin completes)
state.hookTriggeredSessionId = sessionId === '__clear__' ? undefined : sessionId;
if (sessionId === '__clear__') {
state.hookTriggeredSessionId = undefined;
state.hookTriggeredAt = undefined;
} else {
state.hookTriggeredSessionId = sessionId;
state.hookTriggeredAt = new Date().toISOString();
}
saveState(workspacePath, state);
return NextResponse.json({ success: true });
} catch (e) {