Expand description
§Module: template
Template-mode support for in-place response documents. Parses structured patch blocks from agent responses and applies them to named component slots in the document, with boundary marker lifecycle management for CRDT-safe stream writes.
§Spec
parse_patches: Scans agent response text for<!-- patch:name -->...<!-- /patch:name -->blocks and returns a list ofPatchBlockvalues plus any unmatched text (content outside patch blocks). Markers inside fenced code blocks (``` or ~~~) and inline code spans are ignored so examples in responses are never mis-parsed as real patches.apply_patches: Delegates toapply_patches_with_overrideswith an empty override map. Applies parsed patches to matching<!-- agent:name -->components in the document.apply_patches_with_overrides: Core patch application pipeline:- Pre-patch: strips all existing boundary markers, inserts a fresh boundary at the end
of the
exchangecomponent (keyed to the file stem). - Applies each patch using mode resolution: stream overrides > inline attr (
patch=ormode=) >.agent-doc/components.toml> built-in defaults (exchange/findingsdefault toappend, all others toreplace). - For
appendmode, uses boundary-aware insertion when a boundary marker exists. - Patches targeting missing component names are routed as overflow to
exchange/output. - Unmatched text and overflow are merged and appended to
exchange/output(or an auto-createdexchangecomponent if none exists). - Post-patch: if the boundary was consumed, re-inserts a fresh one at the end of exchange.
- Pre-patch: strips all existing boundary markers, inserts a fresh boundary at the end
of the
reposition_boundary_to_end: Removes all boundaries and inserts a new one at the end ofexchange. Used by the IPC write path to keep boundary position current.reposition_boundary_to_end_with_summary: Same, with optional human-readable suffix on the boundary ID (e.g.a0cfeb34:agent-doc).template_info: Reads a document file, resolves its template mode flag, and returns a serializableTemplateInfowith per-component name, resolved mode, content, and line number. Used by editor plugins for rendering.is_template_mode(test-only): Legacy helper to detectmode = "template"string.
§Agentic Contracts
parse_patchesis pure and infallible for valid UTF-8; it returnsOkeven for empty or patch-free responses.- Patch markers inside fenced code blocks are never extracted as real patches. Agents may include example markers in code blocks without triggering unintended writes.
- Component patches are applied in reverse document order so earlier byte offsets remain valid throughout the operation.
- A boundary marker always exists at the end of
exchangeafterapply_patches_with_overridesreturns. Callers that perform incremental (CRDT/stream) writes may rely on this invariant. - Missing-component patches never cause errors; content is silently routed to
exchange/outputwith a diagnostic written to stderr. - Mode precedence is deterministic: stream override > inline attr (
patch=>mode=) >components.toml(patchkey >modekey) > built-in default. Callers can rely on this ordering when constructing overrides for stream mode. template_inforeads the document from disk; callers must ensure the file is flushed before calling (especially in the IPC write path).
§Evals
parse_single_patch: single patch block → onePatchBlock, empty unmatchedparse_multiple_patches: two sequential patch blocks → twoPatchBlocks in order, empty unmatchedparse_with_unmatched_content: text before and after patch block → unmatched contains both text segmentsparse_empty_response: empty string → zero patches, empty unmatchedparse_no_patches: plain text with no markers → zero patches, full text in unmatchedparse_patches_ignores_markers_in_fenced_code_block: agent:component markers inside ``` are preserved as contentparse_patches_ignores_patch_markers_in_fenced_code_block: nested patch markers inside ``` are not parsed as patchesparse_patches_ignores_markers_in_tilde_fence: patch markers inside ~~~ are ignoredparse_patches_ignores_closing_marker_in_code_block: closing marker inside code block is skipped; real close is foundparse_patches_normal_markers_still_work: sanity — two back-to-back patches parse correctlyapply_patches_replace: patch to non-exchange component replaces existing contentapply_patches_unmatched_creates_exchange: unmatched text auto-creates<!-- agent:exchange -->when absentapply_patches_unmatched_appends_to_existing_exchange: unmatched text appends to existing exchange; no duplicate componentapply_patches_missing_component_routes_to_exchange: patch targeting unknown component name appears in exchangeapply_patches_missing_component_creates_exchange: missing component + no exchange → auto-creates exchange with overflowinline_attr_mode_overrides_config:mode=replaceon tag wins overcomponents.tomlappend configinline_attr_mode_overrides_default:mode=replaceon exchange wins over built-in append defaultno_inline_attr_falls_back_to_config: no inline attr →components.tomlappend config appliesno_inline_attr_no_config_falls_back_to_default: no attr, no config → exchange defaults to appendinline_patch_attr_overrides_config:patch=replaceon tag wins overcomponents.tomlappend configtemplate_info_works: template-mode doc →TemplateInfo.template_mode = true, component list populatedtemplate_info_legacy_mode_works:response_mode: templatefrontmatter key recognizedtemplate_info_append_mode: non-template doc →template_mode = false, empty component listis_template_mode_detection:Some("template")→ true; other strings andNone→ false- (aspirational)
apply_patches_boundary_invariant: after any apply_patches call with an exchange component, a boundary marker exists at end of exchange - (aspirational)
reposition_boundary_removes_stale: multiple stale boundaries are reduced to exactly one at end of exchange
Structs§
- Component
Info - Per-component info for plugin rendering.
- Patch
Block - A parsed patch directive from an agent response.
- Template
Info - Template info output for plugins.
Functions§
- apply_
patches - Apply patch blocks to a document’s components.
- apply_
patches_ with_ overrides - Apply patches with per-component mode overrides (e.g., stream mode forces “replace” for cumulative buffers even on append-mode components like exchange).
- parse_
patches - Parse
<!-- patch:name -->...<!-- /patch:name -->blocks from an agent response. - reposition_
boundary_ to_ end - Reposition the boundary marker to the end of the exchange component.
- reposition_
boundary_ to_ end_ with_ summary - Reposition boundary with an optional human-readable summary suffix.
- template_
info - Get template info for a document (for plugin rendering).