import type { Message, MessageAttachment } from '../../types/message/index.js'; /** * Where an attachment's bytes live when the message does not carry them. * * Every attachment was inline base64 on the message. That is fine for one * screenshot and wrong for everything else it implies: the bytes are copied * into the turn's durable transcript, into every checkpoint, into every * compaction pass that walks the history, and — because a conversation * resends its history — into every subsequent request. A 4 MB PDF attached * once is 4 MB in the transcript and 4 MB on the wire per turn for the rest * of the turn. * * So a message may carry a REFERENCE instead. The kernel treats `ref` as * opaque: this seam says nothing about whether it is a hash, a path, or a * URL, because the store that minted it is the only thing that can answer. * A content-addressed store gets deduplication for free and this interface * neither requires nor prevents that. */ /** An attachment whose bytes are held by a store. */ export interface StoredAttachment { readonly type: 'stored'; /** * Opaque to the kernel, meaningful to the store that minted it. * * Never parsed here. A ref that the kernel could interpret is a ref the * kernel could construct, and a model-authored one would then be a path * into whatever the store can reach. */ readonly ref: string; /** * What the provider is told this is. * * Declared on the message rather than read from the store, because it * decides which content block gets built and that decision has to be * makeable without a round trip. `resolveAttachment` checks it against * what the store reports and refuses a mismatch. */ readonly mediaType: string; /** Which kind of block to build once the bytes arrive. */ readonly kind: 'image' | 'document'; /** Shown to the model, for a document it can refer to by name. */ readonly name?: string; /** See {@link DocumentAttachment.citations}. Ignored for an image. */ readonly citations?: boolean; } export interface StoredBytes { readonly data: string; readonly mediaType: string; } /** Authority owned by the public operation resolving stored bytes. */ export interface AttachmentOperationOptions { /** * A pre-aborted signal starts no store work. Implementations should use it * to stop their own I/O; the SDK also stops awaiting a store that ignores it. */ readonly signal?: AbortSignal; } /** Policy owned by the operation that materializes one or more references. */ export interface AttachmentResolutionOptions extends AttachmentOperationOptions { /** * Maximum wall-clock time for the complete materialization phase. * * Defaults to one minute. `0` retains the prior unbounded wait. The SDK * still races the wait itself, so a custom store cannot defeat this bound * by ignoring the signal it receives. */ readonly timeoutMs?: number; } /** One minute is long enough for remote stores without letting a turn wedge forever. */ export declare const DEFAULT_ATTACHMENT_RESOLVE_TIMEOUT_MS = 60000; export interface AttachmentStore { /** * Take bytes, return a ref. * * `mediaType` is stored alongside, so `get` can report what it holds and * a caller can be caught claiming something else. */ put(bytes: StoredBytes): Promise; /** `undefined` for a ref this store does not hold. */ get(ref: string, options?: AttachmentOperationOptions): Promise; } /** A reference nothing could resolve. */ export declare class AttachmentNotFoundError extends Error { readonly details: { ref: string; }; constructor(details: { ref: string; }); } /** A message that carries a ref, in a turn with nowhere to resolve it. */ export declare class NoAttachmentStoreError extends Error { readonly details: { ref: string; }; constructor(details: { ref: string; }); } /** A store whose bytes are not what the message said they were. */ export declare class AttachmentMediaTypeMismatchError extends Error { readonly details: { ref: string; declared: string; stored: string; }; constructor(details: { ref: string; declared: string; stored: string; }); } /** A store did not settle the materialization phase within its declared bound. */ export declare class AttachmentResolutionTimeoutError extends Error { readonly details: { timeoutMs: number; }; constructor(details: { timeoutMs: number; }); } export declare const isStoredAttachment: (attachment: MessageAttachment) => attachment is MessageAttachment & StoredAttachment; /** * Turn a stored attachment into an inline one, or refuse. * * Every failure here REFUSES rather than dropping the attachment. A message * that quietly lost its image is a model answering a question about a * picture it never saw, confidently, and nothing in the transcript says * why — the worst available outcome, and the reason none of these three * branches returns the message unchanged. */ export declare function resolveAttachment(attachment: MessageAttachment, store: AttachmentStore | undefined, options?: AttachmentResolutionOptions): Promise; /** * Resolve every stored attachment on every message. * * Returns the SAME array when nothing was stored, so the common case costs * one scan and no allocation — and so a caller cannot tell resolved * messages from unresolved ones by identity and get it wrong. */ export declare function resolveAttachments(messages: readonly Message[], store: AttachmentStore | undefined, options?: AttachmentResolutionOptions): Promise; //# sourceMappingURL=index.d.ts.map