bfa60338cc
Co-Authored-By: Paperclip <noreply@paperclip.ing>
60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
const DEFAULT_CAPTURED_OUTPUT_BYTES = 256 * 1024;
|
|
|
|
export type CapturedOutput = {
|
|
text: string;
|
|
truncated: boolean;
|
|
totalBytes: number;
|
|
};
|
|
|
|
export function createCapturedOutputBuffer(maxBytes = DEFAULT_CAPTURED_OUTPUT_BYTES) {
|
|
const limit = Math.max(1, Math.trunc(maxBytes));
|
|
const chunks: Buffer[] = [];
|
|
let bufferedBytes = 0;
|
|
let totalBytes = 0;
|
|
let truncated = false;
|
|
|
|
return {
|
|
append(chunk: Buffer | string | null | undefined) {
|
|
if (chunk === null || chunk === undefined) return;
|
|
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
if (buffer.length === 0) return;
|
|
|
|
chunks.push(buffer);
|
|
bufferedBytes += buffer.length;
|
|
totalBytes += buffer.length;
|
|
|
|
while (bufferedBytes > limit && chunks.length > 0) {
|
|
const overflow = bufferedBytes - limit;
|
|
const head = chunks[0]!;
|
|
if (head.length <= overflow) {
|
|
chunks.shift();
|
|
bufferedBytes -= head.length;
|
|
truncated = true;
|
|
continue;
|
|
}
|
|
|
|
chunks[0] = head.subarray(overflow);
|
|
bufferedBytes -= overflow;
|
|
truncated = true;
|
|
}
|
|
},
|
|
|
|
finish(): CapturedOutput {
|
|
const body = Buffer.concat(chunks).toString("utf8");
|
|
if (!truncated) {
|
|
return {
|
|
text: body,
|
|
truncated,
|
|
totalBytes,
|
|
};
|
|
}
|
|
|
|
return {
|
|
text: `[output truncated to last ${limit} bytes; total ${totalBytes} bytes]\n${body}`,
|
|
truncated,
|
|
totalBytes,
|
|
};
|
|
},
|
|
};
|
|
}
|