Open History to see the last commit
1import { type MessageId, type RuntimeRequestId } from "@t3tools/contracts";
2import { useState } from "react";
3import { type ComposerSubmissionIntent } from "../../composer-logic";
4import { type SessionPhase, type Thread } from "../../types";
5import {
6 createLocalDispatchSnapshot,
7 hasServerAcknowledgedLocalDispatch,
8 type LocalDispatchSnapshot,
9} from "../ChatView.logic";
10
11export function useLocalDispatchState(input: {
12 activeThread: Thread | undefined;
13 activeLatestRun: Thread["latestRun"] | null;
14 latestUserMessageId: MessageId | null;
15 phase: SessionPhase;
16 activePendingApproval: RuntimeRequestId | null;
17 activePendingUserInput: RuntimeRequestId | null;
18 threadError: string | null | undefined;
19}) {
20 const [localDispatch, setLocalDispatch] = useState<LocalDispatchSnapshot | null>(null);
21
22 const resetLocalDispatch = () => {
23 setLocalDispatch(null);
24 };
25
26 const serverAcknowledgedLocalDispatch = hasServerAcknowledgedLocalDispatch({
27 localDispatch,
28 phase: input.phase,
29 latestRun: input.activeLatestRun,
30 latestUserMessageId: input.latestUserMessageId,
31 runtime: input.activeThread?.runtime ?? null,
32 hasPendingApproval: input.activePendingApproval !== null,
33 hasPendingUserInput: input.activePendingUserInput !== null,
34 threadError: input.threadError,
35 });
36 const activeLocalDispatch = serverAcknowledgedLocalDispatch ? null : localDispatch;
37 const beginLocalDispatch = (options?: {
38 preparingWorktree?: boolean;
39 submissionIntent?: ComposerSubmissionIntent;
40 }) => {
41 const preparingWorktree = Boolean(options?.preparingWorktree);
42 setLocalDispatch((current) => {
43 const active = serverAcknowledgedLocalDispatch ? null : current;
44 if (active) {
45 const submissionIntent = options?.submissionIntent ?? active.submissionIntent;
46 return active.preparingWorktree === preparingWorktree &&
47 active.submissionIntent === submissionIntent
48 ? active
49 : { ...active, preparingWorktree, submissionIntent };
50 }
51 return createLocalDispatchSnapshot(input.activeThread, {
52 ...options,
53 latestUserMessageId: input.latestUserMessageId,
54 });
55 });
56 };
57
58 return {
59 beginLocalDispatch,
60 resetLocalDispatch,
61 localDispatchStartedAt: activeLocalDispatch?.startedAt ?? null,
62 isPreparingWorktree: activeLocalDispatch?.preparingWorktree ?? false,
63 isSendBusy: activeLocalDispatch !== null,
64 backgroundSubmissionPending: activeLocalDispatch?.submissionIntent === "background",
65 };
66}