UNPKG

agents

Version:

A home for your AI agents

79 lines (78 loc) 2.71 kB
//#region src/sessions/sanitize.ts /** * Message hygiene shared by every Sessions write: UTF-8 measurement without a * full encoded copy, and removal of ephemeral provider metadata that must not * be stored or replayed. */ const textEncoder = new TextEncoder(); const BYTE_LENGTH_BUFFER_BYTES = 16 * 1024; const BYTE_LENGTH_WINDOW_CHARS = 16 * 1024; /** * Measure UTF-8 byte length without allocating a complete encoded copy. * Memory stays bounded by a 16 KiB buffer even for near-row-limit strings. */ function byteLength(s) { const buffer = new Uint8Array(BYTE_LENGTH_BUFFER_BYTES); let offset = 0; let bytes = 0; while (offset < s.length) { let end = Math.min(s.length, offset + BYTE_LENGTH_WINDOW_CHARS); if (end < s.length && end > offset && isHighSurrogate(s.charCodeAt(end - 1))) end--; const { read, written } = textEncoder.encodeInto(s.slice(offset, end), buffer); if (read === 0) break; offset += read; bytes += written; } return bytes; } function isHighSurrogate(code) { return code >= 55296 && code <= 56319; } /** * Sanitize a message for persistence by removing ephemeral provider-specific * data that should not be stored or sent back in subsequent requests. * * 1. Strips OpenAI ephemeral fields (itemId, reasoningEncryptedContent) * 2. Filters truly empty reasoning parts (no text, no remaining providerMetadata) */ function sanitizeMessage(message) { const parts = message.parts.flatMap((part) => { let sanitized = part; for (const key of ["providerMetadata", "callProviderMetadata"]) { const metadata = sanitized[key]; if (metadata && typeof metadata === "object" && "openai" in metadata) sanitized = stripOpenAIMetadata(sanitized, key); } if (sanitized.type === "reasoning") { const text = sanitized.text; if (typeof text !== "string" || text.trim() === "") { const metadata = sanitized.providerMetadata; if (!(metadata && typeof metadata === "object" && Object.keys(metadata).length > 0)) return []; } } return [sanitized]; }); return { ...message, parts }; } function stripOpenAIMetadata(part, metadataKey) { const metadata = part[metadataKey]; if (!metadata?.openai) return part; const { itemId: _itemId, reasoningEncryptedContent: _rec, ...restOpenai } = metadata.openai; const { openai: _openai, ...restMetadata } = metadata; let next; if (Object.keys(restOpenai).length > 0) next = { ...restMetadata, openai: restOpenai }; else if (Object.keys(restMetadata).length > 0) next = restMetadata; const { [metadataKey]: _old, ...rest } = part; return next ? { ...rest, [metadataKey]: next } : rest; } //#endregion export { sanitizeMessage as n, byteLength as t }; //# sourceMappingURL=sanitize-D9TujEK8.js.map