Lmml.Narrative.Renderer (Lmml v0.1.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.

Types

content_part()

@type content_part() :: %{required(String.t()) => String.t() | map()}

Functions

image?(name)

@spec image?(String.t()) :: boolean()

True when name's inferred MIME type is an image type.

mime_type(name)

@spec mime_type(String.t()) :: String.t()

The MIME type inferred for name by its file extension, defaulting to application/octet-stream when unrecognized.

render(resolver)

@spec render(Lmml.Narrative.Resolver.t()) :: [content_part()]

Renders a resolved narrative into an ordered list of content parts, text first.