prompts should become templates #11

Closed
opened 2026-04-01 10:28:05 +00:00 by despiegk · 3 comments
Owner
  • on home directory level where we have the decks make a dir called prompts
  • in there we give defined name as we use the prompts in our code
  • use variables inside the prompts for e.g. slidename, deckname, deckpath, slidepath, ...
  • these templates are then used in the code
  • when we open a deck it checks it at that level there is a folder prompt, if not the we have default templates in code and we put the templates there

this allows users to create and modify their own templates

- on home directory level where we have the decks make a dir called prompts - in there we give defined name as we use the prompts in our code - use variables inside the prompts for e.g. slidename, deckname, deckpath, slidepath, ... - these templates are then used in the code - when we open a deck it checks it at that level there is a folder prompt, if not the we have default templates in code and we put the templates there this allows users to create and modify their own templates
Author
Owner

Implementation Spec for Issue #11 — Prompts as User-Editable Templates

Objective

Replace all hardcoded AI prompt constants in the codebase with file-based templates stored in a prompts/ directory at the decks root level. When a deck root directory is scanned/opened and no prompts/ folder exists, the system seeds it with default templates. This allows users to inspect and customize every prompt the system uses without touching source code.

Requirements

  • A prompts/ directory lives at the same level as deck directories (the root passed to deck.scan)
  • Each prompt file has a canonical filename matching the key used in code (e.g. system_instructions.md, agent_build_deck.md, etc.)
  • Prompt files support variable interpolation using {{variable_name}} syntax
  • When deck.scan is called, the system checks for prompts/; if absent, it writes all default templates there
  • Default templates are embedded in the binary via include_str! so the binary works without external files
  • All code that currently builds a prompt string calls a shared load_template helper that reads from disk (falls back to embedded default if file is missing)
  • No change to the JSON-RPC API surface
  • The prompts/ directory is excluded from deck scanning

Template Files (9 total)

File Variables
system_instructions.md (system prompt — no vars)
system_fix_instructions.md (system prompt — no vars)
system_rewrite_instructions.md (system prompt — no vars)
system_fix_slide.md (system prompt — no vars)
system_rewrite_slide.md (system prompt — no vars)
system_slide_to_instructions.md (system prompt — no vars)
system_voice_cleanup.md (system prompt — no vars)
agent_build_deck.md {{instructions}}, {{deck_name}}, {{deck_path}}
generator_slide_image.md {{slide_name}}, {{slide_content}}, {{theme_content}}, {{deck_context}}

