/ components / PromptInput / inputPaste.ts
inputPaste.ts
 1  import { getPastedTextRefNumLines } from 'src/history.js'
 2  import type { PastedContent } from 'src/utils/config.js'
 3  
 4  const TRUNCATION_THRESHOLD = 10000 // Characters before we truncate
 5  const PREVIEW_LENGTH = 1000 // Characters to show at start and end
 6  
 7  type TruncatedMessage = {
 8    truncatedText: string
 9    placeholderContent: string
10  }
11  
12  /**
13   * Determines whether the input text should be truncated. If so, it adds a
14   * truncated text placeholder and neturns
15   *
16   * @param text The input text
17   * @param nextPasteId The reference id to use
18   * @returns The new text to display and separate placeholder content if applicable.
19   */
20  export function maybeTruncateMessageForInput(
21    text: string,
22    nextPasteId: number,
23  ): TruncatedMessage {
24    // If the text is short enough, return it as-is
25    if (text.length <= TRUNCATION_THRESHOLD) {
26      return {
27        truncatedText: text,
28        placeholderContent: '',
29      }
30    }
31  
32    // Calculate how much text to keep from start and end
33    const startLength = Math.floor(PREVIEW_LENGTH / 2)
34    const endLength = Math.floor(PREVIEW_LENGTH / 2)
35  
36    // Extract the portions we'll keep
37    const startText = text.slice(0, startLength)
38    const endText = text.slice(-endLength)
39  
40    // Calculate the number of lines that will be truncated
41    const placeholderContent = text.slice(startLength, -endLength)
42    const truncatedLines = getPastedTextRefNumLines(placeholderContent)
43  
44    // Create a placeholder reference similar to pasted text
45    const placeholderId = nextPasteId
46    const placeholderRef = formatTruncatedTextRef(placeholderId, truncatedLines)
47  
48    // Combine the parts with the placeholder
49    const truncatedText = startText + placeholderRef + endText
50  
51    return {
52      truncatedText,
53      placeholderContent,
54    }
55  }
56  
57  function formatTruncatedTextRef(id: number, numLines: number): string {
58    return `[...Truncated text #${id} +${numLines} lines...]`
59  }
60  
61  export function maybeTruncateInput(
62    input: string,
63    pastedContents: Record<number, PastedContent>,
64  ): { newInput: string; newPastedContents: Record<number, PastedContent> } {
65    // Get the next available ID for the truncated content
66    const existingIds = Object.keys(pastedContents).map(Number)
67    const nextPasteId = existingIds.length > 0 ? Math.max(...existingIds) + 1 : 1
68  
69    // Apply truncation
70    const { truncatedText, placeholderContent } = maybeTruncateMessageForInput(
71      input,
72      nextPasteId,
73    )
74  
75    if (!placeholderContent) {
76      return { newInput: input, newPastedContents: pastedContents }
77    }
78  
79    return {
80      newInput: truncatedText,
81      newPastedContents: {
82        ...pastedContents,
83        [nextPasteId]: {
84          id: nextPasteId,
85          type: 'text',
86          content: placeholderContent,
87        },
88      },
89    }
90  }