{"version":3,"file":"chat_common-DKw8FDol.mjs","names":[],"sources":["../src/batteries/llm/chat_common/types.ts"],"sourcesContent":["/**\n * Wire-shape-agnostic TypeScript types shared across the Chat-family LLM batteries.\n *\n * @remarks\n * This module is INTERNAL to the bundled LLM batteries and is intentionally **not** tagged with\n * an `@module` JSDoc directive — `bin/utils/index.ts` `getEntries` only mints a public package\n * subpath for files that carry such a tag, so a tagless file stays private and is inlined into\n * each consumer by the bundler (the same way `src/lib/utils/retry.ts` is shared, minus the public\n * subpath). It holds the type aliases that the OpenAI Chat Completions battery and the native\n * Ollama battery both need: the validator-description envelope, the JSON Schema subset, the\n * trust-/memory-/retrievable-/thought-attribute envelopes, the system-prompt bucket ordering, the\n * function-tool wire shape, the unsupported-media policy, the retry config, and the\n * {@link ChatHelpersCommon} contract for the wire-shape-agnostic translation helpers.\n *\n * Battery-specific wire shapes (OpenAI Chat Completions message/chunk/response objects, the Ollama\n * native message/chunk objects) live in each battery's own `types.ts`, not here.\n */\n\nimport { v6 as uuidv6 } from 'uuid'\nimport type { ParsedToolCall } from './tool_parsers'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type {\n  Tokenizable,\n  Memory,\n  Thought,\n  Retrievable,\n  Tool,\n  ArtifactTool,\n  MediaKind,\n} from '@nhtio/adk/common'\n\n// ─── DescriptionLike (validator description envelope) ─────────────────────────\n\n/**\n * Structural shape of a validator/Joi `describe()` output, as consumed by the JSON-Schema\n * renderer. A loose superset — only the fields the renderer reads are typed; the index signature\n * carries everything else through untouched.\n */\nexport interface DescriptionLike {\n  /** Validator type name (e.g. `'string'`, `'object'`, `'array'`). */\n  type?: string\n  /** Human-readable description of the field. */\n  description?: string\n  /** Presence flag (`'optional'`, `'required'`, or `'forbidden'`) at the top level. */\n  presence?: string\n  /** Default value supplied when the field is absent. */\n  default?: unknown\n  /** Permitted values declared via an enum/valid set. */\n  enum?: unknown[]\n  /** Permitted values declared via the validator's `valid()` rule. */\n  valids?: unknown[]\n  /** Example values for the field. */\n  examples?: unknown[]\n  /** Nested property descriptions, keyed by property name (for object types). */\n  properties?: Record<string, DescriptionLike>\n  /** Element description(s) for array types. */\n  items?: DescriptionLike | DescriptionLike[]\n  /** Names of required properties (for object types). */\n  required?: string[]\n  /** Validator flags bag carrying presence, description, and default. */\n  flags?: { presence?: string; description?: string; default?: unknown }\n  /** Pass-through for any other validator metadata the renderer does not read. */\n  [key: string]: unknown\n}\n\n// ─── JSON Schema (Chat-Completions-compatible subset) ─────────────────────────\n\n/**\n * The subset of JSON Schema that Chat-family tool/function `parameters` accept, as emitted by\n * {@link ChatHelpersCommon.descriptionToChatCompletionsJsonSchema}. The index signature allows\n * extra keywords to pass through to the wire.\n */\nexport interface JsonSchema {\n  /** JSON Schema primitive/compound type. */\n  type?: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null'\n  /** Human-readable description of the schema node. */\n  description?: string\n  /** Permitted values for the node. */\n  enum?: unknown[]\n  /** Default value for the node. */\n  default?: unknown\n  /** Example values for the node. */\n  examples?: unknown[]\n  /** Property schemas keyed by property name (for `object` types). */\n  properties?: Record<string, JsonSchema>\n  /** Names of required properties (for `object` types). */\n  required?: string[]\n  /** Element schema(s) for `array` types. */\n  items?: JsonSchema | JsonSchema[]\n  /** Whether (or what schema) additional, undeclared properties are permitted. */\n  additionalProperties?: boolean | JsonSchema\n  /** Pass-through for any other JSON Schema keyword. */\n  [key: string]: unknown\n}\n\n// ─── Helper-attribute envelopes ───────────────────────────────────────────────\n\n/**\n * Attribute bag rendered onto the trust envelope that wraps untrusted (third-party) content.\n */\nexport interface UntrustedContentAttrs {\n  /**\n   * Nonce binding the envelope's open and close markers together — it becomes part of the tag NAME\n   * (`<..._<nonce>>`) so a model mirroring the fence cannot forge a sibling's closer.\n   *\n   * FOOTGUN: this nonce MUST be unguessable AND non-path-shaped. It is typically the source record's id; a\n   * path-shaped id (e.g. `chunk-assembly-events-9`) is copied by small models as a CITATION\n   * (`/assembly/events-9`), which a doc-path validator then rejects → re-cite loop. Mint record ids with\n   * `crypto.randomUUID()`; carry page/human provenance in `source=` (rendered before `nonce=`), never in the id.\n   */\n  nonce: string\n  /** Content classifier rendered on the envelope. */\n  kind: string\n  /** Name of the tool that produced the content, when applicable. */\n  tool?: string\n  /**\n   * When wrapping a {@link @nhtio/adk!Media}-derived text marker, the modality hazard axis derived from\n   * `media.modalityHazard`: `'inert'`, `'extractable'` (from `'extractable-instructions'`), or\n   * `'opaque'` (from `'opaque-perceptual'`). Omitted for non-media envelopes.\n   */\n  modality?: 'inert' | 'extractable' | 'opaque'\n}\n\n/**\n * Attribute bag rendered onto the trust envelope that wraps trusted (first-party) content.\n */\nexport interface TrustedContentAttrs {\n  /**\n   * Nonce binding the envelope's open and close markers together — it becomes part of the tag NAME\n   * (`<..._<nonce>>`) so a model mirroring the fence cannot forge a sibling's closer.\n   *\n   * FOOTGUN: this nonce MUST be unguessable AND non-path-shaped. It is typically the source record's id; a\n   * path-shaped id (e.g. `chunk-assembly-events-9`) is copied by small models as a CITATION\n   * (`/assembly/events-9`), which a doc-path validator then rejects → re-cite loop. Mint record ids with\n   * `crypto.randomUUID()`; carry page/human provenance in `source=` (rendered before `nonce=`), never in the id.\n   */\n  nonce: string\n  /** Content classifier rendered on the envelope. */\n  kind: string\n  /** Name of the tool that produced the content, when applicable. */\n  tool?: string\n  /**\n   * Same semantics as {@link UntrustedContentAttrs.modality}.\n   */\n  modality?: 'inert' | 'extractable' | 'opaque'\n}\n\n/**\n * Attribute bag rendered onto a standing-instruction block.\n */\nexport interface StandingInstructionAttrs {\n  /** Optional version label for the standing instruction. */\n  version?: string\n}\n\n/**\n * Attribute bag rendered onto a memory block.\n */\nexport interface MemoryAttrs {\n  /**\n   * Nonce binding the block's open and close markers together — it becomes part of the tag NAME\n   * (`<..._<nonce>>`) so a model mirroring the block cannot forge a sibling's closer.\n   *\n   * FOOTGUN: this nonce MUST be unguessable AND non-path-shaped. It is typically the source record's id; a\n   * path-shaped id (e.g. `chunk-assembly-events-9`) is copied by small models as a CITATION\n   * (`/assembly/events-9`), which a doc-path validator then rejects → re-cite loop. Mint record ids with\n   * `crypto.randomUUID()`; carry page/human provenance in `source=` (rendered before `nonce=`), never in the id.\n   */\n  nonce: string\n  /** Origin of the memory (e.g. the producing subsystem). */\n  source?: string\n  /** ISO-8601 creation timestamp of the memory. */\n  createdAt?: string\n  /** Memory classifier. */\n  kind?: string\n  /** Relevance/recall score, when the memory was retrieved by similarity. */\n  score?: number\n}\n\n/**\n * Attribute bag rendered onto a retrievable block.\n */\nexport interface RetrievableAttrs {\n  /**\n   * Nonce binding the block's open and close markers together — it becomes part of the tag NAME\n   * (`<..._<nonce>>`) so a model mirroring the block cannot forge a sibling's closer.\n   *\n   * FOOTGUN: this nonce MUST be unguessable AND non-path-shaped. It is typically the source record's id; a\n   * path-shaped id (e.g. `chunk-assembly-events-9`) is copied by small models as a CITATION\n   * (`/assembly/events-9`), which a doc-path validator then rejects → re-cite loop. Mint record ids with\n   * `crypto.randomUUID()`; carry page/human provenance in `source=` (rendered before `nonce=`), never in the id.\n   */\n  nonce: string\n  /** Origin of the retrievable (e.g. the source document or system). */\n  source?: string\n  /** ISO-8601 creation timestamp of the retrievable. */\n  createdAt?: string\n  /** Retrievable classifier. */\n  kind?: string\n  /** Relevance score from the retrieval query. */\n  score?: number\n}\n\n/**\n * Attribute bag rendered onto a thought block.\n */\nexport interface ThoughtAttrs {\n  /**\n   * Nonce binding the block's open and close markers together — it becomes part of the tag NAME\n   * (`<..._<nonce>>`) so a model mirroring the block cannot forge a sibling's closer.\n   *\n   * FOOTGUN: this nonce MUST be unguessable AND non-path-shaped. It is typically the source record's id; a\n   * path-shaped id (e.g. `chunk-assembly-events-9`) is copied by small models as a CITATION\n   * (`/assembly/events-9`), which a doc-path validator then rejects → re-cite loop. Mint record ids with\n   * `crypto.randomUUID()`; carry page/human provenance in `source=` (rendered before `nonce=`), never in the id.\n   */\n  nonce: string\n  /** Whether the thought is the model's own, a peer's, or opaque vendor reasoning. */\n  kind: 'self-reasoning' | 'peer-reasoning' | 'opaque-reasoning'\n  /** Identity of the agent the thought originated from. */\n  from: string\n  /** ISO-8601 creation timestamp of the thought. */\n  createdAt?: string\n  /** Replay-compatibility label gating whether the thought is surfaced on replay. */\n  replayCompatibility?: string\n}\n\n// ─── Bucket order ─────────────────────────────────────────────────────────────\n\n/**\n * Name of a system-prompt content bucket whose render order is configurable.\n */\nexport type ChatCompletionsBucketLabel =\n  | 'standingInstructions'\n  | 'memories'\n  | 'retrievables'\n  | 'timeline'\n\n/**\n * Ordered list of {@link ChatCompletionsBucketLabel}s controlling the sequence in which content\n * buckets are assembled into the prompt.\n */\nexport type ChatCompletionsBucketOrder = ReadonlyArray<ChatCompletionsBucketLabel>\n\n// ─── Function-tool wire shape (identical for OpenAI Chat Completions and Ollama) ──\n\n/**\n * Wire shape of a single function tool advertised to the model — identical for OpenAI Chat\n * Completions and Ollama.\n */\nexport interface ChatCompletionsTool {\n  /** Tool kind; always `'function'` for the bundled batteries. */\n  type: 'function'\n  /** The function declaration: its name, description, and JSON-Schema parameters. */\n  function: {\n    name: string\n    description?: string\n    parameters?: JsonSchema\n  }\n}\n\n// ─── Unsupported-media policy ─────────────────────────────────────────────────\n\n/**\n * Policy for how a Chat-family battery handles a {@link @nhtio/adk!Media} instance whose modality the\n * wire protocol cannot natively represent.\n *\n * @remarks\n * The option SHAPE is shared; each battery decides which modalities count as \"unsupported\"\n * (OpenAI Chat Completions: video; Ollama native `/api/chat`: everything except image). Three\n * modes:\n *\n * - `'throw'` — raise the battery's unsupported-media exception and fail the dispatch. Loud\n *   failure; the default, so a misconfigured pipeline surfaces immediately.\n * - `'fallback-stash'` — look for a model-readable text entry in `media.stash`. If present, render\n *   that text inside the appropriate trust envelope in lieu of a media block. If no entry is found,\n *   fall through to `'synthetic-description'` behaviour. The shorthand string form uses the\n *   battery's default key list (`['text:transcript', 'text:caption', 'text:description']`, walked\n *   in order). The object form `{ mode: 'fallback-stash'; stashKeys }` overrides the key list.\n * - `'synthetic-description'` — always render a synthetic text description constructed from\n *   `filename`, `byteLength`, and `mimeType` regardless of `stash` presence.\n */\nexport type UnsupportedMediaPolicy =\n  | 'throw'\n  | 'fallback-stash'\n  | 'synthetic-description'\n  | { mode: 'fallback-stash'; stashKeys: ReadonlyArray<string> }\n\n// ─── Media OUTPUT (generated media surfaced as assistant attachments) ─────────\n\n/**\n * One piece of media a model GENERATED as turn output — the descriptor a\n * {@link MediaOutputExtractorFn} returns for the adapter to persist + attach to the assistant\n * {@link @nhtio/adk!Message}.\n *\n * @remarks\n * The LLM batteries are multimodal-IN, text-OUT by default: the tested open-weight chat checkpoints\n * emit only text, so no media output is produced unless a consumer wraps a media-emitting model AND\n * supplies an extractor. The framework contract already supports the output direction —\n * `Message.attachments` is symmetric across roles and `ctx.storeMediaBytes` persists generated bytes —\n * so this descriptor is all the adapter needs: it calls `storeMediaBytes` with `bytes`, builds a\n * `Media.toolGenerated({ kind, mimeType, filename, reader })` from the returned reader, and attaches it.\n */\nexport interface GeneratedMediaOutput {\n  /** Media modality (`'image'`/`'audio'`/`'video'`/`'document'`). */\n  kind: MediaKind\n  /** Concrete MIME type of the generated bytes (e.g. `'audio/wav'`, `'image/png'`). */\n  mimeType: string\n  /** The generated media bytes. */\n  bytes: Uint8Array\n  /** Optional filename for the attachment; the adapter supplies a default when omitted. */\n  filename?: string\n}\n\n/**\n * Extracts generated media from a battery's raw generation result so the adapter can surface it as\n * assistant `Message.attachments`. Injectable + defaulted to absent (no media output) on every LLM\n * battery, mirroring the `toolCallParser` / `reasoningParser` / `decodeMedia` injection seams.\n *\n * @remarks\n * `result` is the battery-native generation object (transformers.js `model.generate` / pipeline output;\n * the LiteRT-LM final `Message` + raw content items) — deliberately typed `unknown` because its shape is\n * battery-specific and the extractor is supplied by whoever wraps a media-emitting model. Returning an\n * empty array (or not supplying the hook) yields today's text-only behavior, byte-for-byte unchanged.\n */\nexport type MediaOutputExtractorFn = (\n  result: unknown\n) => GeneratedMediaOutput[] | Promise<GeneratedMediaOutput[]>\n\n// ─── Raw generation observability (the model's text BEFORE parsing) ───────────\n\n/**\n * One observation of a battery's raw model output for a single completed generation, fired the instant\n * the full text is in hand — AFTER envelope-token stripping + reasoning/tool-call parsing, but BEFORE\n * the parsed result is persisted. The whole point is to expose the gap between what the model literally\n * emitted (`rawText`) and what the battery managed to extract (`cleanedText` / `toolCalls` /\n * `reasoning`): when a small on-device model emits a tool call in a shape no parser matches, the call\n * silently leaks into `cleanedText` as prose, and this is the ONLY seam where that is visible.\n *\n * @remarks\n * This is a pure observability tap — it returns `void`, never mutates the result, and never throws into\n * the generation path (the adapter swallows callback errors). It fires once per terminal generation\n * (one per non-streamed turn; one per stream at stream end), for BOTH the transformers.js and LiteRT-LM\n * on-device batteries, at the identical point in each. Use it for parser bring-up against a new model,\n * live debugging (\"why did the agent abstain?\"), or capturing ground-truth fixtures — exactly the job\n * that previously required patching a temporary hook into the adapter.\n */\nexport interface RawGenerationObservation {\n  /**\n   * The model's complete decoded output for this generation, with non-semantic envelope/turn-boundary\n   * special tokens already stripped (the same text handed to the parsers) — i.e. what the parsers\n   * actually saw. This is the field to inspect when a tool call did not parse.\n   */\n  rawText: string\n  /**\n   * The residual prose after reasoning + tool-call extraction — what becomes the assistant message\n   * `content`. If a tool call failed to parse, its source text is still here (the leak).\n   */\n  cleanedText: string\n  /** The reasoning/thinking traces the reasoning parser extracted (empty when none / not applicable). */\n  reasoning: ReadonlyArray<string>\n  /** The tool calls the tool-call parser extracted (empty when the model emitted none, or none parsed). */\n  toolCalls: ReadonlyArray<ParsedToolCall>\n  /** Whether this generation streamed its prose to the consumer (vs. a single batch decode). */\n  streamed: boolean\n  /** The adapter's stream/message id for this generation, for correlating with other telemetry. */\n  streamId: string\n}\n\n/**\n * Observe a battery's raw model output for one completed generation. Injectable + defaulted to absent\n * on the on-device LLM batteries (transformers.js, LiteRT-LM), mirroring the `toolCallParser` /\n * `reasoningParser` / `extractMediaOutputs` injection seams. Fired once per terminal generation, after\n * parsing and before persistence; purely observational (return value ignored, errors swallowed).\n */\nexport type RawGenerationObserverFn = (observation: RawGenerationObservation) => void\n\n// ─── Prompt observability (the exact request BEFORE it is dispatched) ──────────\n\n/**\n * One observation of the fully-assembled request a battery is about to send TO the model, fired the\n * instant assembly completes and BEFORE the engine/HTTP dispatch. It is the mirror of\n * {@link RawGenerationObservation}: that seam exposes the raw text coming back FROM the model; this one\n * exposes the raw request going TO it. Together they let you read ground truth at both ends of the wire —\n * e.g. to settle whether a \"smart quote\" in a rendered answer came from the model itself or from a\n * downstream markdown renderer, you inspect the bytes here, not the DOM.\n *\n * @remarks\n * This is a pure observability tap — it returns `void`, never mutates the request, and never throws into\n * the generation path (the adapter swallows callback errors). It fires once per terminal generation\n * (one per non-streamed turn; one per stream, at dispatch), across ALL five LLM batteries.\n *\n * **Handed back AS-IS — no redaction.** The observation carries the request exactly as assembled. The ADK\n * does not scrub credentials, headers, or any other field for you: what you put on the request is what you\n * see here, and if you route this to a persistent sink (a log, `localStorage`, a file) you may persist\n * secrets that rode the request (an `apiKey`, `Authorization` header, etc.). That is your responsibility to\n * handle, not the battery's — the ADK surfaces the truth and lets you decide what to do with it. (In\n * practice the API batteries strip ADK-control keys like `apiKey` out of the wire body before this fires,\n * but that is incidental to how the body is built, not a guarantee.)\n */\nexport interface PromptAssembledObservation {\n  /** Which battery assembled this request (e.g. `'litert_lm'`, `'openai_chat_completions'`). */\n  battery: string\n  /**\n   * The shape of the assembled request. `'rendered-prompt'` for the on-device batteries (transformers.js,\n   * LiteRT-LM), which render a preface string + a messages array for the engine; `'request-body'` for the\n   * API batteries (OpenAI-compatible, Ollama, WebLLM), which POST a JSON body.\n   */\n  kind: 'rendered-prompt' | 'request-body'\n  /**\n   * On-device leading/system content rendered ahead of the timeline (e.g. the LiteRT `preface` object,\n   * which carries the assembled system message text and — for native tool delivery — the tool list), when\n   * applicable. Its concrete shape is battery-specific; captured verbatim. Absent for the API batteries.\n   */\n  preface?: unknown\n  /**\n   * The per-turn messages exactly as handed to the engine (on-device) or placed on the wire (API): the\n   * engine's message array, or the request body's `messages`.\n   */\n  messages: unknown\n  /**\n   * The tool declarations exactly as dispatched: the rendered `<tool_definitions>` prompt text (on-device\n   * prompt-delivery) or the wire `tools` array (API / native tool delivery). Absent when no tools are sent.\n   */\n  tools?: unknown\n  /**\n   * API batteries only: the complete assembled request body, exactly as it will be sent (see the AS-IS /\n   * no-redaction note above). Absent for the on-device batteries.\n   */\n  requestBody?: unknown\n  /** Whether this generation streams its response (vs. a single batch call). */\n  streamed: boolean\n  /** The adapter's stream/message id for this generation, for correlating with other telemetry. */\n  streamId: string\n}\n\n/**\n * Observe the fully-assembled request a battery is about to dispatch. Injectable + defaulted to absent on\n * every LLM battery, mirroring {@link RawGenerationObserverFn}. Fired once per terminal generation, after\n * assembly and before dispatch; purely observational (return value ignored, errors swallowed). The request\n * is handed back AS-IS — see {@link PromptAssembledObservation} for the no-redaction contract.\n */\nexport type PromptAssembledObserverFn = (observation: PromptAssembledObservation) => void\n\n// ─── Tool-call id ingress ─────────────────────────────────────────────────────\n\n/**\n * Shapes a provider-supplied tool-call id at adapter ingress, before the call is stored or used for\n * spool/result correlation. This hook exists to prevent the concrete failure seen with grok-4.3 on\n * Bedrock Mantle, which repeats `call_0` across tool-calling turns. Default absent = identity, so\n * adapters retain today's behaviour unless a consumer opts in.\n *\n * @remarks\n * `#doStoreToolCall` adds to `turnToolCalls` synchronously before its await, and adoption is a\n * sequential loop, so each call sees every prior call — including same-response siblings. A correctly\n * numbered parallel batch (`call_0`..`call_3`) is therefore safe because those ids are already\n * DISTINCT, not because the siblings are unstored. A genuine same-response duplicate IS de-collided,\n * which is intentional.\n */\nexport type ToolCallIdFilterFn = (id: string, ctx: DispatchContext) => string\n\n/**\n * De-collides a provider-supplied tool-call id against calls already adopted in this dispatch. It\n * prevents the concrete `call_0`-repeated-across-turns failure seen with grok-4.3 on Bedrock Mantle.\n * Default absent = identity; this implementation returns the original id when no collision exists.\n *\n * @remarks\n * `#doStoreToolCall` adds to `turnToolCalls` synchronously before its await, and adoption is a\n * sequential loop, so each call sees every prior call — including same-response siblings. A correctly\n * numbered parallel batch (`call_0`..`call_3`) passes through because those ids are already DISTINCT,\n * not because the siblings are unstored. A genuine same-response duplicate is de-collided, as intended.\n */\nexport const deCollideToolCallIds: ToolCallIdFilterFn = (id, ctx) =>\n  [...ctx.turnToolCalls].some((tc) => tc.id === id) ? uuidv6() : id\n\n// ─── Retry config ─────────────────────────────────────────────────────────────\n\n/**\n * Retry/backoff configuration for a Chat-family battery's HTTP requests.\n */\nexport interface ChatCompletionsRetryConfig {\n  /** Maximum number of attempts (including the first) before giving up. */\n  maxAttempts?: number\n  /** Base delay in milliseconds for the first retry; doubles each attempt. */\n  baseDelayMs?: number\n  /** Upper bound in milliseconds on any single backoff delay. */\n  maxDelayMs?: number\n  /** HTTP status codes that trigger a retry. */\n  retriableStatuses?: number[]\n  /** Whether to honour a server `Retry-After` header in place of computed backoff. */\n  honorRetryAfter?: boolean\n}\n\n// ─── Shared helper contract (wire-shape-agnostic members) ─────────────────────\n\n/**\n * The wire-shape-agnostic subset of a Chat-family battery's translation helpers — every helper\n * that produces a plain `string` (or JSON Schema / tool-definition wire, which is identical across\n * the family) rather than a battery-specific message object.\n *\n * @remarks\n * Both `ChatCompletionsHelpers` (OpenAI battery) and `OllamaHelpers` (Ollama battery) extend this\n * contract and add their own wire-specific members (timeline-message rendering, tool-call-result\n * rendering, history assembly, and — for OpenAI — streaming tool-call delta accumulation). Helpers\n * that compose other helpers receive their dependents via explicit `deps` arguments typed against\n * THIS contract (never against a battery-specific bag), so the shared implementations carry no\n * import edge back to any individual battery.\n */\nexport interface ChatHelpersCommon {\n  /** Converts a validator `describe()` envelope into the Chat-Completions JSON-Schema subset. */\n  descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema\n  /** Wraps untrusted (third-party) text in the untrusted-content trust envelope. */\n  renderUntrustedContent: (content: string, attrs: UntrustedContentAttrs) => string\n  /** Wraps trusted (first-party) text in the trusted-content trust envelope. */\n  renderTrustedContent: (content: string, attrs: TrustedContentAttrs) => string\n  /** Renders standing instructions into a single prompt block. */\n  renderStandingInstructions: (\n    items: Iterable<Tokenizable>,\n    attrs?: StandingInstructionAttrs\n  ) => string\n  /** Renders memories (each with its attribute bag) into a single prompt block. */\n  renderMemories: (items: Iterable<{ memory: Memory; attrs: MemoryAttrs }>) => string\n  /** Renders the safety directive that precedes any retrievable content. */\n  renderRetrievableSafetyDirective: () => string\n  /** Renders first-party (trusted) retrievables into a single prompt block. */\n  renderFirstPartyRetrievables: (\n    items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs }>,\n    renderRetrievableHandleBody?: ChatHelpersCommon['renderRetrievableHandleBody']\n  ) => Promise<string>\n  /** Renders third-party public retrievables, wrapping each in the untrusted-content envelope. */\n  renderThirdPartyPublicRetrievables: (\n    items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs }>,\n    deps: {\n      renderUntrustedContent: ChatHelpersCommon['renderUntrustedContent']\n      renderRetrievableHandleBody?: ChatHelpersCommon['renderRetrievableHandleBody']\n    }\n  ) => Promise<string>\n  /** Renders third-party private retrievables, wrapping each in the untrusted-content envelope. */\n  renderThirdPartyPrivateRetrievables: (\n    items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs }>,\n    deps: {\n      renderUntrustedContent: ChatHelpersCommon['renderUntrustedContent']\n      renderRetrievableHandleBody?: ChatHelpersCommon['renderRetrievableHandleBody']\n    }\n  ) => Promise<string>\n  /** Assembles the full retrievables block: safety directive plus the trust-tiered sub-renderers. */\n  renderRetrievables: (\n    items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs }>,\n    deps: {\n      renderRetrievableSafetyDirective: ChatHelpersCommon['renderRetrievableSafetyDirective']\n      renderFirstPartyRetrievables: ChatHelpersCommon['renderFirstPartyRetrievables']\n      renderThirdPartyPublicRetrievables: ChatHelpersCommon['renderThirdPartyPublicRetrievables']\n      renderThirdPartyPrivateRetrievables: ChatHelpersCommon['renderThirdPartyPrivateRetrievables']\n      renderUntrustedContent: ChatHelpersCommon['renderUntrustedContent']\n      renderRetrievableHandleBody?: ChatHelpersCommon['renderRetrievableHandleBody']\n    }\n  ) => Promise<string>\n  /**\n   * Renders the directions-bearing \"handle\" body for a non-inlined {@link @nhtio/adk!SpooledArtifact}\n   * tool result: metadata (callId/kind/byteLength/lineCount) plus the forged `artifact_*` tools the\n   * model should call to read it incrementally.\n   *\n   * @remarks\n   * Optional override seam. When omitted the battery uses the shared\n   * {@link defaultRenderArtifactHandleBody}. A consumer overrides it to change WHICH reader the model\n   * is steered toward first — e.g. promoting the JSON content-readers (`artifact_json_get` /\n   * `artifact_json_keys`) ahead of the metadata-only `artifact_json_type` for a small model that grabs\n   * the first listed tool. The tool list itself comes from the artifact's `constructor.toolMethods`;\n   * an override typically reorders or re-annotates that list before delegating to the default renderer.\n   */\n  renderArtifactHandleBody?: (input: {\n    callId: string\n    artifact: unknown\n    byteLength: number\n    lineCount: number\n    estimatedTokens?: number\n    encoding?: string\n  }) => string\n  /**\n   * Renders the directions-bearing \"handle\" body for a non-inlined {@link @nhtio/adk!Retrievable}\n   * whose content is a {@link @nhtio/adk!SpooledArtifact}: metadata (callId/kind/byteLength/lineCount)\n   * plus the forged `artifact_*` tools the model should call to read it incrementally.\n   *\n   * @remarks\n   * Optional override seam, the retrievable-side counterpart to {@link renderArtifactHandleBody}.\n   * When omitted the battery uses the shared {@link defaultRenderRetrievableHandleBody}.\n   */\n  renderRetrievableHandleBody?: (input: {\n    callId: string\n    artifact: unknown\n    byteLength: number\n    lineCount: number\n    estimatedTokens?: number\n    encoding?: string\n  }) => string\n  /** Renders a single thought into its prompt block, optionally carrying an opaque replay payload. */\n  renderThought: (content: string, attrs: ThoughtAttrs, payload?: unknown) => string\n  /** Selects which thoughts to surface, by surfacing mode, self identity, and replay compatibility. */\n  filterThoughts: (\n    thoughts: Iterable<Thought>,\n    mode: 'all-self' | 'latest-self' | 'all',\n    selfIdentity: string,\n    replayCompatibility: ReadonlyArray<string>\n  ) => Thought[]\n  /** Translates the tool registry into the function-tool wire array advertised to the model. */\n  toolsToChatCompletionsTools: (\n    tools: ReadonlyArray<Tool | ArtifactTool>,\n    deps: { descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema }\n  ) => ChatCompletionsTool[]\n  /** Assembles the system-prompt message from its constituent buckets in {@link ChatCompletionsBucketOrder}. */\n  renderChatCompletionsSystemPrompt: (input: {\n    systemPrompt: Tokenizable\n    /**\n     * Live dispatch context for resolving a DYNAMIC {@link Tokenizable} `systemPrompt` via\n     * `.render(ctx)`. Optional; a static `systemPrompt` ignores it. The real implementation\n     * (`chat_common/helpers.ts`) already accepts and forwards this — declared here so the type\n     * matches what the function actually does.\n     */\n    renderCtx?: unknown\n    standingInstructions: Iterable<Tokenizable>\n    memories: Iterable<Memory>\n    retrievables: Iterable<Retrievable>\n    bucketOrder: ChatCompletionsBucketOrder\n    renderStandingInstructions: ChatHelpersCommon['renderStandingInstructions']\n    renderMemories: ChatHelpersCommon['renderMemories']\n    renderRetrievables: ChatHelpersCommon['renderRetrievables']\n    renderRetrievableHandleBody?: ChatHelpersCommon['renderRetrievableHandleBody']\n    renderRetrievableSafetyDirective: ChatHelpersCommon['renderRetrievableSafetyDirective']\n    renderFirstPartyRetrievables: ChatHelpersCommon['renderFirstPartyRetrievables']\n    renderThirdPartyPublicRetrievables: ChatHelpersCommon['renderThirdPartyPublicRetrievables']\n    renderThirdPartyPrivateRetrievables: ChatHelpersCommon['renderThirdPartyPrivateRetrievables']\n    renderUntrustedContent: ChatHelpersCommon['renderUntrustedContent']\n  }) => Promise<string>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwdA,IAAa,wBAA4C,IAAI,QAC3D,CAAC,GAAG,IAAI,aAAa,EAAE,MAAM,OAAO,GAAG,OAAO,EAAE,IAAI,GAAO,IAAI"}