mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
refactor(domain): one owner each for non-empty text schemas and UTF-8 head excerpts (#10569)
Fifteen domain schema files each declared z.string().min(1), eight of them as boundedTextSchema although it bounds nothing. They now share nonEmptyTextSchema from src/domain/textSchemas.ts; the one trimming copy in reconstructionCoverage.ts is renamed trimmedTextSchema. Three private UTF-8 prefix truncators (gdb recent MI records, rizin diagnostics, environment replay) and src/process/boundedUtf8Text.ts are replaced by utf8HeadExcerpt in src/domain/utf8HeadExcerpt.ts, which encodes only the retained prefix and returns a slice of the source text.
This commit is contained in:
1 parent
1ba93b4602
commit
eead7a5815
29 files changed
+236
-173
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import type { ComputerAction } from "../../domain/desktop/computerActions.js";
|
||||
import type { JsonValue } from "../../domain/jsonValue.js";
|
||||
import { boundedUtf8Text } from "../../process/boundedUtf8Text.js";
|
||||
import { utf8HeadExcerpt } from "../../domain/utf8HeadExcerpt.js";
|
||||
|
||||
/** Bytes the log keeps of each string in an action's arguments, such as type's text. */
|
||||
export const LOGGED_TEXT_BYTES = 1024;
|
||||
@@ -35,7 +35,7 @@ const bounded = (
|
||||
redact: Redact,
|
||||
): { readonly value: JsonValue; readonly cut: boolean } => {
|
||||
if (typeof value === "string") {
|
||||
const { text, truncated } = boundedUtf8Text(
|
||||
const { text, truncated } = utf8HeadExcerpt(
|
||||
redact(value),
|
||||
LOGGED_TEXT_BYTES,
|
||||
);
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type EnvironmentSource,
|
||||
type RecordedExchange,
|
||||
} from "./environmentSource.js";
|
||||
import { utf8HeadExcerpt } from "../../domain/utf8HeadExcerpt.js";
|
||||
|
||||
/** Caller arguments as the MCP tool receives them. */
|
||||
export type ReplayArguments = Readonly<Record<string, unknown>>;
|
||||
@@ -307,13 +308,6 @@ export const selectsRecordedLine = (
|
||||
return true;
|
||||
};
|
||||
|
||||
/** The longest prefix of text whose UTF-8 encoding fits the byte limit, encoding only that prefix. */
|
||||
const utf8Prefix = (text: string, maxBytes: number): string => {
|
||||
// encodeInto stops before the first character that does not fit, so `read` ends on a boundary.
|
||||
const { read } = new TextEncoder().encodeInto(text, new Uint8Array(maxBytes));
|
||||
return text.slice(0, read);
|
||||
};
|
||||
|
||||
/** Base64 characters, in whole groups, whose bytes fit the replay limit. */
|
||||
const BASE64_LIMIT_CHARS = Math.floor(REPLAY_BODY_LIMIT_BYTES / 3) * 4;
|
||||
|
||||
@@ -334,7 +328,7 @@ const replayBody = (exchange: RecordedExchange): ReplayBody => {
|
||||
: { body: body.encoded.slice(0, BASE64_LIMIT_CHARS), truncated: true };
|
||||
case "cut":
|
||||
return {
|
||||
body: utf8Prefix(body.text, REPLAY_BODY_LIMIT_BYTES),
|
||||
body: utf8HeadExcerpt(body.text, REPLAY_BODY_LIMIT_BYTES).text,
|
||||
truncated: true,
|
||||
};
|
||||
case "json":
|
||||
@@ -380,15 +374,18 @@ export const replayAnswer = (
|
||||
exact: boolean,
|
||||
{ body, truncated }: ReplayBody = replayBody(exchange),
|
||||
): ReplayResult => {
|
||||
const recordedPath = utf8Prefix(exchange.path, REPLAY_METADATA_LIMIT_BYTES);
|
||||
const recordedPath = utf8HeadExcerpt(
|
||||
exchange.path,
|
||||
REPLAY_METADATA_LIMIT_BYTES,
|
||||
).text;
|
||||
const recordedQuery =
|
||||
exchange.query === null
|
||||
? null
|
||||
: utf8Prefix(exchange.query, REPLAY_METADATA_LIMIT_BYTES);
|
||||
: utf8HeadExcerpt(exchange.query, REPLAY_METADATA_LIMIT_BYTES).text;
|
||||
const contentType =
|
||||
exchange.contentType === null
|
||||
? null
|
||||
: utf8Prefix(exchange.contentType, REPLAY_METADATA_LIMIT_BYTES);
|
||||
: utf8HeadExcerpt(exchange.contentType, REPLAY_METADATA_LIMIT_BYTES).text;
|
||||
return {
|
||||
status: exchange.status,
|
||||
content_type: contentType,
|
||||
|
||||
Reference in new issue
Block a user