diff --git a/locale-resource-formats.md b/locale-resource-formats.md index 11ad4b5..1172001 100644 --- a/locale-resource-formats.md +++ b/locale-resource-formats.md @@ -48,7 +48,7 @@ The slot-bearing roles map onto the data path of a voice interaction: their named slots are filled by the caller before the text is spoken. `.entity`, `.voc`, and `.blacklist` share the slot-free format; they are how a -developer encodes a set of natural-language phrasings for OVOS to use, and +developer encodes a set of natural-language phrasings for the assistant to use, and differ only in *which component consumes them* (§4.3). This specification covers the **folder layout**, the **common parsing rules**, @@ -229,7 +229,7 @@ templates using expansion `(a|b)` / `[x]` only, **no named slots**. They are syntactically and semantically identical, and a loader parses all three the same way — each **loads as** the union of the sample sets of all its lines (OVOS-INTENT-1 §4). They are how a developer encodes a set of natural-language -phrasings for OVOS to consume. +phrasings for the assistant to consume. They differ **only in role** — which component reads the file and what it does with the expanded phrase set: @@ -274,6 +274,86 @@ yeah trailer ``` +### 4.4 `.prompt` — language-model prompt + +**Format.** Prompt: the **whole file**, verbatim, is one prompt. It is plain +text — **not** a template in the OVOS-INTENT-1 grammar — so `(`, `)`, `[`, +`]`, `<`, `>`, `|`, every newline, and all other characters are literal. There +is no expansion and no line filtering: a `.prompt` is read whole (§3), `#` +lines and blank lines included, because every character is part of the prompt. + +**Author-only comments.** The one exception to "every character is part of +the prompt" is **HTML-style comments**: a substring matching `` is +**stripped** before the file is handed to a language model. Comments may +span multiple lines; nesting is not supported. A `` in the same file is malformed — loaders **MUST** report it and +**SHOULD** treat the whole file as literal text (skipping comment +processing) rather than rendering a half-stripped prompt. Comments are +author-only notes (titling, attribution, reviewer cues) that never reach +the model. + +**Role.** The localized prompt a skill feeds to a language model. Like every +other resource it is shipped per language under `locale//` and resolved +through the override precedence of §2.1, so a prompt can be translated, +adjusted per region, or overridden by a user. + +**Substitution.** The one special construct is the **`{name}`** substitution +point. A slot **name** consists of lowercase ASCII letters, digits, and +underscores, and MUST NOT begin with a digit. At render time a caller supplies +values keyed by name; an occurrence of `{name}` is replaced by the +caller-supplied value **only when all three hold**: + +1. it forms a complete, well-formed `{name}` (a `{` not followed by a valid + name and a closing `}` is literal text — so `{}`, `{ }`, and JSON such as + `{"key": 1}` pass through untouched); +2. the caller supplied a value for that name; +3. it does **not** lie inside a fenced code block — text between a pair of + ```` ``` ```` fences (CommonMark fenced code block) is literal, so a + `{name}` shown as an example inside a code block is never substituted. + Fence detection follows CommonMark: a line whose first non-whitespace + content is three or more backticks opens or closes a fence; an open + fence with no closing fence in the file extends to end-of-file. + Implementations **MAY** use simpler heuristics (counting triple + backticks) so long as the well-formed cases of §4.4 render identically; + pathological inputs (nested fences, indented fences) are + implementation-defined. + +**Slots are optional.** A `{name}` for which the caller supplied no value is +left **as literal text** — an unfilled slot is not an error. This is the +deliberate opposite of `.dialog` (§4.2), where the caller MUST fill every slot +and an unfilled one MUST NOT be rendered. A prompt is free-form text that may +legitimately contain brace characters the author never intended as slots, so +substitution is conservative: it touches only the names the caller explicitly +provides. + +**Loads as.** The single whole-file string, with substitution applied per the +rules above. + +The full content of a file `weather_report.prompt`, rendered with the caller +value `{"query": "weather in Lisbon"}` (a `#` line is ordinary prompt text +here — it is **not** stripped): + +```` +# Weather assistant + +You are a concise weather assistant. Answer the user's question. + +User asked: {query} + +Reply as JSON shaped like {"summary": "...", "temp_c": 0}. The {response} +placeholder shown in the code block below is illustrative only: + +``` +{"summary": "{response}", "temp_c": 18} +``` +```` + +`{query}` is substituted; the `# Weather assistant` heading is kept, the +literal JSON braces are left untouched, and the `{response}` inside the fenced +block is not substituted. A `{tone}` slot the caller passed no value for would +likewise stay literal. + + --- ## 5. Authoring a conformant loader