Skip to content
Source
Sign inSign up

threadTitleRegeneration.ts

66 lines2.2 KB

1import type {
2 CommandId,
3 OrchestrationV2ShellSnapshot,
4 ThreadId,
5 ThreadTitleRegenerationOutcome,
6} from "@t3tools/contracts";
7import type { Atom, AtomRegistry } from "effect/reactivity";
8​
9export interface TitleRegenerationRequest {
10 readonly threadId: ThreadId;
11 readonly requestId: CommandId;
12 readonly sequence: number;
14​
15export interface TitleRegenerationSources {
16 readonly snapshot: Atom.Atom<OrchestrationV2ShellSnapshot | null>;
17 readonly disconnected: Atom.Atom<boolean>;
19​
20function settledOutcome(
21 snapshot: OrchestrationV2ShellSnapshot | null,
22 request: TitleRegenerationRequest,
23): ThreadTitleRegenerationOutcome | null | undefined {
24 if (snapshot === null) return undefined;
25 if (snapshot.snapshotSequence < request.sequence) return undefined;
26 const thread =
27 snapshot.threads.find((candidate) => candidate.id === request.threadId) ??
28 snapshot.archivedThreads.find((candidate) => candidate.id === request.threadId);
29 if (thread === undefined) return null;
30 const last = thread.lastTitleRegeneration;
31 if (last?.requestId === request.requestId) {
32 return last.message === undefined
33 ? { status: last.status }
34 : { status: last.status, message: last.message };
35 }
36 return thread.titleRegeneration?.requestId === request.requestId ? undefined : null;
38​
39export function waitForTitleRegenerationOutcome(
40 registry: AtomRegistry.AtomRegistry,
41 sources: TitleRegenerationSources,
42 request: TitleRegenerationRequest,
43): Promise<ThreadTitleRegenerationOutcome | null> {
44 return new Promise((resolve) => {
45 let settled = false;
46 let unsubscribes: ReadonlyArray<() => void> = [];
47 const release = () => {
48 for (const unsubscribe of unsubscribes) unsubscribe();
49 };
50 const check = () => {
51 if (settled) return;
52 let outcome = settledOutcome(registry.get(sources.snapshot), request);
53 if (outcome === undefined && registry.get(sources.disconnected)) outcome = null;
54 if (outcome === undefined) return;
55 settled = true;
56 release();
57 resolve(outcome);
58 };
59 unsubscribes = [
60 registry.subscribe(sources.snapshot, check),
61 registry.subscribe(sources.disconnected, check),
62 ];
63 if (settled) release();
64 else check();
65 });