fix: unblock agent events after portal direct chat escalation
When a session starts with LLM direct chat then escalates to goosed, invalidate the portal-direct-chat snapshot and stop replaying stale SSE so page-generation turns stream and finish correctly. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+35
-1
@@ -198,16 +198,50 @@ function evaluateCanHandle({
|
||||
return { ok: true, reason: null };
|
||||
}
|
||||
|
||||
export function isPortalDirectChatSnapshot(snapshot) {
|
||||
export function isPortalDirectChatSnapshot(snapshot, { sessionId = null } = {}) {
|
||||
if (!snapshot) return false;
|
||||
const messages = Array.isArray(snapshot?.messages) ? snapshot.messages : [];
|
||||
const lastAssistant = [...messages].reverse().find((message) => message?.role === 'assistant');
|
||||
if (lastAssistant?.metadata?.source !== 'portal-direct-chat') return false;
|
||||
// Mixed agent sessions: a user turn after the portal-direct-chat assistant means
|
||||
// execution moved to goosed — never replay the stale direct-chat snapshot.
|
||||
if (sessionId && !isDirectChatSessionId(sessionId)) {
|
||||
const lastAssistantIndex = messages.indexOf(lastAssistant);
|
||||
const hasUserTurnAfterDirectChat = messages
|
||||
.slice(lastAssistantIndex + 1)
|
||||
.some((message) => message?.role === 'user');
|
||||
if (hasUserTurnAfterDirectChat) return false;
|
||||
}
|
||||
const updatedAtRaw = snapshot?.session?.updated_at ?? snapshot?.meta?.saved_at ?? 0;
|
||||
const updatedAt = Date.parse(String(updatedAtRaw)) || Number(updatedAtRaw) || 0;
|
||||
if (!updatedAt) return true;
|
||||
return Date.now() - updatedAt <= 5 * 60 * 1000;
|
||||
}
|
||||
|
||||
export async function shouldExpirePortalDirectChatSnapshot(pool, sessionId, snapshot) {
|
||||
if (!pool || !sessionId || !snapshot) return false;
|
||||
if (isDirectChatSessionId(sessionId)) return false;
|
||||
if (!isPortalDirectChatSnapshot(snapshot, { sessionId })) return false;
|
||||
const syncedAt = Number(snapshot?.meta?.synced_at ?? 0);
|
||||
if (!syncedAt) return false;
|
||||
const [rows] = await pool.query(
|
||||
`SELECT r.id
|
||||
FROM h5_agent_runs r
|
||||
WHERE r.agent_session_id = ?
|
||||
AND r.status = 'succeeded'
|
||||
AND r.completed_at > ?
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM h5_agent_run_events e
|
||||
WHERE e.run_id = r.id
|
||||
AND e.event_type = 'direct_chat_completed'
|
||||
)
|
||||
LIMIT 1`,
|
||||
[sessionId, syncedAt],
|
||||
);
|
||||
return rows.length > 0;
|
||||
}
|
||||
|
||||
function normalizeUsageForBilling(usage, previousState) {
|
||||
if (!usage) return null;
|
||||
const input = Math.max(0, Number(usage.inputTokens ?? 0) || 0);
|
||||
|
||||
Reference in New Issue
Block a user