/** * Multimodal content-part builders for `task.start.input.content`. * * QAR accepts a user turn either as the flat `user_query` string OR as an * ordered list of discriminated `content` parts (text interleaved with inline * files) — never both. These helpers build the wire parts so consumers don't * hand-write the base64 encoding or the `type` discriminator: * * ```ts * import { QodoClient, textPart, filePart, imagePart } from '@qodo/sdk'; * * const stream = client.tasks.start({ * agent_id: 'reviewer', * input: { * content: [ * textPart('What does this screenshot show?'), * imagePart(pngBytes, { mediaType: 'image/png', filename: 'shot.png' }), * ], * }, * }); * ``` * * Provider-neutral by design: a file part carries its bytes + an explicit * `mediaType` and nothing else. The set of *accepted* media types and the * per-message size caps are an operator-owned policy the runtime enforces at * dispatch — deliberately kept off the wire schema and out of these bindings, * so the SDK never bakes one provider's limits into the contract. */ import type { FilePart, TaskInput, TextPart } from '../qar/payloads.js'; /** * Wire-schema cap on the TOTAL number of `content` parts (text + file) in a * single turn. Mirrors QAR's `qar.consts.MAX_CONTENT_PARTS` part-flood guard * (`Field(max_length=...)` on `QodoTaskStartPayload.content`). This is the * only count the SDK enforces pre-wire; the tighter, operator-tunable * per-message *file*-count cap is a server-side policy applied at dispatch. */ export declare const MAX_CONTENT_PARTS = 100; /** * Accepted raw inputs for a file part's bytes: * - `Uint8Array` (and therefore Node `Buffer`, which extends it), * - `ArrayBuffer`, * - a base64 `string` (no prefix), or * - a base64 `data:` URL (`data:;base64,`) — the * payload is extracted and the explicit `mediaType` option still wins. */ export type FileData = Uint8Array | ArrayBuffer | string; /** Options for {@link filePart} / {@link imagePart}. `mediaType` is required. */ export interface FilePartOptions { /** * IANA media type of the bytes (e.g. `'image/png'`, `'application/pdf'`). * Required and never inferred — even from a `data:` URL — so the wire part * is unambiguous. Which types the runtime accepts is its allowlist to * decide, not the SDK's. */ readonly mediaType: string; /** * Optional client metadata. Treated as sensitive downstream (kept out of * span attributes); never load-bearing. */ readonly filename?: string | null; } /** * Build a `text` content part. Order in the parent `content` array is * semantically meaningful — parts render in array order. */ export declare function textPart(text: string): TextPart; /** * Build a `file` content part from raw bytes, a base64 string, or a base64 * `data:` URL. Requires an explicit, non-empty `mediaType`; the bytes are * base64-encoded for the wire. One builder serves every file kind (image, * PDF, …) — the kind is carried by `mediaType`. * * Throws {@link QodoContentValidationError} when `mediaType` is empty, the * data is empty, or a string payload is not valid base64. */ export declare function filePart(data: FileData, options: FilePartOptions): FilePart; /** * Build a `file` content part for an image — a readability alias for * {@link filePart} (the wire shape is identical; the kind is carried by * `mediaType`). Requires an explicit image `mediaType` like * `'image/png'` / `'image/jpeg'`. */ export declare function imagePart(data: FileData, options: FilePartOptions): FilePart; /** * Assert that a `task.start.input` honors QAR's provider-neutral, * schema-level `content` invariants, throwing * {@link QodoContentValidationError} otherwise. Called pre-wire by * `tasks.start` / `tasks.startWithAgent` / `tasks.startWithGraph` / * `tasks.continue` (and `tasks.continueOrStart` transitively); exported so * consumers can run the same check off-band (CI lint, Studio preview). * * Enforces exactly what the wire schema mandates — `user_query` XOR * `content`, a non-empty `content` array when present, the * {@link MAX_CONTENT_PARTS} cap, and non-empty `media_type` / `data` on each * file part. It does NOT apply the operator-owned media-type allowlist or * size caps; those stay server-side by design. */ export declare function assertValidContentInput(input: TaskInput | null | undefined): void; //# sourceMappingURL=content.d.ts.map