@sema-agent/core
Version:
Stateless, task-oriented AI agent core
51 lines (50 loc) • 1.84 kB
JavaScript
export const AGGREGATE_MEDIA_BUDGET_BYTES = 30 * 1024 * 1024;
const MEDIA_STRIPPED_MARKER = "[media removed to fit the request media budget — re-read the file if you still need to see it]";
function imageBytes(b) {
return typeof b.data === "string" ? Math.floor((b.data.length * 3) / 4) : 0;
}
function blocksOf(m) {
const content = m.content;
return Array.isArray(content) ? content : undefined;
}
export function capAggregateMediaBytes(messages, opts) {
const { limitBytes } = opts;
if (!Number.isFinite(limitBytes) || limitBytes <= 0)
return messages;
let total = 0;
for (const m of messages) {
const blocks = blocksOf(m);
if (blocks)
for (const b of blocks)
if (b.type === "image" || b.type === "document")
total += imageBytes(b);
}
if (total <= limitBytes)
return messages;
let remaining = total;
let removedBytes = 0;
let removedCount = 0;
const out = messages.slice();
for (let i = 0; i < out.length && remaining > limitBytes; i++) {
const blocks = blocksOf(out[i]);
if (!blocks)
continue;
let changed = false;
const next = blocks.map((b) => {
if (remaining > limitBytes && (b.type === "image" || b.type === "document")) {
const bytes = imageBytes(b);
remaining -= bytes;
removedBytes += bytes;
removedCount += 1;
changed = true;
return { type: "text", text: MEDIA_STRIPPED_MARKER };
}
return b;
});
if (changed)
out[i] = { ...out[i], content: next };
}
if (removedCount > 0)
opts.onStripped?.({ totalBytes: total, limitBytes, removedCount, removedBytes });
return out;
}