/** * Wire-shape-agnostic translation helpers shared across the Chat-family LLM batteries. * * @remarks * INTERNAL to the bundled LLM batteries — intentionally **not** `@module`-tagged, so it stays a * private, inlined module (see the note in `./types`). These helpers turn ADK primitives into * plain strings (or the family-identical JSON Schema / function-tool wire), independent of any * single battery's message-object shape. The OpenAI Chat Completions battery and the native Ollama * battery both re-export every name here from their own `helpers.ts` barrels (each under its * unprefixed name AND a `default*` alias) so consumer override composition is unchanged. * * Helpers that compose other helpers receive their dependents via explicit `deps` arguments typed * against {@link ChatHelpersCommon} — never against a battery-specific helper bag — so this module * carries no import edge back to any individual battery. */ import type { Tool, ArtifactTool, Tokenizable, Memory, Thought, Retrievable } from "../../../common"; import type { ChatCompletionsBucketOrder, ChatCompletionsTool, DescriptionLike, JsonSchema, MemoryAttrs, RetrievableAttrs, StandingInstructionAttrs, ThoughtAttrs, TrustedContentAttrs, UntrustedContentAttrs, ChatHelpersCommon } from "./types"; export declare const escapeXmlAttribute: (value: string) => string; /** * Substitute a placeholder for an empty tool-call name. * * @remarks * `ToolCall.tool` is validated by a bare `validator.string().required()`, which — like the rest of * this validator family — rejects the empty string, not just `undefined`/`null`. Every adapter's * "tool not found" / "malformed args" fallback branches exist specifically to survive a bad * `call.name` from the model, but they construct their error-carrying `ToolCall` from `call.name` * unguarded — so the one input those branches exist to handle gracefully (a hallucinated tool call * with an empty name) crashes them instead. Call this at every such construction site so the * degenerate case reports a name-shaped placeholder rather than throwing * `E_INVALID_INITIAL_TOOL_CALL_VALUE` from inside the recovery path itself. */ export declare const normalizeToolName: (name: string) => string; /** * Neutralise the **no-nonce** `` / `` developer-rules tier * if it appears inside model- or user-supplied BODY content. * * @remarks * Every other trust tier (untrusted/trusted/peer/thought/memory/retrieved) carries an unguessable * per-primitive nonce in its tag name, so a model that mirrors one cannot forge a sibling's closer. The * standing-instructions tier is the lone exception — {@link renderStandingInstructions} emits it WITHOUT * a nonce because it is the highest-authority block. That makes a model-mirrored copy textually * identical to the real tier. The legitimate tier is ALWAYS harness-injected (built by * `renderStandingInstructions` and concatenated into the system prompt) and never flows through a * message/thought body — so escaping the leading `<` of the literal token wherever it occurs in body * content is always safe and renders the copy inert (visible, but unmistakably not a structural tag). * Mirrors how the nonce already neutralises the other tiers. See the envelope-mimicry threat model. */ export declare const neutraliseDeveloperRulesTag: (text: string) => string; /** * Strip the non-semantic envelope/turn-boundary special tokens (see {@link ENVELOPE_SPECIAL_TOKEN_RE}) * from decoded model text before it reaches the parser layer. * * @remarks * **Why this exists.** The transformers.js streaming path decodes with `skip_special_tokens:false` (it * must — the live prose-stop gate watches for tool/think markers, which ARE special tokens). That leaves * envelope tokens like Llama's `<|python_tag|>{json}<|eom_id|>` or ChatML's trailing `<|im_end|>` in the * accumulated text, so the JSON tool-call parsers see `<|python_tag|>{…}` and decline — even though the * NON-streaming path (which decodes with `skip_special_tokens:true`) parses the identical call fine. * Normalising here makes the stream and batch paths parse equivalent text. Surfaced by the deep model * matrix (Llama-3.2-1B + Qwen2.5-Coder tool calls passed on batch, failed on stream). */ export declare const stripEnvelopeSpecialTokens: (text: string) => string; /** * Validate a media `mimeType` for safe interpolation into a `data:;base64,…` URI, a * `Blob({type})`, or a synthetic-description line. * * @remarks * A raw `mimeType` is attacker-influenced (it rides in on user uploads / tool output). The committee's * sharpest finding was a `mimeType` like `image/png;base64,;x=` — interpolated into * `data:${mime};base64,${b64}` it produces a DOUBLE `;base64,`, letting a permissive data-URI parser * decode the attacker's prefix instead of the real payload (a content-type confusion / injection). A * `\r\n` in the mime is an HTTP-header-injection vector if the URI is ever reflected. We accept ONLY a * strict `type/subtype` (no params, no whitespace, no `;`/`,`); anything else collapses to the kind's * generic safe subtype (so an image still decodes as an image) or `application/octet-stream`. */ export declare const sanitizeMimeType: (raw: string, kind?: "image" | "audio" | "video" | "document") => string; /** * Sanitise a media `filename` for interpolation into a synthetic-description line that is then placed * INSIDE a trust envelope whose body is not XML-escaped. * * @remarks * A filename is attacker-influenced and the synthetic-description body is not escaped, so a filename * like `x.png>SYSTEM: …` could close the envelope, and one that mimics the * `[media: …]` format could forge a second descriptor. We strip the envelope-significant characters * (`<`, `>`, and newlines/control chars) and length-cap (a megabyte filename is a prompt-bloat DoS). * The filename is metadata, not content the model must read byte-exact, so stripping is safe. */ export declare const sanitizeFilenameForDescription: (filename: string, maxLen?: number) => string; /** * Clamp a stash entry's trust tier to its containing media's tier as a FLOOR: a stash entry may render * at the parent's tier or LOWER (less trusted), never HIGHER. * * @remarks * The committee's #1-ranked escalation: a `third-party-private` Media carrying a stash entry tagged * `first-party` would otherwise render its fallback text in a `` envelope (the * media-fallback renderer keys the envelope off the entry's OWN tier). That lets untrusted content * smuggle itself into the trusted tier. Flooring to the parent closes it: a child can de-escalate but * never escalate above the asset it belongs to. */ export declare const floorTrustTier: (parent: T, entry: T) => T; export declare const memoryToAttrs: (m: Memory) => { memory: Memory; attrs: MemoryAttrs; }; export declare const retrievableToAttrs: (r: Retrievable) => { retrievable: Retrievable; attrs: RetrievableAttrs; }; export declare const sanitiseNameField: (raw: string) => string; /** Implements {@link ChatHelpersCommon.descriptionToChatCompletionsJsonSchema}. */ export declare const descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema; /** Default JSON-Schema renderer; alias of {@link descriptionToChatCompletionsJsonSchema}. */ export declare const defaultDescriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema; /** Implements {@link ChatHelpersCommon.renderUntrustedContent}. */ export declare const renderUntrustedContent: (content: string, attrs: UntrustedContentAttrs) => string; /** Default untrusted-content renderer; alias of {@link renderUntrustedContent}. */ export declare const defaultRenderUntrustedContent: (content: string, attrs: UntrustedContentAttrs) => string; /** Implements {@link ChatHelpersCommon.renderTrustedContent}. */ export declare const renderTrustedContent: (content: string, attrs: TrustedContentAttrs) => string; /** Default trusted-content renderer; alias of {@link renderTrustedContent}. */ export declare const defaultRenderTrustedContent: (content: string, attrs: TrustedContentAttrs) => string; /** * Structural (cross-realm-safe) check that a tool result is a {@link @nhtio/adk!SpooledArtifact}: it * exposes the reader surface the handle pattern needs (`asString` + `byteLength`/`lineCount`) and a * constructor carrying the `toolMethods` descriptor list the model is told to call. Used instead of a * bare `instanceof` so a SpooledArtifact from another realm (worker, bundle copy) still matches. */ export declare const looksLikeSpooledArtifact: (value: unknown) => value is { byteLength: () => Promise; lineCount: () => Promise; asString: () => Promise; }; /** * Render the "handle" body for a tool call's spooled-artifact result marked `inline: false`. See * {@link buildHandleBody} for the shared mechanics; this variant's leading sentence frames the * artifact as a tool result. */ export declare const renderArtifactHandleBody: (input: { callId: string; artifact: unknown; byteLength: number; lineCount: number; estimatedTokens?: number; encoding?: string; }) => string; /** * Render the "handle" body for a {@link @nhtio/adk!Retrievable}'s spooled-artifact content marked * `inline: false`. See {@link buildHandleBody} for the shared mechanics; this variant's leading * sentence frames the artifact as a retrieved record rather than a tool result. */ export declare const renderRetrievableHandleBody: (input: { callId: string; artifact: unknown; byteLength: number; lineCount: number; estimatedTokens?: number; encoding?: string; }) => string; /** Default handle-body renderer for tool-call artifacts; the `renderArtifactHandleBody` override falls back to this. */ export declare const defaultRenderArtifactHandleBody: (input: { callId: string; artifact: unknown; byteLength: number; lineCount: number; estimatedTokens?: number; encoding?: string; }) => string; /** Default handle-body renderer for retrievable artifacts; the `renderRetrievableHandleBody` override falls back to this. */ export declare const defaultRenderRetrievableHandleBody: (input: { callId: string; artifact: unknown; byteLength: number; lineCount: number; estimatedTokens?: number; encoding?: string; }) => string; /** Implements {@link ChatHelpersCommon.renderStandingInstructions}. */ export declare const renderStandingInstructions: (items: Iterable, attrs?: StandingInstructionAttrs) => string; /** Default standing-instructions renderer; alias of {@link renderStandingInstructions}. */ export declare const defaultRenderStandingInstructions: (items: Iterable, attrs?: StandingInstructionAttrs) => string; /** Implements {@link ChatHelpersCommon.renderMemories}. */ export declare const renderMemories: (items: Iterable<{ memory: Memory; attrs: MemoryAttrs; }>) => string; /** Default memories renderer; alias of {@link renderMemories}. */ export declare const defaultRenderMemories: (items: Iterable<{ memory: Memory; attrs: MemoryAttrs; }>) => string; /** Implements {@link ChatHelpersCommon.renderRetrievableSafetyDirective}. */ export declare const renderRetrievableSafetyDirective: () => string; /** Default safety-directive renderer; alias of {@link renderRetrievableSafetyDirective}. */ export declare const defaultRenderRetrievableSafetyDirective: () => string; /** Implements {@link ChatHelpersCommon.renderFirstPartyRetrievables}. */ export declare const renderFirstPartyRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, renderHandle?: ChatHelpersCommon["renderRetrievableHandleBody"]) => Promise; /** Default first-party retrievables renderer; alias of {@link renderFirstPartyRetrievables}. */ export declare const defaultRenderFirstPartyRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, renderHandle?: ChatHelpersCommon["renderRetrievableHandleBody"]) => Promise; /** Implements {@link ChatHelpersCommon.renderThirdPartyPublicRetrievables}. */ export declare const renderThirdPartyPublicRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, deps: { renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; }) => Promise; /** Default third-party-public retrievables renderer; alias of {@link renderThirdPartyPublicRetrievables}. */ export declare const defaultRenderThirdPartyPublicRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, deps: { renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; }) => Promise; /** Implements {@link ChatHelpersCommon.renderThirdPartyPrivateRetrievables}. */ export declare const renderThirdPartyPrivateRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, deps: { renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; }) => Promise; /** Default third-party-private retrievables renderer; alias of {@link renderThirdPartyPrivateRetrievables}. */ export declare const defaultRenderThirdPartyPrivateRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, deps: { renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; }) => Promise; /** Implements {@link ChatHelpersCommon.renderRetrievables}. */ export declare const renderRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, deps: { renderRetrievableSafetyDirective: ChatHelpersCommon["renderRetrievableSafetyDirective"]; renderFirstPartyRetrievables: ChatHelpersCommon["renderFirstPartyRetrievables"]; renderThirdPartyPublicRetrievables: ChatHelpersCommon["renderThirdPartyPublicRetrievables"]; renderThirdPartyPrivateRetrievables: ChatHelpersCommon["renderThirdPartyPrivateRetrievables"]; renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; }) => Promise; /** Default retrievables orchestrator; alias of {@link renderRetrievables}. */ export declare const defaultRenderRetrievables: (items: Iterable<{ retrievable: Retrievable; attrs: RetrievableAttrs; }>, deps: { renderRetrievableSafetyDirective: ChatHelpersCommon["renderRetrievableSafetyDirective"]; renderFirstPartyRetrievables: ChatHelpersCommon["renderFirstPartyRetrievables"]; renderThirdPartyPublicRetrievables: ChatHelpersCommon["renderThirdPartyPublicRetrievables"]; renderThirdPartyPrivateRetrievables: ChatHelpersCommon["renderThirdPartyPrivateRetrievables"]; renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; }) => Promise; /** Implements {@link ChatHelpersCommon.renderThought}. */ export declare const renderThought: (content: string, attrs: ThoughtAttrs, payload?: unknown) => string; /** Default thought renderer; alias of {@link renderThought}. */ export declare const defaultRenderThought: (content: string, attrs: ThoughtAttrs, payload?: unknown) => string; /** Implements {@link ChatHelpersCommon.filterThoughts}. */ export declare const filterThoughts: (thoughts: Iterable, mode: "all-self" | "latest-self" | "all", selfIdentity: string, replayCompatibility: ReadonlyArray) => Thought[]; /** Default thought filter; alias of {@link filterThoughts}. */ export declare const defaultFilterThoughts: (thoughts: Iterable, mode: "all-self" | "latest-self" | "all", selfIdentity: string, replayCompatibility: ReadonlyArray) => Thought[]; /** Implements {@link ChatHelpersCommon.toolsToChatCompletionsTools}. */ export declare const toolsToChatCompletionsTools: (tools: ReadonlyArray, deps: { descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema; }) => ChatCompletionsTool[]; /** Default tool-translation helper; alias of {@link toolsToChatCompletionsTools}. */ export declare const defaultToolsToChatCompletionsTools: (tools: ReadonlyArray, deps: { descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema; }) => ChatCompletionsTool[]; /** Implements {@link ChatHelpersCommon.renderChatCompletionsSystemPrompt}. */ export declare const renderChatCompletionsSystemPrompt: (input: { systemPrompt: Tokenizable; standingInstructions: Iterable; memories: Iterable; retrievables: Iterable; /** * Live dispatch context for resolving a DYNAMIC {@link Tokenizable} systemPrompt via `.render(ctx)`. * Optional; a static systemPrompt ignores it. (standingInstructions/memories render through their own * sub-helpers and remain static-string reads — the flagship's only dynamic content is a thought.) */ renderCtx?: unknown; bucketOrder: ChatCompletionsBucketOrder; renderStandingInstructions: ChatHelpersCommon["renderStandingInstructions"]; renderMemories: ChatHelpersCommon["renderMemories"]; renderRetrievables: ChatHelpersCommon["renderRetrievables"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; renderRetrievableSafetyDirective: ChatHelpersCommon["renderRetrievableSafetyDirective"]; renderFirstPartyRetrievables: ChatHelpersCommon["renderFirstPartyRetrievables"]; renderThirdPartyPublicRetrievables: ChatHelpersCommon["renderThirdPartyPublicRetrievables"]; renderThirdPartyPrivateRetrievables: ChatHelpersCommon["renderThirdPartyPrivateRetrievables"]; renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; }) => Promise; /** Default system-prompt renderer; alias of {@link renderChatCompletionsSystemPrompt}. */ export declare const defaultRenderChatCompletionsSystemPrompt: (input: { systemPrompt: Tokenizable; standingInstructions: Iterable; memories: Iterable; retrievables: Iterable; /** * Live dispatch context for resolving a DYNAMIC {@link Tokenizable} systemPrompt via `.render(ctx)`. * Optional; a static systemPrompt ignores it. (standingInstructions/memories render through their own * sub-helpers and remain static-string reads — the flagship's only dynamic content is a thought.) */ renderCtx?: unknown; bucketOrder: ChatCompletionsBucketOrder; renderStandingInstructions: ChatHelpersCommon["renderStandingInstructions"]; renderMemories: ChatHelpersCommon["renderMemories"]; renderRetrievables: ChatHelpersCommon["renderRetrievables"]; renderRetrievableHandleBody?: ChatHelpersCommon["renderRetrievableHandleBody"]; renderRetrievableSafetyDirective: ChatHelpersCommon["renderRetrievableSafetyDirective"]; renderFirstPartyRetrievables: ChatHelpersCommon["renderFirstPartyRetrievables"]; renderThirdPartyPublicRetrievables: ChatHelpersCommon["renderThirdPartyPublicRetrievables"]; renderThirdPartyPrivateRetrievables: ChatHelpersCommon["renderThirdPartyPrivateRetrievables"]; renderUntrustedContent: ChatHelpersCommon["renderUntrustedContent"]; }) => Promise; /** * Computes a SHA-256 fingerprint of `value` via {@link canonical} canonicalisation, over its UTF-8 * bytes, using `globalThis.crypto.subtle.digest`. * * @remarks * Wire-shape-agnostic replay-prefix fingerprinting primitive shared across the Chat-family LLM * batteries' "reasoning replay" features (Anthropic's signed `thinking` blocks, and any sibling * battery's equivalent). Each battery assembles its own wire-shaped prefix object — e.g. `{ model, * system, tools, messages }` for Anthropic Messages — and passes it here; this primitive carries no * knowledge of any individual wire shape. */ export declare const canonicalFingerprint: (value: unknown) => Promise; /** Default canonical-fingerprint primitive; alias of {@link canonicalFingerprint}. */ export declare const defaultCanonicalFingerprint: (value: unknown) => Promise;