mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 01:57:57 +00:00
* fix(native-chat): retire acknowledged send echoes after catch-up * test: follow phone lint rules in reconnect regression * test: format reconnect message expectation * Keep current chat requests independent of loaded history * Read current chat requests in bounded cursor pieces * Fix current request subscription static checks * Match generated request schema import ordering * fix(native-chat): correct current request type boundaries * Exercise current request reads in wire compatibility inventory * Align current request fixtures with provider commit and RPC surface * test(native-chat): include current request browser capability * Keep the mobile chat session hook within its line budget * Format mobile current request readers * fix(native-chat): reopen once for a current-request version whose read keeps failing A deterministic read failure reopened the subscription, whose first frame re-read the same version and reset the backoff, so the pane resubscribed every 750 ms forever. * test(native-chat): type the current-request snapshot fixture * test(native-chat): wait for the hydrated open before driving the subscription
84 lines
3.3 KiB
TypeScript
84 lines
3.3 KiB
TypeScript
import { agentSessionCurrentContextRows } from './agent-session-context-clear'
|
|
import type { AgentJournalRenderItem } from './agent-session-journal-types'
|
|
import type { AgentSessionSubscribeEvent } from './agent-session-wire'
|
|
import type { AgentSessionCurrentRequestsMarker } from './agent-session-current-requests-wire'
|
|
import { AGENT_SESSION_CURRENT_REQUESTS_CLIENT_CAPABILITY } from './agent-session-current-requests-capability'
|
|
|
|
export type AgentSessionCurrentRequestsState = {
|
|
currentRequests?: AgentJournalRenderItem[]
|
|
requestMarker?: AgentSessionCurrentRequestsMarker
|
|
/** Qualification survives contact loss alongside the last complete answer. */
|
|
requestAuthority?: AgentSessionCurrentRequestsMarker
|
|
}
|
|
|
|
export function currentRequestsState(
|
|
state: AgentSessionCurrentRequestsState
|
|
): AgentSessionCurrentRequestsState {
|
|
return {
|
|
currentRequests: state.currentRequests,
|
|
requestMarker: state.requestMarker,
|
|
requestAuthority: state.requestAuthority
|
|
}
|
|
}
|
|
|
|
export function applyCurrentRequestsMarker(
|
|
state: AgentSessionCurrentRequestsState,
|
|
marker: AgentSessionCurrentRequestsMarker
|
|
): AgentSessionCurrentRequestsState {
|
|
if (marker.contract !== AGENT_SESSION_CURRENT_REQUESTS_CLIENT_CAPABILITY) {
|
|
return state
|
|
}
|
|
const prior = state.requestMarker ?? state.requestAuthority
|
|
if (prior?.publisher === marker.publisher && marker.revision <= prior.revision) {
|
|
return currentRequestsState(state)
|
|
}
|
|
const sameOwner =
|
|
prior?.publisher === marker.publisher &&
|
|
prior.owner === marker.owner &&
|
|
prior.epoch === marker.epoch &&
|
|
prior.sessionId === marker.sessionId
|
|
return {
|
|
currentRequests: sameOwner ? state.currentRequests : [],
|
|
requestAuthority: sameOwner ? state.requestAuthority : undefined,
|
|
requestMarker: marker
|
|
}
|
|
}
|
|
|
|
/** Openings assert support; an omitted field later only means unchanged. */
|
|
export function currentRequestsAfterEvent(
|
|
state: AgentSessionCurrentRequestsState & { fence: number | null; epoch: string | null },
|
|
event: Exclude<AgentSessionSubscribeEvent, { type: 'end' }>,
|
|
opensSubscription: boolean
|
|
): AgentSessionCurrentRequestsState {
|
|
if (event.currentRequests) {
|
|
return applyCurrentRequestsMarker(state, event.currentRequests)
|
|
}
|
|
if (opensSubscription) {
|
|
return currentRequestsState({})
|
|
}
|
|
const epoch = event.type === 'batch' ? event.batch.cursor.epoch : event.page.epoch
|
|
if (
|
|
state.requestMarker &&
|
|
(epoch !== state.epoch || (event.fence !== undefined && event.fence !== state.fence))
|
|
) {
|
|
return { currentRequests: [], requestMarker: undefined, requestAuthority: undefined }
|
|
}
|
|
return currentRequestsState(state)
|
|
}
|
|
|
|
export type AgentSessionCurrentRequest = AgentJournalRenderItem & {
|
|
body: Extract<AgentJournalRenderItem['body'], { kind: 'approval' | 'question' }>
|
|
}
|
|
|
|
/** Complete operational records own controls independently of historical pages. */
|
|
export function selectAgentSessionCurrentRequests(state: {
|
|
items: readonly AgentJournalRenderItem[]
|
|
currentRequests?: readonly AgentJournalRenderItem[]
|
|
}): AgentSessionCurrentRequest[] {
|
|
return (state.currentRequests ?? agentSessionCurrentContextRows(state.items).items).filter(
|
|
(item): item is AgentSessionCurrentRequest =>
|
|
(item.body.kind === 'approval' || item.body.kind === 'question') &&
|
|
item.body.resolution.state === 'pending'
|
|
)
|
|
}
|