Skip to content
Source
Sign inSign up
Open History to see the last commit

composerSend.logic.ts

81 lines3.1 KB

1import type { EnvironmentId, ThreadContextRecord } from "@t3tools/contracts";
2import { collectInlineContextIds } from "../../lib/composerContextReferences";
3​
4/** Attached threads the prompt still links to; replacing linked text leaves stale records. */
5export function referencedThreadContexts(draft: {
6 readonly prompt: string;
7 readonly threadContexts: ReadonlyArray<ThreadContextRecord>;
8}): ReadonlyArray<ThreadContextRecord> {
9 if (draft.threadContexts.length === 0) return [];
10 const referenced = new Set(collectInlineContextIds(draft.prompt));
11 return draft.threadContexts.filter((record) => referenced.has(record.contextId));
13​
14/** Why a send waits for the user to pick a machine when no machine was chosen automatically. */
15export function loadBalancingSendWarning(input: {
16 readonly pending: boolean;
17 readonly threadContexts: ReadonlyArray<ThreadContextRecord>;
18 readonly candidateEnvironmentIds: ReadonlyArray<EnvironmentId>;
19}) {
20 if (input.pending) {
21 return {
22 title: "Checking machine resources",
23 description: "Resource checks are still running. You can choose a machine in the composer.",
24 };
25 }
26 const noMachineReadsEveryThread =
27 input.threadContexts.length > 0 &&
28 !input.candidateEnvironmentIds.some((environmentId) =>
29 input.threadContexts.every((record) => record.environmentId === environmentId),
30 );
31 return {
32 title: "Choose a machine to continue",
33 description: noMachineReadsEveryThread
34 ? "No machine can read every attached thread. Choose a machine in the composer or remove the threads."
35 : "No eligible machine has available resources. Choose a machine in the composer to override.",
36 };
38​
39/**
40 * Why a multiple-model send cannot start: the server predates worktree bootstrap, or the
41 * draft is not a new thread on a Git branch with at least one model.
42 */
43export function multipleModelSendBlock(input: {
44 readonly selectionCount: number;
45 readonly serverSupportsWorktreeBootstrap: boolean;
46 readonly isLocalDraftThread: boolean;
47 readonly isGitRepo: boolean;
48 readonly branch: string | null;
49}): "server-outdated" | "needs-new-git-thread" | null {
50 if (!input.serverSupportsWorktreeBootstrap) return "server-outdated";
51 if (
52 !input.isLocalDraftThread ||
53 !input.isGitRepo ||
54 !input.branch ||
55 input.selectionCount === 0
56 ) {
57 return "needs-new-git-thread";
58 }
59 return null;
61​
62/** Why a message sent over pending approvals did not go out, or null to stop quietly. */
63export function approvalRedirectNotice(input: {
64 readonly draftChanged: boolean;
65 readonly declined: boolean;
66 readonly approvalResponding: boolean;
67 readonly approvalArrived: boolean;
68}): string | null {
69 if (input.draftChanged) {
70 return input.declined
71 ? "Approval declined. Your message changed, so it wasn't sent."
72 : "Your message changed, so it wasn't sent.";
73 }
74 if (input.approvalResponding) {
75 return "An approval is already being answered, so your message wasn't sent.";
76 }
77 if (input.declined && input.approvalArrived) {
78 return "Another approval arrived, so your message wasn't sent.";
79 }
80 return null;