Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
commit
03634b1ca3
11340 files changed
+3442369
No files matched your search
@@ -0,0 +1,261 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { ClientSessionState } from '@/app/types'
|
||||
import { createClientSessionState } from '@/lib/chat-runtime'
|
||||
|
||||
import { $activeSessionId, $selectedStoredSessionId, $unreadFinishedSessionIds } from './session'
|
||||
import {
|
||||
$attentionSessionIds,
|
||||
$stalledSessionIds,
|
||||
$workingSessionIds,
|
||||
clearAllSessionStates,
|
||||
getRecentlySettledSessionIds,
|
||||
publishSessionState,
|
||||
SESSION_WATCHDOG_TIMEOUT_MS
|
||||
} from './session-states'
|
||||
|
||||
// Read from the store rather than restated here: these assert what happens on
|
||||
// either side of the threshold, not what the threshold is.
|
||||
const WATCHDOG_MS = SESSION_WATCHDOG_TIMEOUT_MS
|
||||
|
||||
function state(over: Partial<ClientSessionState> = {}): ClientSessionState {
|
||||
return { ...createClientSessionState(null), storedSessionId: 's1', ...over }
|
||||
}
|
||||
|
||||
describe('session status transitions', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
vi.setSystemTime(0)
|
||||
clearAllSessionStates()
|
||||
$unreadFinishedSessionIds.set([])
|
||||
$selectedStoredSessionId.set(null)
|
||||
$activeSessionId.set(null)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.runOnlyPendingTimers()
|
||||
vi.useRealTimers()
|
||||
clearAllSessionStates()
|
||||
$unreadFinishedSessionIds.set([])
|
||||
$selectedStoredSessionId.set(null)
|
||||
$activeSessionId.set(null)
|
||||
})
|
||||
|
||||
it('adds a session to $workingSessionIds when busy transitions to true', () => {
|
||||
const s = state({ busy: false, storedSessionId: 's1' })
|
||||
publishSessionState('rt1', s)
|
||||
|
||||
publishSessionState('rt1', { ...s, busy: true })
|
||||
|
||||
expect($workingSessionIds.get()).toContain('s1')
|
||||
})
|
||||
|
||||
it('removes a session from $workingSessionIds when busy transitions to false', () => {
|
||||
const working = state({ busy: true, storedSessionId: 's1' })
|
||||
publishSessionState('rt1', working)
|
||||
|
||||
expect($workingSessionIds.get()).toContain('s1')
|
||||
|
||||
publishSessionState('rt1', { ...working, busy: false })
|
||||
|
||||
expect($workingSessionIds.get()).not.toContain('s1')
|
||||
})
|
||||
|
||||
it('adds a session to $attentionSessionIds when needsInput is true', () => {
|
||||
const s = state({ busy: true, needsInput: false, storedSessionId: 's1' })
|
||||
publishSessionState('rt1', s)
|
||||
|
||||
publishSessionState('rt1', { ...s, needsInput: true })
|
||||
|
||||
expect($attentionSessionIds.get()).toContain('s1')
|
||||
})
|
||||
|
||||
it('marks a background session unread when its turn finishes', () => {
|
||||
$selectedStoredSessionId.set('other-session')
|
||||
const working = state({ busy: true, storedSessionId: 's1' })
|
||||
publishSessionState('rt1', working)
|
||||
|
||||
publishSessionState('rt1', { ...working, busy: false })
|
||||
|
||||
expect($unreadFinishedSessionIds.get()).toEqual(['s1'])
|
||||
})
|
||||
|
||||
it('does NOT mark unread when the finishing session is the active one', () => {
|
||||
$selectedStoredSessionId.set('s1')
|
||||
const working = state({ busy: true, storedSessionId: 's1' })
|
||||
publishSessionState('rt1', working)
|
||||
|
||||
publishSessionState('rt1', { ...working, busy: false })
|
||||
|
||||
expect($unreadFinishedSessionIds.get()).toEqual([])
|
||||
})
|
||||
|
||||
it('does NOT mark unread on idle→idle re-asserts (no prior working state)', () => {
|
||||
$selectedStoredSessionId.set('other-session')
|
||||
publishSessionState('rt1', state({ busy: false, storedSessionId: 's1' }))
|
||||
|
||||
expect($unreadFinishedSessionIds.get()).toEqual([])
|
||||
})
|
||||
|
||||
it('grants settle grace when a working session goes idle', () => {
|
||||
$selectedStoredSessionId.set('other')
|
||||
const working = state({ busy: true, storedSessionId: 's1' })
|
||||
publishSessionState('rt1', working)
|
||||
|
||||
publishSessionState('rt1', { ...working, busy: false })
|
||||
|
||||
expect(getRecentlySettledSessionIds()).toEqual(['s1'])
|
||||
})
|
||||
|
||||
it('does not grant grace on idle→idle re-asserts', () => {
|
||||
publishSessionState('rt1', state({ busy: false, storedSessionId: 's1' }))
|
||||
expect(getRecentlySettledSessionIds()).toEqual([])
|
||||
})
|
||||
|
||||
it('clears settle grace when the session goes busy again', () => {
|
||||
$selectedStoredSessionId.set('other')
|
||||
const working = state({ busy: true, storedSessionId: 's2' })
|
||||
publishSessionState('rt1', working)
|
||||
const idle = { ...working, busy: false }
|
||||
publishSessionState('rt1', idle)
|
||||
|
||||
expect(getRecentlySettledSessionIds()).toEqual(['s2'])
|
||||
|
||||
publishSessionState('rt1', { ...idle, busy: true })
|
||||
|
||||
expect(getRecentlySettledSessionIds()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('session watchdog', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
clearAllSessionStates()
|
||||
$unreadFinishedSessionIds.set([])
|
||||
$selectedStoredSessionId.set(null)
|
||||
$activeSessionId.set(null)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.runOnlyPendingTimers()
|
||||
vi.useRealTimers()
|
||||
clearAllSessionStates()
|
||||
$unreadFinishedSessionIds.set([])
|
||||
$selectedStoredSessionId.set(null)
|
||||
$activeSessionId.set(null)
|
||||
})
|
||||
|
||||
it('marks a silent session stalled without pretending it finished', () => {
|
||||
publishSessionState('rt1', state({ busy: true, storedSessionId: 's1' }))
|
||||
|
||||
vi.advanceTimersByTime(WATCHDOG_MS)
|
||||
|
||||
expect($workingSessionIds.get()).toContain('s1')
|
||||
expect($stalledSessionIds.get()).toContain('s1')
|
||||
})
|
||||
|
||||
it('clears stalled on new activity and rearms the watchdog', () => {
|
||||
const working = state({ busy: true, storedSessionId: 's2' })
|
||||
publishSessionState('rt2', working)
|
||||
vi.advanceTimersByTime(WATCHDOG_MS)
|
||||
expect($stalledSessionIds.get()).toContain('s2')
|
||||
|
||||
publishSessionState('rt2', { ...working, awaitingResponse: true })
|
||||
expect($stalledSessionIds.get()).not.toContain('s2')
|
||||
|
||||
vi.advanceTimersByTime(WATCHDOG_MS - 1)
|
||||
expect($stalledSessionIds.get()).not.toContain('s2')
|
||||
expect($workingSessionIds.get()).toContain('s2')
|
||||
})
|
||||
|
||||
it('clears both running and stalled on an authoritative terminal transition', () => {
|
||||
const working = state({ busy: true, storedSessionId: 's3' })
|
||||
publishSessionState('rt3', working)
|
||||
vi.advanceTimersByTime(WATCHDOG_MS)
|
||||
expect($stalledSessionIds.get()).toContain('s3')
|
||||
|
||||
publishSessionState('rt3', { ...working, busy: false })
|
||||
|
||||
expect($workingSessionIds.get()).not.toContain('s3')
|
||||
expect($stalledSessionIds.get()).not.toContain('s3')
|
||||
})
|
||||
|
||||
it('never marks a session stalled when it settles before the window', () => {
|
||||
const working = state({ busy: true, storedSessionId: 's4' })
|
||||
publishSessionState('rt4', working)
|
||||
publishSessionState('rt4', { ...working, busy: false })
|
||||
vi.advanceTimersByTime(WATCHDOG_MS)
|
||||
|
||||
expect($workingSessionIds.get()).not.toContain('s4')
|
||||
expect($stalledSessionIds.get()).not.toContain('s4')
|
||||
})
|
||||
|
||||
it('clears stalled state and disarms timers on a gateway wipe', () => {
|
||||
publishSessionState('rt1', state({ busy: true, storedSessionId: 's1' }))
|
||||
vi.advanceTimersByTime(WATCHDOG_MS)
|
||||
expect($stalledSessionIds.get()).toEqual(['s1'])
|
||||
|
||||
clearAllSessionStates()
|
||||
vi.advanceTimersByTime(WATCHDOG_MS)
|
||||
|
||||
expect($workingSessionIds.get()).toEqual([])
|
||||
expect($stalledSessionIds.get()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('computed $workingSessionIds', () => {
|
||||
beforeEach(() => {
|
||||
clearAllSessionStates()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
clearAllSessionStates()
|
||||
})
|
||||
|
||||
it('is empty when no sessions are busy', () => {
|
||||
expect($workingSessionIds.get()).toEqual([])
|
||||
})
|
||||
|
||||
it('reflects busy sessions under the id their surfaces key on', () => {
|
||||
publishSessionState('rt1', state({ busy: true, storedSessionId: 's1' }))
|
||||
publishSessionState('rt2', state({ busy: false, storedSessionId: 's2' }))
|
||||
// Not yet persisted, so the runtime id is the only id it has — and the one
|
||||
// the row is keyed by until the backend hands a stored id back.
|
||||
publishSessionState('rt3', state({ busy: true, storedSessionId: null }))
|
||||
|
||||
expect($workingSessionIds.get()).toEqual(['s1', 'rt3'])
|
||||
})
|
||||
|
||||
it('updates when session state changes', () => {
|
||||
publishSessionState('rt1', state({ busy: true, storedSessionId: 's1' }))
|
||||
expect($workingSessionIds.get()).toEqual(['s1'])
|
||||
|
||||
publishSessionState('rt1', state({ busy: false, storedSessionId: 's1' }))
|
||||
expect($workingSessionIds.get()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('computed $attentionSessionIds', () => {
|
||||
beforeEach(() => {
|
||||
clearAllSessionStates()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
clearAllSessionStates()
|
||||
})
|
||||
|
||||
it('reflects sessions with needsInput=true and a storedSessionId', () => {
|
||||
publishSessionState('rt1', state({ needsInput: true, storedSessionId: 's1' }))
|
||||
publishSessionState('rt2', state({ needsInput: false, storedSessionId: 's2' }))
|
||||
|
||||
expect($attentionSessionIds.get()).toEqual(['s1'])
|
||||
})
|
||||
|
||||
it('clears when $sessionStates is cleared', () => {
|
||||
publishSessionState('rt1', state({ needsInput: true, storedSessionId: 's1' }))
|
||||
expect($attentionSessionIds.get()).toEqual(['s1'])
|
||||
|
||||
clearAllSessionStates()
|
||||
expect($attentionSessionIds.get()).toEqual([])
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user