mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-10-03 17:15:19 -07:00
refactor(ui): name the head budget and the truncation suffix
Addresses the budget comment on #1058 by the second route the review offered -- defining the constant as the head budget rather than reserving the suffix inside it. TOAST_ERROR_BUDGET read as though it bounded `display`, but `display` is the head plus " …", so it could be 402. Renamed to HEAD_BUDGET and documented as bounding the message rather than the rendered string, with the suffix now a named constant instead of a literal in the template. Reserving the two characters was the alternative, but nothing downstream has a hard limit -- the description box scrolls -- so it would have shortened the message to satisfy a round number. Verified: head <= 400 and display <= 402 on every truncating input, including no-space text, a short first line, sentence-boundary backoff and the real 4795-char error, with the untouched-when-not-truncated and exact-`full` invariants still holding. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
committed by
capy-ai-staging[bot]
co-authored by
Claude Opus 5
parent
e3b9c98977
commit
8086c818b6
@@ -12,9 +12,19 @@
|
|||||||
* budget, and report how much was dropped so nobody assumes they read it all.
|
* budget, and report how much was dropped so nobody assumes they read it all.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Characters of an error worth putting in a toast. Roughly the first
|
/** Longest head of an oversized error kept for the toast, before the ellipsis.
|
||||||
* paragraph — enough for a sentence or two of real message. */
|
*
|
||||||
const TOAST_ERROR_BUDGET = 400;
|
* Roughly the first paragraph — enough for a sentence or two of real message.
|
||||||
|
* This bounds the *message* rather than the rendered string: `display` is this
|
||||||
|
* plus `TRUNCATION_SUFFIX` when something was cut. Spending two of these
|
||||||
|
* characters on the ellipsis instead would shorten the message to no purpose,
|
||||||
|
* since nothing downstream has a hard character limit — the description box
|
||||||
|
* scrolls.
|
||||||
|
*/
|
||||||
|
const HEAD_BUDGET = 400;
|
||||||
|
|
||||||
|
/** Marks a `display` value as incomplete. Appended after the head. */
|
||||||
|
const TRUNCATION_SUFFIX = ' …';
|
||||||
|
|
||||||
/** Below this, condensing is not worth it and the whole message is shown.
|
/** Below this, condensing is not worth it and the whole message is shown.
|
||||||
*
|
*
|
||||||
@@ -25,7 +35,7 @@ const TOAST_ERROR_BUDGET = 400;
|
|||||||
* around a single character. No Copy action is offered in this range because
|
* around a single character. No Copy action is offered in this range because
|
||||||
* nothing is being withheld: `display` already holds the entire message.
|
* nothing is being withheld: `display` already holds the entire message.
|
||||||
*/
|
*/
|
||||||
const MIN_TO_CONDENSE = TOAST_ERROR_BUDGET + 120;
|
const MIN_TO_CONDENSE = HEAD_BUDGET + 120;
|
||||||
|
|
||||||
export interface CondensedError {
|
export interface CondensedError {
|
||||||
/** What to show in the toast.
|
/** What to show in the toast.
|
||||||
@@ -60,16 +70,16 @@ export function condenseError(raw: string | null | undefined): CondensedError {
|
|||||||
// it fits, since a newline is a stronger boundary than any punctuation.
|
// it fits, since a newline is a stronger boundary than any punctuation.
|
||||||
const firstLine = text.split('\n', 1)[0].trim();
|
const firstLine = text.split('\n', 1)[0].trim();
|
||||||
let head =
|
let head =
|
||||||
firstLine.length > 0 && firstLine.length <= TOAST_ERROR_BUDGET
|
firstLine.length > 0 && firstLine.length <= HEAD_BUDGET
|
||||||
? firstLine
|
? firstLine
|
||||||
: text.slice(0, TOAST_ERROR_BUDGET);
|
: text.slice(0, HEAD_BUDGET);
|
||||||
|
|
||||||
if (head.length < text.length && head === text.slice(0, head.length)) {
|
if (head.length < text.length && head === text.slice(0, head.length)) {
|
||||||
// Back off to the last sentence end inside the budget so the text does not
|
// Back off to the last sentence end inside the budget so the text does not
|
||||||
// stop mid-word. Only accept it if it keeps most of the budget — otherwise
|
// stop mid-word. Only accept it if it keeps most of the budget — otherwise
|
||||||
// a stray early period would throw away usable context.
|
// a stray early period would throw away usable context.
|
||||||
const lastStop = Math.max(head.lastIndexOf('. '), head.lastIndexOf('? '));
|
const lastStop = Math.max(head.lastIndexOf('. '), head.lastIndexOf('? '));
|
||||||
if (lastStop > TOAST_ERROR_BUDGET * 0.4) {
|
if (lastStop > HEAD_BUDGET * 0.4) {
|
||||||
head = head.slice(0, lastStop + 1);
|
head = head.slice(0, lastStop + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,5 +93,5 @@ export function condenseError(raw: string | null | undefined): CondensedError {
|
|||||||
return { display: full, full, truncated: false, omitted: 0 };
|
return { display: full, full, truncated: false, omitted: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { display: `${head} …`, full, truncated: true, omitted };
|
return { display: `${head}${TRUNCATION_SUFFIX}`, full, truncated: true, omitted };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user