From 2083003b31d27f2756321b413f904cca0b3e1e3f Mon Sep 17 00:00:00 2001 From: CreatorGhost Date: Sun, 12 Jul 2026 00:08:46 +0530 Subject: [PATCH 1/2] fix(tui): relax paste summary thresholds for short pastes --- packages/tui/src/component/prompt/index.tsx | 6 +++--- packages/tui/src/prompt/part.ts | 11 +++++++++++ packages/tui/test/prompt/part.test.ts | 18 +++++++++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/tui/src/component/prompt/index.tsx b/packages/tui/src/component/prompt/index.tsx index 02f6342605c8..879207cb9ef2 100644 --- a/packages/tui/src/component/prompt/index.tsx +++ b/packages/tui/src/component/prompt/index.tsx @@ -31,7 +31,7 @@ import { promptOffsetWidth } from "../../prompt/display" import { createStore, produce, unwrap } from "solid-js/store" import { usePromptHistory, type PromptInfo } from "../../prompt/history" import { computePromptTraits } from "../../prompt/traits" -import { expandPastedTextPlaceholders, expandTrackedPastedText } from "../../prompt/part" +import { expandPastedTextPlaceholders, expandTrackedPastedText, shouldSummarizePaste } from "../../prompt/part" import { usePromptStash } from "../../prompt/stash" import { DialogStash } from "../dialog-stash" import { type AutocompleteRef, Autocomplete } from "./autocomplete" @@ -1198,11 +1198,11 @@ export function Prompt(props: PromptProps) { } } - const lineCount = (pastedContent.match(/\n/g)?.length ?? 0) + 1 if ( - (lineCount >= 3 || pastedContent.length > 150) && + shouldSummarizePaste(pastedContent) && kv.get("paste_summary_enabled", !sync.data.config.experimental?.disable_paste_summary) ) { + const lineCount = (pastedContent.match(/\n/g)?.length ?? 0) + 1 pasteText(pastedContent, `[Pasted ~${lineCount} lines]`) return } diff --git a/packages/tui/src/prompt/part.ts b/packages/tui/src/prompt/part.ts index 0027b9aaed77..107eddb4561e 100644 --- a/packages/tui/src/prompt/part.ts +++ b/packages/tui/src/prompt/part.ts @@ -1,5 +1,16 @@ import { displaySlice } from "./display" +// Summarize only genuinely large pastes into a "[Pasted ~N lines]" placeholder. +// Short pastes, including dictated speech-to-text input (typically a sentence +// or two on a single line), must stay inline and editable. +const PASTE_SUMMARY_LINE_LIMIT = 10 +const PASTE_SUMMARY_CHAR_LIMIT = 1000 + +export function shouldSummarizePaste(text: string) { + const lines = (text.match(/\n/g)?.length ?? 0) + 1 + return lines > PASTE_SUMMARY_LINE_LIMIT || text.length > PASTE_SUMMARY_CHAR_LIMIT +} + export function stripPromptPartIDs(part: Part) { const { id: _id, messageID: _messageID, sessionID: _sessionID, ...rest } = part return rest diff --git a/packages/tui/test/prompt/part.test.ts b/packages/tui/test/prompt/part.test.ts index 2d5605ac0c49..b4651fcf3b6d 100644 --- a/packages/tui/test/prompt/part.test.ts +++ b/packages/tui/test/prompt/part.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import { expandTrackedPastedText, stripPromptPartIDs } from "../../src/prompt/part" +import { expandTrackedPastedText, shouldSummarizePaste, stripPromptPartIDs } from "../../src/prompt/part" describe("prompt part", () => { test("strips persisted IDs from reused parts", () => { @@ -36,6 +36,22 @@ describe("prompt part", () => { ).toBe("你好你好\npublic:\n\tvoid ExecuteTask();\nprivate:\n阿斯顿法国红酒看来") }) + test("keeps short pastes inline", () => { + expect(shouldSummarizePaste("a short sentence")).toBe(false) + expect(shouldSummarizePaste("one\ntwo\nthree\nfour lines")).toBe(false) + // dictated speech-to-text sized input: a paragraph on a single line + expect(shouldSummarizePaste("word ".repeat(150).trim())).toBe(false) + // boundary: exactly at the limits stays inline + expect(shouldSummarizePaste(Array.from({ length: 10 }, () => "line").join("\n"))).toBe(false) + expect(shouldSummarizePaste("x".repeat(1000))).toBe(false) + }) + + test("summarizes genuinely large pastes", () => { + expect(shouldSummarizePaste("x".repeat(1001))).toBe(true) + expect(shouldSummarizePaste(Array.from({ length: 11 }, () => "line").join("\n"))).toBe(true) + expect(shouldSummarizePaste("log line\n".repeat(200))).toBe(true) + }) + test("only expands the tracked placeholder occurrence", () => { const marker = "[Pasted ~3 lines]" const prefix = `keep ${marker} then ` From be2bf8e09ee5ebacbcfa58d55d855a995b0eb810 Mon Sep 17 00:00:00 2001 From: CreatorGhost Date: Sun, 12 Jul 2026 00:25:46 +0530 Subject: [PATCH 2/2] refactor(tui): extract countPasteLines helper per review --- packages/tui/src/component/prompt/index.tsx | 5 ++--- packages/tui/src/prompt/part.ts | 7 +++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/tui/src/component/prompt/index.tsx b/packages/tui/src/component/prompt/index.tsx index 879207cb9ef2..80d4bfa8b8fe 100644 --- a/packages/tui/src/component/prompt/index.tsx +++ b/packages/tui/src/component/prompt/index.tsx @@ -31,7 +31,7 @@ import { promptOffsetWidth } from "../../prompt/display" import { createStore, produce, unwrap } from "solid-js/store" import { usePromptHistory, type PromptInfo } from "../../prompt/history" import { computePromptTraits } from "../../prompt/traits" -import { expandPastedTextPlaceholders, expandTrackedPastedText, shouldSummarizePaste } from "../../prompt/part" +import { countPasteLines, expandPastedTextPlaceholders, expandTrackedPastedText, shouldSummarizePaste } from "../../prompt/part" import { usePromptStash } from "../../prompt/stash" import { DialogStash } from "../dialog-stash" import { type AutocompleteRef, Autocomplete } from "./autocomplete" @@ -1202,8 +1202,7 @@ export function Prompt(props: PromptProps) { shouldSummarizePaste(pastedContent) && kv.get("paste_summary_enabled", !sync.data.config.experimental?.disable_paste_summary) ) { - const lineCount = (pastedContent.match(/\n/g)?.length ?? 0) + 1 - pasteText(pastedContent, `[Pasted ~${lineCount} lines]`) + pasteText(pastedContent, `[Pasted ~${countPasteLines(pastedContent)} lines]`) return } diff --git a/packages/tui/src/prompt/part.ts b/packages/tui/src/prompt/part.ts index 107eddb4561e..ff9ff46b16d8 100644 --- a/packages/tui/src/prompt/part.ts +++ b/packages/tui/src/prompt/part.ts @@ -6,9 +6,12 @@ import { displaySlice } from "./display" const PASTE_SUMMARY_LINE_LIMIT = 10 const PASTE_SUMMARY_CHAR_LIMIT = 1000 +export function countPasteLines(text: string) { + return (text.match(/\n/g)?.length ?? 0) + 1 +} + export function shouldSummarizePaste(text: string) { - const lines = (text.match(/\n/g)?.length ?? 0) + 1 - return lines > PASTE_SUMMARY_LINE_LIMIT || text.length > PASTE_SUMMARY_CHAR_LIMIT + return countPasteLines(text) > PASTE_SUMMARY_LINE_LIMIT || text.length > PASTE_SUMMARY_CHAR_LIMIT } export function stripPromptPartIDs(part: Part) {