Architecture of Meetily's Template System for AI-Generated Summaries: A Technical Deep Dive
Meetily implements a modular three-layer template architecture in its Tauri-Rust backend that separates data definition, storage resolution, and runtime prompt assembly to power customizable AI-generated meeting summaries.
The architecture of Meetily's template system for AI-generated summaries provides an extensible framework for structuring LLM prompts within the Zackriya-Solutions/meetily repository. Built entirely in Rust within the frontend/src-tauri/src/summary/templates directory, this system supports both compiled-in defaults and user-provided JSON configurations while enforcing strict schema validation.
Core Data Structures: The Template Schema
The foundation of the system rests in frontend/src-tauri/src/summary/templates/types.rs, which defines the data contract between storage and the summary engine.
Two primary structs govern all template operations:
TemplateSection– Represents a discrete prompt component containing a title, optional instruction, and the LLM-compatible prompt string.Template– The container struct comprising a display name, description, and an ordered vector ofTemplateSectioninstances.
These definitions enforce type safety across the application, ensuring that any loaded template—whether bundled or custom—conforms to the expected schema before reaching the processor.
Template Storage and Resolution Strategy
The architecture of Meetily's template system for AI-generated summaries implements a hierarchical storage strategy that prioritizes user customization while maintaining reliable fallbacks.
Bundled Defaults via Compile-Time Embedding
Default templates ship with the binary through frontend/src-tauri/src/summary/templates/defaults.rs. This module uses Rust’s include_str! macro to embed JSON template files directly into the compiled artifact, ensuring that standard templates remain available offline and require no external file system access.
Dynamic Loading with Validation
The frontend/src-tauri/src/summary/templates/loader.rs module handles runtime template resolution through several key functions:
get_custom_templates_dir()– Resolves the user-configurable templates directory (defaulting to$HOME/.meetily/templates).load_bundled_template()– Retrieves embedded defaults when custom templates are unavailable.validate_and_parse_template()– Enforces schema compliance against theTemplatestruct before instantiation.
The loader implements a fallback chain: when the UI requests a template ID, the system first searches the custom directory, validates the JSON if found, and only falls back to bundled assets if the custom lookup fails. Public API functions get_template, list_template_ids, and list_templates expose these capabilities to downstream consumers.
Runtime Integration with the Summary Engine
Once loaded, templates integrate into the generation pipeline through frontend/src-tauri/src/summary/service.rs and frontend/src-tauri/src/summary/processor.rs.
Caching and Fingerprinting
The service layer generates a template_cache_fingerprint (implemented in service.rs lines 124-132) to uniquely identify template-content combinations. This fingerprinting mechanism enables aggressive caching—identical transcripts processed with identical templates bypass LLM calls entirely, reducing API costs and improving response times.
Prompt Assembly
The processor receives the validated Template struct and constructs the final LLM payload in processor.rs (lines 306-331). It iterates through each TemplateSection, concatenating the instruction and prompt fields into a cohesive prompt structure that the backend submits to the language model.
use crate::summary::processor::generate_meeting_summary;
use crate::summary::templates::Template;
// Assume `transcripts` is a Vec<String> of the meeting speech
let tmpl = templates::get_template("standard_meeting")?;
let summary = generate_meeting_summary(&transcripts, &tmpl, target_language)?;
Frontend API: Tauri Commands for Template Management
The React frontend communicates with the template system through frontend/src-tauri/src/summary/template_commands.rs, which exposes Tauri IPC commands:
list_templates()– Returns a vector of available template metadata for the UI catalogue.get_template_details()– Retrieves full template specifications for editing or previewing.
These commands bridge the Rust backend with the TypeScript frontend, enabling users to select, preview, and customize templates without restarting the application.
Creating Custom Templates: JSON Structure and Storage
Developers and users can extend the system by creating JSON files that match the Template schema. The following example demonstrates a minimal custom template configuration:
{
"name": "My Custom Brief",
"description": "A concise summary for quick read‑throughs",
"sections": [
{
"title": "Highlights",
"instruction": "Summarize the key decisions",
"prompt": "{{TRANSCRIPT}}"
}
]
}
Save this file as my_custom_brief.json inside the directory returned by templates::loader::get_custom_templates_dir() (typically $HOME/.meetily/templates). The loader automatically validates the schema and includes it in the template catalogue immediately.
To list available templates programmatically:
// Returns a vector of (id, name, description) for the UI
let list = templates::list_templates();
for (id, name, desc) in list {
println!("{id}: {name} – {desc}");
}
Summary
The architecture of Meetily's template system for AI-generated summaries separates concerns across three distinct layers:
- Data Definition: Rust structs in
types.rsenforce compile-time safety and runtime validation. - Storage Resolution: The loader module implements a cascading search strategy (custom over bundled) with JSON schema validation.
- Runtime Processing: The service and processor layers handle caching, fingerprinting, and prompt assembly for LLM consumption.
This design enables seamless extensibility—adding new summary formats requires only dropping a JSON file into the templates directory, while the Rust backend guarantees type safety and caching efficiency.
Frequently Asked Questions
How does Meetily validate custom template JSON files?
The system validates custom templates through the validate_and_parse_template function in loader.rs, which deserializes the JSON against the Template struct defined in types.rs. Any schema deviation—such as missing required fields or incorrect data types—triggers an error before the template enters the selection catalogue, preventing malformed prompts from reaching the LLM.
Where does Meetily store custom templates on disk?
Custom templates reside in the directory returned by get_custom_templates_dir(), which defaults to $HOME/.meetily/templates on Unix systems and equivalent paths on Windows. The loader checks this location before falling back to bundled defaults, allowing users to override built-in templates by using identical filenames or add new templates by using unique identifiers.
What is the difference between bundled and custom templates in Meetily?
Bundled templates are compiled into the binary at build time via include_str! in defaults.rs, ensuring availability without external file dependencies. Custom templates are user-provided JSON files stored in the filesystem that the loader discovers at runtime. The architecture checks for custom templates first, enabling users to override or extend default behavior without modifying source code or recompiling the application.
How does the template system optimize LLM API usage?
The system implements content-addressable caching through template_cache_fingerprint in service.rs. This fingerprint hashes the combination of transcript content and template structure, allowing the backend to serve identical summaries from cache rather than making redundant API calls to the language model when processing recurring meeting types with standardized templates.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →