Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
type AskSnapshot = {
|
|
messages: readonly {
|
|
id: string;
|
|
runId?: string | null;
|
|
blocks: readonly { kind: string; status?: string }[];
|
|
}[];
|
|
run?: { id: string; status: string } | null;
|
|
activeRuns?: readonly { id: string; status: string }[];
|
|
};
|
|
|
|
export function latestAnswerableAskMessageId(snapshot: AskSnapshot | null): string | null {
|
|
if (!snapshot) return null;
|
|
const waitingRunIds = new Set(
|
|
(snapshot.activeRuns ?? (snapshot.run ? [snapshot.run] : []))
|
|
.filter((run) => run.status === "waiting_input")
|
|
.map((run) => run.id),
|
|
);
|
|
for (let index = snapshot.messages.length - 1; index >= 0; index -= 1) {
|
|
const message = snapshot.messages[index];
|
|
if (!message?.runId || !waitingRunIds.has(message.runId)) continue;
|
|
if (message.blocks.some((block) => block.kind === "ask" && block.status !== "answered")) {
|
|
return message.id;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function selectedAskActionLabel(
|
|
answer: string,
|
|
actions?: readonly { id: string; label: string }[],
|
|
): string {
|
|
return actions?.find((action) => action.id === answer)?.label ?? answer;
|
|
}
|