Watch
0
0
Fork
You've already forked hyperhive
0

templates: the agent system prompt is a Jinja template, rendered through hive-template

system.md carries {{ label }}-style variables and an {% if not archetype %} block in place of the config:repo / config:archetype marker pairs, so prompt.rs drops its line filter, marker parsers and string replaces. The rendered prompt is byte for byte the old one for a custom agent, an archetype agent and an empty archetype name, with and without hive, swarm, docs and operators. hive-template now drops a block tag's own line.
This commit is contained in:
damocles 2026-11-11 02:26:25 +01:00 • committed by mara
commit c0eb6780ec
2 changed files with 165 additions and 242 deletions

View file

@ -7,6 +7,9 @@ block is `{% if cond %}...{% endif %}`, and a lone `{` or `}` stays plain text.
- **`render(template, &context)`**: the text, or a message when the template
does not parse or names a variable the context lacks. An unknown variable is
an error, never an empty string.
- A block tag alone on its line leaves no line behind (`trim_blocks` and
`lstrip_blocks` are on), so a template ending in a block tag and a newline
loses that newline.
- **`variables(template)`**: the variables the template reads, so a caller can
refuse an unknown field when the template is saved instead of when it renders.

View file

@ -10,12 +10,15 @@ use std::collections::BTreeSet;
use minijinja::{Environment, UndefinedBehavior};
use serde::Serialize;
/// An environment that refuses a name the context does not hold, and keeps the
/// template's trailing newline.
/// An environment that refuses a name the context does not hold, keeps the
/// template's trailing newline, and drops a block tag's own line (`{% if %}` on a
/// line by itself leaves no blank line behind).
fn environment() -> Environment<'static> {
let mut env = Environment::new();
env.set_undefined_behavior(UndefinedBehavior::Strict);
env.set_keep_trailing_newline(true);
env.set_trim_blocks(true);
env.set_lstrip_blocks(true);
env
}
@ -56,7 +59,16 @@ mod tests {
"{{ repo }}{% if role == \"agent\" %} (agent){% endif %}\n",
&ctx,
);
assert_eq!(out.as_deref(), Ok("o/r (agent)\n"));
assert_eq!(out.as_deref(), Ok("o/r (agent)"));
}
#[test]
fn a_block_tag_on_its_own_line_leaves_no_line_behind() {
let out = render(
"a\n{% if on %}\nb\n{% else %}\nc\n{% endif %}\nd\n",
&json!({ "on": false }),
);
assert_eq!(out.as_deref(), Ok("a\nc\nd\n"));
}
#[test]