New Files to Create

  • crates/hero_slides_lib/prompts/*.md — 9 default template files
  • crates/hero_slides_lib/src/prompts.rs — core module: load_template, render_template, seed_prompts_dir, prompts_dir_for_root

Files to Modify

  • crates/hero_slides_lib/src/lib.rs — register pub mod prompts
  • crates/hero_slides_lib/src/instructions.rs — remove SYSTEM_PROMPT constant, add prompts_dir param
  • crates/hero_slides_lib/src/generator.rs — replace static string in build_prompt with template loading
  • crates/hero_slides_lib/src/voice.rs — replace inline system prompt with template loading
  • crates/hero_slides_lib/src/deck.rs — thread prompts_dir, call seed_prompts_dir on create
  • crates/hero_slides_lib/src/discovery.rs — skip prompts/ during deck scan
  • crates/hero_slides_server/src/agent.rs — remove 4 system prompt constants, use templates
  • crates/hero_slides_server/src/rpc.rs — seed prompts/ on scan/create, thread prompts_dir to callers

Implementation Steps

  1. Create 9 default .md template files in crates/hero_slides_lib/prompts/
  2. Create crates/hero_slides_lib/src/prompts.rs with core helpers
  3. Register prompts module in lib.rs
  4. Update discovery.rs to skip prompts/ (independent, parallel with 1-3)
  5. Refactor instructions.rs — load system prompt from template
  6. Refactor voice.rs — load voice cleanup prompt from template
  7. Refactor generator.rsbuild_prompt uses template + render
  8. Update deck.rs — thread prompts_dir, seed on create
  9. Refactor agent.rs — remove constants, load from templates
  10. Update rpc.rs — seed on scan/create, thread prompts_dir to callers

Acceptance Criteria

  • prompts/ directory created at deck root when calling deck.scan for the first time
  • Contains exactly 9 .md template files
  • User can edit any template; next AI call uses modified text without recompiling
  • Deleted template silently falls back to embedded default
  • prompts/ not treated as a deck directory during scan
  • deck.create seeds prompts/ in parent
  • All existing tests (cargo test) continue to pass
  • {{variable_name}} substitution works; unknown tokens left untouched
  • Binary works with no external prompt files (embedded defaults always available)
  • No new JSON-RPC methods required

Notes

  • The deck root means the root argument passed to deck.scan, not individual deck directories
  • include_str! paths in prompts.rs (at src/prompts.rs) reference ../prompts/filename.md
  • Steps 1 & 4 are fully independent. Steps 5, 6, 7 can all run once Step 2 is done.
  • No OpenRPC spec changes needed — feature is internal to lib/server boundary
## Implementation Spec for Issue #11 — Prompts as User-Editable Templates ### Objective Replace all hardcoded AI prompt constants in the codebase with file-based templates stored in a `prompts/` directory at the decks root level. When a deck root directory is scanned/opened and no `prompts/` folder exists, the system seeds it with default templates. This allows users to inspect and customize every prompt the system uses without touching source code. ### Requirements - A `prompts/` directory lives at the **same level as deck directories** (the root passed to `deck.scan`) - Each prompt file has a **canonical filename** matching the key used in code (e.g. `system_instructions.md`, `agent_build_deck.md`, etc.) - Prompt files support **variable interpolation** using `{{variable_name}}` syntax - When `deck.scan` is called, the system checks for `prompts/`; if absent, it writes all default templates there - Default templates are embedded in the binary via `include_str!` so the binary works without external files - All code that currently builds a prompt string calls a shared `load_template` helper that reads from disk (falls back to embedded default if file is missing) - No change to the JSON-RPC API surface - The `prompts/` directory is excluded from deck scanning ### Template Files (9 total) | File | Variables | |---|---| | `system_instructions.md` | *(system prompt — no vars)* | | `system_fix_instructions.md` | *(system prompt — no vars)* | | `system_rewrite_instructions.md` | *(system prompt — no vars)* | | `system_fix_slide.md` | *(system prompt — no vars)* | | `system_rewrite_slide.md` | *(system prompt — no vars)* | | `system_slide_to_instructions.md` | *(system prompt — no vars)* | | `system_voice_cleanup.md` | *(system prompt — no vars)* | | `agent_build_deck.md` | `{{instructions}}`, `{{deck_name}}`, `{{deck_path}}` | | `generator_slide_image.md` | `{{slide_name}}`, `{{slide_content}}`, `{{theme_content}}`, `{{deck_context}}` | ### New Files to Create - `crates/hero_slides_lib/prompts/*.md` — 9 default template files - `crates/hero_slides_lib/src/prompts.rs` — core module: `load_template`, `render_template`, `seed_prompts_dir`, `prompts_dir_for_root` ### Files to Modify - `crates/hero_slides_lib/src/lib.rs` — register `pub mod prompts` - `crates/hero_slides_lib/src/instructions.rs` — remove `SYSTEM_PROMPT` constant, add `prompts_dir` param - `crates/hero_slides_lib/src/generator.rs` — replace static string in `build_prompt` with template loading - `crates/hero_slides_lib/src/voice.rs` — replace inline system prompt with template loading - `crates/hero_slides_lib/src/deck.rs` — thread `prompts_dir`, call `seed_prompts_dir` on create - `crates/hero_slides_lib/src/discovery.rs` — skip `prompts/` during deck scan - `crates/hero_slides_server/src/agent.rs` — remove 4 system prompt constants, use templates - `crates/hero_slides_server/src/rpc.rs` — seed `prompts/` on scan/create, thread `prompts_dir` to callers ### Implementation Steps 1. Create 9 default `.md` template files in `crates/hero_slides_lib/prompts/` 2. Create `crates/hero_slides_lib/src/prompts.rs` with core helpers 3. Register `prompts` module in `lib.rs` 4. Update `discovery.rs` to skip `prompts/` (independent, parallel with 1-3) 5. Refactor `instructions.rs` — load system prompt from template 6. Refactor `voice.rs` — load voice cleanup prompt from template 7. Refactor `generator.rs` — `build_prompt` uses template + render 8. Update `deck.rs` — thread `prompts_dir`, seed on create 9. Refactor `agent.rs` — remove constants, load from templates 10. Update `rpc.rs` — seed on scan/create, thread `prompts_dir` to callers ### Acceptance Criteria - [ ] `prompts/` directory created at deck root when calling `deck.scan` for the first time - [ ] Contains exactly 9 `.md` template files - [ ] User can edit any template; next AI call uses modified text without recompiling - [ ] Deleted template silently falls back to embedded default - [ ] `prompts/` not treated as a deck directory during scan - [ ] `deck.create` seeds `prompts/` in parent - [ ] All existing tests (`cargo test`) continue to pass - [ ] `{{variable_name}}` substitution works; unknown tokens left untouched - [ ] Binary works with no external prompt files (embedded defaults always available) - [ ] No new JSON-RPC methods required ### Notes - The deck root means the `root` argument passed to `deck.scan`, not individual deck directories - `include_str!` paths in `prompts.rs` (at `src/prompts.rs`) reference `../prompts/filename.md` - Steps 1 & 4 are fully independent. Steps 5, 6, 7 can all run once Step 2 is done. - No OpenRPC spec changes needed — feature is internal to lib/server boundary
Author
Owner

Implementation Complete

Changes Made

New files created:

  • crates/hero_slides_lib/src/prompts/ — 8 default template .md files (one per AI prompt)
  • crates/hero_slides_lib/src/prompts.rs — core module: load_template, render_template, seed_prompts_dir, prompts_dir_for_root

Files modified:

  • crates/hero_slides_lib/src/lib.rs — added pub mod prompts and re-exported helpers
  • crates/hero_slides_lib/src/discovery.rs — skip prompts/ directory during deck scan
  • crates/hero_slides_lib/src/instructions.rs — removed SYSTEM_PROMPT constant; loads from template
  • crates/hero_slides_lib/src/voice.rs — removed inline system prompt; loads from template
  • crates/hero_slides_lib/src/generator.rsbuild_prompt now uses generator_slide_image.md template with {{variable}} substitution
  • crates/hero_slides_lib/src/deck.rsscan_decks seeds prompts/; deck_create seeds prompts/ in parent; threads prompts_dir to generate_slide
  • crates/hero_slides_server/src/agent.rs — removed 4 system prompt constants; all handlers load from templates
  • crates/hero_slides_server/src/rpc.rs — updated voice_transcribe and slide_to_instructions call sites
  • crates/hero_slides_rhai/src/instructions_module.rs — updated call site
  • crates/hero_slides_rhai/src/voice_module.rs — updated call site

How it works

  • Templates live at <deck-root>/prompts/ (same level as deck directories)
  • On deck.scan or deck.create, the prompts/ folder is auto-seeded with defaults
  • Users can edit any .md file in prompts/ — the next AI call picks up the change immediately, no recompile needed
  • If a file is deleted or missing, the embedded binary default is used silently
  • Variable interpolation uses {{variable_name}} syntax (e.g. {{instructions}}, {{slide_name}}, {{theme_content}})
  • The system_rewrite_slide.md template was improved to focus on structure/content/idea and explicitly NOT specify colors or typography (those come from the deck theme)

Test Results

  • 38 unit tests: all passed
  • 12 integration tests: all passed
  • 2 doc-tests: all passed
## Implementation Complete ### Changes Made **New files created:** - `crates/hero_slides_lib/src/prompts/` — 8 default template `.md` files (one per AI prompt) - `crates/hero_slides_lib/src/prompts.rs` — core module: `load_template`, `render_template`, `seed_prompts_dir`, `prompts_dir_for_root` **Files modified:** - `crates/hero_slides_lib/src/lib.rs` — added `pub mod prompts` and re-exported helpers - `crates/hero_slides_lib/src/discovery.rs` — skip `prompts/` directory during deck scan - `crates/hero_slides_lib/src/instructions.rs` — removed `SYSTEM_PROMPT` constant; loads from template - `crates/hero_slides_lib/src/voice.rs` — removed inline system prompt; loads from template - `crates/hero_slides_lib/src/generator.rs` — `build_prompt` now uses `generator_slide_image.md` template with `{{variable}}` substitution - `crates/hero_slides_lib/src/deck.rs` — `scan_decks` seeds `prompts/`; `deck_create` seeds `prompts/` in parent; threads `prompts_dir` to `generate_slide` - `crates/hero_slides_server/src/agent.rs` — removed 4 system prompt constants; all handlers load from templates - `crates/hero_slides_server/src/rpc.rs` — updated `voice_transcribe` and `slide_to_instructions` call sites - `crates/hero_slides_rhai/src/instructions_module.rs` — updated call site - `crates/hero_slides_rhai/src/voice_module.rs` — updated call site ### How it works - Templates live at `<deck-root>/prompts/` (same level as deck directories) - On `deck.scan` or `deck.create`, the `prompts/` folder is auto-seeded with defaults - Users can edit any `.md` file in `prompts/` — the next AI call picks up the change immediately, no recompile needed - If a file is deleted or missing, the embedded binary default is used silently - Variable interpolation uses `{{variable_name}}` syntax (e.g. `{{instructions}}`, `{{slide_name}}`, `{{theme_content}}`) - The `system_rewrite_slide.md` template was improved to focus on structure/content/idea and explicitly NOT specify colors or typography (those come from the deck theme) ### Test Results - 38 unit tests: all passed - 12 integration tests: all passed - 2 doc-tests: all passed
Author
Owner

Implementation committed: 1a56ffe

Browse: 1a56ffe

Implementation committed: `1a56ffe` Browse: https://forge.ourworld.tf/lhumina_code/hero_slides/commit/1a56ffe
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_slides#11
No description provided.