@sema-agent/core
Version:
Stateless, task-oriented AI agent core
52 lines (51 loc) • 2.59 kB
TypeScript
/**
* The ONE admission an image's bytes pass before they reach the model as an `ImageContent` block —
* whether a file supplied them (the Read tool's image lane) or a caller did (`TaskSpec.images`' inline
* arm). Four steps, in this order:
*
* ① the claimed type is one the content API accepts (png / jpeg / gif / webp — the four
* {@link imageMagicMatches} can verify);
* ② the raw bytes are within the read cap (5 MiB without a downsampler, 64 MiB with one);
* ③ the bytes carry the claimed type's signature — an empty / text / mis-named "png" would
* otherwise become a malformed block that 400s the NEXT whole provider request;
* ④ optional downsample (when a downsampler is supplied; a processing failure keeps the original
* bytes, CC's catch → createImageResponse(original)), then the provider's hard limit, which is on the
* BASE64 length, not raw bytes.
*
* The answer is structured; each carrier words its own refusal (the Read tool speaks to the model, the
* task door to the caller). The block it admits is built from the bytes it checked — never from a
* caller's string it did not decode.
*/
import type { ImageContent } from "../../internal/llm.js";
import { type ImageDimensions, type ImageDownsampler } from "../../core/mcp.js";
/** The image types the content API accepts — the only ones a signature check can verify. */
export declare const ADMITTED_IMAGE_MIME_TYPES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp"];
/** The raw-byte read cap for an image, with or without a downsampler. */
export declare function imageReadCap(downsampler: ImageDownsampler | undefined): number;
export type ImageAdmission = {
ok: true;
block: ImageContent;
/** The raw byte count of the bytes checked (before any downsample). */
originalSize: number;
/** Measured by the downsampler; absent without one (never fabricated). */
dimensions?: ImageDimensions;
/** True when the downsampler actually changed the pixel size. */
resized: boolean;
} | {
ok: false;
reason: "mime_unsupported" | "magic_mismatch";
rawBytes: number;
} | {
ok: false;
reason: "raw_too_large";
rawBytes: number;
cap: number;
}
/** `base64` is the encoding that failed the limit (the caller words the refusal from its length). */
| {
ok: false;
reason: "base64_too_large";
rawBytes: number;
base64: string;
};
export declare function admitImageBytes(bytes: Uint8Array, claimedMime: string, downsampler: ImageDownsampler | undefined): Promise<ImageAdmission>;