Lmml. Narrative. Renderer
(lmml v0.2.0)
View Source
Turns a Lmml.Narrative.Resolver.t() into the list of typed content
parts a multimodal LLM chat completion API expects for a message's
content field -- the same %{"type" => ...} shape already built by
hand elsewhere in this workspace for vision models (see dsh's
DeepSeekHarness.CLI.ContextExpander/Brain.Session, which construct
%{"type" => "image_url", "image_url" => %{"url" => data_uri}} and
%{"type" => "text", "text" => text} parts).
Scope
The narrative's raw text becomes a single verbatim "text" part,
included as-is rather than rewritten to strip or splice around embed
occurrences. This is a deliberate difference from ContextExpander
(which does rewrite free-form chat text, replacing an @ref with a
"[Image: label]" placeholder): an lmml narrative's embed syntax
(@name.ext / @@@name.ext ... @@@) is always clearly delimited and
meaningful Markdown-superset text on its own, so a model reading the
raw narrative already sees exactly where each embed occurs -- no
destructive rewriting is needed to convey position, and every resolved
embed's part is simply appended after the text part, in first-occurrence
order.
Each resolved embed becomes one further content part, typed by mapping
its name's file extension to a MIME type: image extensions become
"image_url" parts (a base64 data URI, exactly like ContextExpander);
everything else becomes an "attachment" part carrying the resolved
content directly (%{"type" => "attachment", "name" => ..., "mime" => ..., "content" => ...}).
Summary
Functions
True when name's inferred MIME type is an image type.
The MIME type inferred for name by its file extension, defaulting to application/octet-stream when unrecognized.
Renders a resolved narrative into an ordered list of content parts, text
first. Equivalent to render/2 with no options.
Renders a resolved narrative into an ordered list of content parts, text
first, honoring opts.
Exports a narrative to standard, human-readable Markdown by replacing
embed syntax (@name.ext and @@@name.ext ... @@@) with clean text
placeholders (e.g. [Image: logo.png] or [Attachment: config.yaml]).
The total byte size of all resolved embed content in resolved (the sum
of every embed's resolved bytes, not counting the narrative text). Useful
for gauging a narrative's payload against a budget before rendering.
Types
@type opts() :: [{:max_embed_bytes, non_neg_integer()}]
Options for render/2.
Functions
True when name's inferred MIME type is an image type.
The MIME type inferred for name by its file extension, defaulting to application/octet-stream when unrecognized.
@spec render(Lmml.Narrative.Resolver.t()) :: [content_part()]
Renders a resolved narrative into an ordered list of content parts, text
first. Equivalent to render/2 with no options.
@spec render(Lmml.Narrative.Resolver.t(), opts()) :: [content_part()]
Renders a resolved narrative into an ordered list of content parts, text
first, honoring opts.
Options:
:max_embed_bytes-- a per-embed byte budget. Any resolved embed whose content exceeds this size is omitted from the result (it is not truncated, since a partial image or config is worse than none). This is a safety valve for sending a narrative to an API with a payload/token budget: set it to the largest single asset you are willing to transmit and oversized embeds quietly drop out rather than blowing the request. Defaults to no limit (all embeds kept).
The narrative's raw text always becomes the first, verbatim "text"
part regardless of opts.
@spec to_md( Lmml.Narrative.Resolver.t() | Lmml.Bundle.t(), keyword() ) :: String.t()
Exports a narrative to standard, human-readable Markdown by replacing
embed syntax (@name.ext and @@@name.ext ... @@@) with clean text
placeholders (e.g. [Image: logo.png] or [Attachment: config.yaml]).
@spec total_embed_bytes(Lmml.Narrative.Resolver.t()) :: non_neg_integer()
The total byte size of all resolved embed content in resolved (the sum
of every embed's resolved bytes, not counting the narrative text). Useful
for gauging a narrative's payload against a budget before rendering.