Templates

Manage and run AI agent templates and recipes

Overview

Templates provide pre-built AI agent workflows that can be installed, customized, and run. The default repository is agent-recipes on GitHub.

Python API

Load a Template

python
from praisonai.templates import load_template

# Load from default agent-recipes repository
template = load_template("transcript-generator")

# Load from GitHub with version pinning
template = load_template("github:MervinPraison/agent-recipes/transcript-generator@v1.0.0")

# Load from local path
template = load_template("./my-template")

# Load in offline mode (cache only)
template = load_template("transcript-generator", offline=True)

List Available Templates

python
from praisonai.templates import list_templates

# List all templates
templates = list_templates()

# List only cached templates
templates = list_templates(source="cached")

# List in offline mode
templates = list_templates(offline=True)

for t in templates:
    print(f"{t.name} v{t.version}: {t.description}")

Search Templates

python
from praisonai.templates import search_templates

# Search by keyword
results = search_templates("video")

# Search in offline mode
results = search_templates("transcript", offline=True)

Install a Template

python
from praisonai.templates import install_template

# Install to cache
cached = install_template("github:MervinPraison/agent-recipes/transcript-generator")
print(f"Installed to: {cached.path}")

Clear Cache

python
from praisonai.templates import clear_cache

# Clear all cached templates
count = clear_cache()
print(f"Cleared {count} templates")

Concurrent cache access

Multiple agents in the same process and multiple praisonai run invocations that share ~/.praisonai/cache/templates/ can safely call load_template(), install_template(), and clear_cache() in parallel. Since PraisonAI #3420, TemplateCache uses process-wide per-key locks and stages writes into a reserved .staging sibling directory before swapping in with an atomic os.replace(), so concurrent readers never observe a half-populated cache entry and clear() cannot rmtree a write in flight.

No API change — this is a drop-in guarantee for anyone using the template cache from multi-agent or multi-process workflows.

Create Agent from Template

python
from praisonaiagents import Agent

# Create agent from template (lazy loads praisonai.templates)
agent = Agent.from_template("transcript-generator")

# With config overrides
agent = Agent.from_template(
    "transcript-generator",
    config={"output_format": "srt"}
)

Create Workflow from Template

python
from praisonaiagents import AgentFlow

# Create workflow from template
workflow = Workflow.from_template("data-transformer")

# With config and offline mode
workflow = Workflow.from_template(
    "github:MervinPraison/agent-recipes/video-editor@v1.0.0",
    config={"resolution": "1080p"},
    offline=True
)

# Run the workflow
result = workflow.run()

Template URI Formats

FormatExample
Simple nametranscript-generator
Packagepackage:agent_recipes/transcript-generator
GitHubgithub:owner/repo/template
GitHub with refgithub:owner/repo/template@v1.0.0
Local path./my-template or ~/templates/test
HTTP URLhttps://example.com/template.yaml

Available Templates

TemplateDescription
transcript-generatorGenerate transcripts from audio/video
shorts-generatorCreate short-form video clips
video-editorAI-powered video editing
data-transformerTransform data between formats

Custom Templates Directory

Templates can be discovered from multiple directories with precedence:

python
from praisonai.templates import TemplateDiscovery, discover_templates, find_template_path

# Discover templates from custom directories
discovery = TemplateDiscovery(
    custom_dirs=["~/.praisonai/templates", "./my-templates"],
    include_package=True,  # Include agent-recipes package
    include_defaults=True  # Include default search paths
)

# List all discovered templates
templates = discovery.discover_all()
for name, template in templates.items():
    print(f"{name} ({template.source}): {template.path}")

# Find a specific template by name
template = discovery.find_template("my-custom-template")
if template:
    print(f"Found at: {template.path}")

# Get search paths with status
for path, source, exists in discovery.get_search_paths():
    status = "✓" if exists else "✗"
    print(f"{status} [{source}] {path}")

Search Path Precedence

PriorityPathSource
1 (highest)Custom dirs (via custom_dirs)custom
2~/.praisonai/templatescustom
3~/.config/praison/templatescustom
4./.praison/templatesproject
5 (lowest)agent_recipes packagepackage

When the same template name exists in multiple locations, the higher priority version is used.

Input Sentinel Protection

Templates use secure variable substitution that protects user input from injection:

python
from praisonai.templates import TemplateLoader

loader = TemplateLoader()

# User input containing {{...}} syntax is protected
config = {
    "topic": "AI Safety",
    "input": "User says: {{malicious_var}} should not be processed"
}

# The {{malicious_var}} in user input remains literal
# Only template variables like {{topic}} are substituted
workflow_config = loader.load_workflow_config(template)

How It Works

  1. Per-render unique sentinel – A cryptographically random token is generated for each substitution
  2. Protection phase – User-provided values containing {{...}} are replaced with sentinel tokens
  3. Substitution phase – Template variables are substituted normally
  4. Restoration phase – Sentinel tokens are replaced with original user values

This prevents:

  • Template injection attacks
  • Accidental variable resolution in user content
  • Sentinel collision attacks (unique per render)

Security

Templates support allowlists and checksum verification:

python
from praisonai.templates import TemplateSecurity, SecurityConfig

config = SecurityConfig(
    allowed_sources={"github:MervinPraison/agent-recipes"},
    allow_any_github=False
)
security = TemplateSecurity(config=config)