mirror of
https://github.com/stablyai/orca.git
synced 2026-11-05 03:27:44 +00:00
* Scope native chat command discovery to menu demand * Fix command discovery CI imports and test timing * fix: recover demanded command menus after context retirement * test: load command host fixture before mocked consumers * test: retain eager cache reads across command expiry * test: cover command recovery after pending deadline * test: count demanded command renders and query isolation * test: load mobile command host fixture during collection * test: type command batch fields from subscribe events * test: check command event arrays without assertion * Fix command discovery fixture project boundaries * Name command fixture mocks with public Vitest types * Assert opening metadata on resumed session snapshots * test: assert passive command population boundaries * test: cover mobile command capability handoff * test: correct capability proof scope adapters
70 lines
1.6 KiB
TypeScript
70 lines
1.6 KiB
TypeScript
import type { AgentSessionCommandsResult } from './agent-session-wire'
|
|
|
|
/** Own recovery only while this target's menu is demanded. */
|
|
export function startAgentSessionCommandMenuQuery(
|
|
read: () => Promise<AgentSessionCommandsResult>,
|
|
accept: (result: AgentSessionCommandsResult) => void
|
|
): { invalidate(): void; dispose(): void } {
|
|
let stopped = false
|
|
let running = false
|
|
let dirty = false
|
|
let failures = 0
|
|
let deadline = Date.now() + 330_000
|
|
let timer: ReturnType<typeof setTimeout> | undefined
|
|
const schedule = (delay: number): void => {
|
|
clearTimeout(timer)
|
|
if (!stopped && Date.now() + delay < deadline) {
|
|
timer = setTimeout(() => void run(), delay)
|
|
}
|
|
}
|
|
const run = async (): Promise<void> => {
|
|
if (stopped || Date.now() >= deadline) {
|
|
return
|
|
}
|
|
running = true
|
|
dirty = false
|
|
let delay: number | undefined
|
|
try {
|
|
const result = await read()
|
|
if (stopped || Date.now() >= deadline) {
|
|
return
|
|
}
|
|
accept(result)
|
|
failures = 0
|
|
if (result.commandsPending) {
|
|
delay = 10_000
|
|
}
|
|
} catch {
|
|
if (++failures < 3) {
|
|
delay = 10_000
|
|
}
|
|
} finally {
|
|
running = false
|
|
if (dirty) {
|
|
schedule(0)
|
|
} else if (delay !== undefined) {
|
|
schedule(delay)
|
|
}
|
|
}
|
|
}
|
|
void run()
|
|
return {
|
|
invalidate() {
|
|
if (stopped) {
|
|
return
|
|
}
|
|
failures = 0
|
|
deadline = Date.now() + 330_000
|
|
dirty = true
|
|
if (!running) {
|
|
schedule(0)
|
|
}
|
|
},
|
|
dispose() {
|
|
stopped = true
|
|
dirty = false
|
|
clearTimeout(timer)
|
|
}
|
|
}
|
|
}
|