| 1 | import { assistantCitationsToPlainText } from "@t3tools/shared/assistantCitations"; |
| 2 | import { truncate } from "@t3tools/shared/String"; |
| 3 | |
| 4 | export interface ThreadTitleSeedInput { |
| 5 | readonly text: string; |
| 6 | readonly attachments: ReadonlyArray<{ readonly name: string }>; |
| 7 | readonly fallbackLabels?: ReadonlyArray<string | null | undefined>; |
| 8 | } |
| 9 | |
| 10 | function normalizeTitleSeed(value: string): string { |
| 11 | return assistantCitationsToPlainText(value).trim().replace(/\s+/gu, " "); |
| 12 | } |
| 13 | |
| 14 | export function deriveThreadTitleSeed(input: ThreadTitleSeedInput): string { |
| 15 | const text = normalizeTitleSeed(input.text); |
| 16 | if (text.length > 0) { |
| 17 | return truncate(text); |
| 18 | } |
| 19 | |
| 20 | const attachmentName = normalizeTitleSeed(input.attachments[0]?.name ?? ""); |
| 21 | if (attachmentName.length > 0) { |
| 22 | return truncate(`Image: ${attachmentName}`); |
| 23 | } |
| 24 | |
| 25 | for (const label of input.fallbackLabels ?? []) { |
| 26 | const normalized = normalizeTitleSeed(label ?? ""); |
| 27 | if (normalized.length > 0) { |
| 28 | return truncate(normalized); |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | return "New thread"; |
| 33 | } |