/** * `@ai-matrx/agents/sources` — THE ONE SOURCE PAYLOAD (contract v1, frozen 2026-09-27). * * Every request that is built from a person's Sources carries them as a * `SourceSet`: a list of `SourceRef` pointers (never blobs) plus how the model * should be grounded in them. The server answers with a `SourceManifest` * (sizes and states, never bodies — POST /sources/manifest) or a * `ResolvedSourceSet` (grounded text for generators — POST /sources/resolve). * * Contract of record: common-docs `projects/unified-source-input/DESIGN.md` * § "Contract v1 — FROZEN". A shape change here is an AMENDMENT there first, * with its Pydantic twin beside aidream's `parse_resource_reference`. * * `SourceRef` IS the existing `resource_ref` pointer already on the wire * (aidream `services/conversation_context/resource_context.py`), extended with * optional fields only — never coin a second pointer type. * * Pure module: no React, no I/O, no "use client". */ declare const RESOURCE_REF_KIND: "resource_ref"; declare const SOURCE_SET_KIND: "source_set"; declare const SOURCE_MANIFEST_KIND: "source_manifest"; declare const RESOLVED_SOURCE_SET_KIND: "resolved_source_set"; /** * The plain key naming a Sources envelope (`resource_ref` / `source_set` / `resolved_source_set`). * These are wire protocol, not content kinds (Content IR rule 28), so they never ride `__kind` * (REGISTER.md amendment A6, 2026-10-25). */ declare const ENVELOPE_KEY: "envelope"; /** The envelope a value names, read from `envelope` or the old `__kind` spelling; else undefined. */ declare function envelopeOf(value: unknown): string | undefined; /** The wire version every `SourceSet` carries. */ declare const SOURCE_SET_VERSION: 1; /** A bounded preview of one representation promoted into the prompt. */ interface ResourcePromotion { representation: string; max_chars?: number; } type SourceDelivery = "direct" | "context"; type SourceGrounding = "whole" | "selected" | "retrieve"; /** The pointer — the existing `resource_ref` envelope, extended (all new fields optional). */ interface SourceRef { envelope: typeof RESOURCE_REF_KIND; /** Server resource token: "file" (A2; "cld_file" is a server alias) | "processed_document" | "note" | "fc_set" | … */ resource_type: string; resource_id: string; /** "clean" | "raw" | "pdf" | a family representation key. Omitted = server's Clean → Raw → original fallback. */ representation?: string; /** Hand-picked Segment ids (rag.kg_chunks ids or ":"). */ include_segments?: string[]; /** Include the text (default "direct") | the AI fetches it on demand ("context"). */ delivery?: SourceDelivery; /** Per-Source cap chosen on the review page. */ max_chars?: number; promote?: ResourcePromotion | ResourcePromotion[]; exclude?: string[]; } /** * A TYPE, not an interface (2026-10-23): it IS a JSON object, so it is assignable wherever the server * contract types the field as a JSON object (@ai-matrx/api's request bodies carry `source_set` as * `{ [key: string]: JsonValue }` — the podcast generate request). An interface has no implicit index * signature and would need a cast at every send. */ type SourceSet = { envelope: typeof SOURCE_SET_KIND; version: typeof SOURCE_SET_VERSION; sources: SourceRef[]; /** Only for "Just a topic". */ topic?: string; /** Default "whole". */ grounding?: SourceGrounding; /** Required in spirit when grounding = "retrieve". */ retrieve_query?: string; /** The model whose context window sets the budget. */ target_model_id?: string; }; type SourceState = "ready" | "processing" | "failed" | "unavailable"; interface SourceManifestForm { form: string; label: string; chars: number; available: boolean; } interface SourceManifestSegment { id: string; /** "Page 7", "Pages 22–24" (a part spanning pages), "0:04–2:31", a heading path, "Part 3". */ label: string; page?: number; chars: number; /** * Amendment A5: the part's opening words (about 160 characters, whitespace * collapsed) — never its body. Lets a person see what a part says and find * a part by its words. */ preview?: string; } interface SourceManifestEntry { ref: SourceRef; label: string; resource_type: string; state: SourceState; state_detail?: string; /** Why it cannot be used — the same words as `DroppedSource.reason`; "archived" = show Restore. */ reason?: DroppedSourceReason | null; forms: SourceManifestForm[]; default_form: string; segments?: SourceManifestSegment[]; } /** POST /sources/manifest { source_set } → sizes and states, never bodies. */ interface SourceManifest { __kind: typeof SOURCE_MANIFEST_KIND; sources: SourceManifestEntry[]; total_chars: number; estimated_tokens: number; /** null = unknown model; the UI says so. */ model_context_tokens: number | null; } interface ResolvedSourceSegment { id: string; page?: number; chars: number; } interface ResolvedSource { ref: SourceRef; label: string; form_used: string; /** Grounded: "### Chunk (page N)" blocks; never re-chunked. */ text: string; segments: ResolvedSourceSegment[]; file_id?: string; processed_document_id?: string; /** "processing" = the raw fallback was used. */ state: "ready" | "processing"; truncated: boolean; /** Every stand-in announces itself. */ notes: string[]; } /** * A1 (2026-09-27): "not_ready" = a file not yet read. "archived" (2026-10-01) = the Source is * archived and this person may know it (its owner, or anyone who can read it anyway): restore it * to use it. Anyone else hears "no_access". One server rule for every kind (`archived_reason.py`). */ type DroppedSourceReason = "no_access" | "archived" | "missing" | "failed" | "over_budget" | "not_ready"; interface DroppedSource { ref: SourceRef; reason: DroppedSourceReason; /** A1: what happened and what to do. */ detail?: string; } /** POST /sources/resolve { source_set } → grounded text for generators. */ interface ResolvedSourceSet { envelope: typeof RESOLVED_SOURCE_SET_KIND; sources: ResolvedSource[]; dropped: DroppedSource[]; total_chars: number; } /** Builder options. `undefined` is accepted everywhere so callers can forward an existing ref's optional fields. */ interface SourceRefOptions { representation?: string | undefined; include_segments?: readonly string[] | undefined; delivery?: SourceDelivery | undefined; max_chars?: number | undefined; promote?: ResourcePromotion | ResourcePromotion[] | undefined; exclude?: readonly string[] | undefined; } /** * Build one pointer. Empty optional fields are omitted (so the wire stays * minimal and equal pointers serialise equally); `exclude` is trimmed, * lower-cased and de-duplicated exactly as the server normalizes it; * `include_segments` is de-duplicated in order. Throws on an empty type or id — * a pointer to nothing is never built silently. */ declare function createSourceRef(resourceType: string, resourceId: string, options?: SourceRefOptions): SourceRef; declare function isSourceRef(value: unknown): value is SourceRef; interface SourceSetOptions { topic?: string | undefined; grounding?: SourceGrounding | undefined; retrieve_query?: string | undefined; target_model_id?: string | undefined; } /** * Build one envelope. Duplicate pointers (same type + id + representation) are * collapsed, keeping the first. `grounding: "retrieve"` without a query and * `grounding: "selected"` with no Source carrying `include_segments` throw — * both would otherwise resolve to something the person never asked for. */ declare function createSourceSet(sources: readonly SourceRef[], options?: SourceSetOptions): SourceSet; /** Structural guard for a wire value claiming to be a v1 `SourceSet`. */ declare function isSourceSet(value: unknown): value is SourceSet; /** * Characters that will actually go in, computed from the Sources themselves * (never trusting a stale `total_chars`): * - `ResolvedSourceSet`: the sum of every resolved text's length. * - `SourceManifest`: per Source, the chosen form's size (the ref's * `representation`, else `default_form`), or the picked Segments' sizes when * `include_segments` is set, capped by the ref's `max_chars`. Sources whose * state is "failed" or "unavailable" contribute nothing — they cannot go in. */ declare function totalChars(value: SourceManifest | ResolvedSourceSet): number; export { ENVELOPE_KEY, RESOLVED_SOURCE_SET_KIND, RESOURCE_REF_KIND, SOURCE_MANIFEST_KIND, SOURCE_SET_KIND, SOURCE_SET_VERSION, createSourceRef, createSourceSet, envelopeOf, isSourceRef, isSourceSet, totalChars }; export type { DroppedSource, DroppedSourceReason, ResolvedSource, ResolvedSourceSegment, ResolvedSourceSet, ResourcePromotion, SourceDelivery, SourceGrounding, SourceManifest, SourceManifestEntry, SourceManifestForm, SourceManifestSegment, SourceRef, SourceRefOptions, SourceSet, SourceSetOptions, SourceState };