| 1 | import type { InboxTarget } from "./pendingFollowup"; |
| 2 | import type { InboxSnapshotLike } from "./composerInboxQueue"; |
| 3 | |
| 4 | export type InboxQueueEdit = { id: string; text: string; contentVersion: string; references: string[] }; |
| 5 | export type InboxQueueRequest = { |
| 6 | kind: "snapshot" | "read" | "edit" | "move" | "delete" | "pause" | "retry" | "steer" | "enqueue_steer"; |
| 7 | itemId?: string; text?: string; contentVersion?: string; |
| 8 | beforeItemId?: string | null; queueRevision?: number; paused?: boolean; |
| 9 | turnId?: string; |
| 10 | display?: string; idempotencyKey?: string; |
| 11 | }; |
| 12 | export type InboxQueueResult = { |
| 13 | outcome: "applied" | "unchanged" | "conflict" | "unavailable"; |
| 14 | reason?: string; snapshot: InboxSnapshotLike; edit?: InboxQueueEdit; |
| 15 | receipt?: { itemId: string; disposition: string; position: number; paused: boolean; error?: string }; |
| 16 | }; |
| 17 | export interface InboxQueueBindings { |
| 18 | InboxQueueForTarget?(target: InboxTarget, request: InboxQueueRequest): Promise<InboxQueueResult>; |
| 19 | } |
| 20 | |
| 21 | export function queuePending(state?: string): boolean { |
| 22 | return state === "queued" || state === "blocked" || state === "uncertain"; |
| 23 | } |
| 24 | |
| 25 | // Adapted from zai-org/ZCode ConversationQueuePanel (Apache-2.0), |
| 26 | // 872ad960. Reasonix uses the same ID anchor for pointer and keyboard moves. |
| 27 | export function queueMoveAnchor(ids: readonly string[], active: string, over: string): string | null | undefined { |
| 28 | if (active === over) return undefined; |
| 29 | const from = ids.indexOf(active), to = ids.indexOf(over); |
| 30 | if (from < 0 || to < 0) return undefined; |
| 31 | if (from < to) { |
| 32 | const remaining = ids.filter(id => id !== active); |
| 33 | return remaining[remaining.indexOf(over) + 1] ?? null; |
| 34 | } |
| 35 | return over; |
| 36 | } |
| 37 | |
| 38 | export function queueActionAnchor(ids: readonly string[], id: string, action: "up" | "down" | "first" | "last"): string | null | undefined { |
| 39 | const index = ids.indexOf(id); |
| 40 | if (index < 0) return undefined; |
| 41 | if (action === "up") return index === 0 ? undefined : ids[index - 1]; |
| 42 | if (action === "down") return index === ids.length - 1 ? undefined : ids[index + 2] ?? null; |
| 43 | if (action === "first") return index === 0 ? undefined : ids[0]; |
| 44 | return index === ids.length - 1 ? undefined : null; |
| 45 | } |
| 46 |