Class PromptFormat
Three places in the codebase render the same mustAlways /
mustNever constraint blocks: RolePromptBuilder (the
primary @RoleSpec renderer), RoleSpecReader (YAML /
external role-spec ingestion), and the SystemPromptBuilder
SCOP bridge in tnsai-integration. Pulling the format here
keeps wording, ordering, and indentation in lockstep — improving
one site no longer means hunting for the other two.
The format itself is the issue's chosen design: positive obligations first (set the tone), negatives last (draw the boundary), single header per block, bullets indented under the header.
- Since:
- 0.9.3
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidrenderConstraints(StringBuilder out, String[] mustAlways, String[] mustNever, String indent) Convenience overload acceptingString[]arrays — convenient for callers reading fromActionMetadatawhose getters return raw arrays.static voidrenderConstraints(StringBuilder out, List<String> mustAlways, List<String> mustNever, String indent) Append a constraint block for an action —Must always:first, thenMust never:, each as a header line followed by indented bullet rules.static voidrenderExamples(StringBuilder out, List<ToolExampleSpec> examples, String indent) Append a `@ToolExample` block for an action — positive examples underExamples:, then negatives underAvoid (anti-patterns):.
-
Method Details
-
renderConstraints
public static void renderConstraints(StringBuilder out, List<String> mustAlways, List<String> mustNever, String indent) Append a constraint block for an action —Must always:first, thenMust never:, each as a header line followed by indented bullet rules. Empty inputs render nothing.Example output (with
indent = " "):Must always: - Call this tool exactly once per turn - Include the returned question text VERBATIM in your reply Must never: - Paraphrase or summarise the questionEach output line begins with a leading
\n; callers stay responsible for any trailing newline they want after the block. Bullet rows are indented two extra spaces under the header so the section grouping stays visually clear.- Parameters:
out- buffer to append tomustAlways- positive obligations;nullor empty skips the blockmustNever- negative obligations;nullor empty skips the blockindent- base indent string applied to both the header and the bullet rows
-
renderConstraints
public static void renderConstraints(StringBuilder out, String[] mustAlways, String[] mustNever, String indent) Convenience overload acceptingString[]arrays — convenient for callers reading fromActionMetadatawhose getters return raw arrays. -
renderExamples
Append a `@ToolExample` block for an action — positive examples underExamples:, then negatives underAvoid (anti-patterns):. Same indent + bullet conventions asrenderConstraints(StringBuilder, List, List, String).Why render examples in the system-prompt prose at all: provider tool definitions (
input_exampleson Anthropic, description fold on OpenAI / Gemini / others) already deliver examples at the tool-call surface. The system-prompt surface is *additionally* useful: the model sees these when reasoning about the role overall, before deciding whether a tool is the right move. Anthropic's research reports a 72%→90% accuracy improvement on complex parameter handling when examples are present — concrete examples beat abstract rules. Token cost is paid once on the cached system prompt, not per call.Empty inputs render nothing. Examples whose
inputis blank are skipped (defensive — the only field every example must have meaningful content for).Bullet shape:
Examples: - {description}: input={input} → output={output} Avoid (anti-patterns): - {description}: input={input} — Why bad: {whyBad}- Parameters:
out- buffer to append toexamples- positive + negative examples;nullor empty skips the entire blockindent- base indent applied to headers and bullets
-