Template Plugin
Reusable AI-powered prompt templates with chaining, context management, and tool control.
Overview
The @tokenring-ai/template package provides a comprehensive system for managing and executing reusable AI prompt templates. It enables users to accelerate repetitive tasks through template chaining, context management, and selective tool activation.
Key Features
- Template Registry: Centralized management of named template functions
- Template Chaining: Execute multiple templates in sequence with automatic context passing
- Context Management: Reset specific contexts (chat, memory, events) between template executions
- Tool Control: Enable/disable specific tools during template execution
- Multiple Inputs: Process arrays of inputs within a single template execution
- Circular Reference Detection: Prevent infinite template loops
- State Persistence: Preserve and restore agent tool states during template execution
Core Components
TemplateService
The central service that manages template registration and execution:
import { Agent } from "@tokenring-ai/agent";
import { TemplateService } from "@tokenring-ai/template";
// Access via agent
const templateService = agent.requireServiceByType(TemplateService);
// List available templates
const templates = templateService.listTemplates();
// Get a specific template
const template = templateService.getTemplateByName("myTemplate");
// Run a template
const result = await templateService.runTemplate(
{ templateName: "myTemplate", input: "Hello world" },
agent
);
TemplateChatRequest Schema
interface TemplateChatRequest {
inputs: string[]; // Array of inputs to process
nextTemplate?: string; // Next template to run
reset?: ResetWhat[]; // Context types to reset (chat, memory, events)
activeTools?: string[]; // Tools to enable during execution
}
TemplateResult Schema
interface TemplateResult {
ok: boolean;
output?: string;
response?: any;
error?: string;
nextTemplateResult?: TemplateResult; // For chained templates
}
Template Structure
Templates are async functions that accept an input string and return a TemplateChatRequest:
import { TemplateChatRequest } from "@tokenring-ai/template";
export async function myTemplate(input: string): Promise<TemplateChatRequest> {
return {
inputs: [input],
// Optional parameters
nextTemplate: "followUpTemplate", // Chain to another template
reset: ["chat", "memory"], // Reset context types
activeTools: ["websearch", "wikipedia"], // Enable specific tools
};
}
Usage Examples
Basic Template Execution
// Run a template
const result = await templateService.runTemplate(
{ templateName: "summarize", input: "Long article text..." },
agent
);
console.log(result.output); // AI response
Template Chaining
// First template generates content
export async function generateDraft(input: string): Promise<TemplateChatRequest> {
return {
inputs: [input],
nextTemplate: "improveDraft", // Chain to improvement template
};
}
// Second template improves the draft
export async function improveDraft(input: string): Promise<TemplateChatRequest> {
return {
inputs: [input],
// No nextTemplate, so this ends the chain
};
}
Context Reset and Tool Management
export async function newTaskTemplate(input: string): Promise<TemplateChatRequest> {
return {
inputs: [input],
reset: ["chat", "memory", "events"], // Clear previous context
activeTools: ["websearch", "wikipedia"], // Enable only these tools
};
}
Multiple Inputs
export async function multiStepAnalysis(input: string): Promise<TemplateChatRequest> {
return {
inputs: [
"Analyze this data for trends",
"Identify key insights",
"Generate recommendations"
],
};
}
Configuration
Templates are configured via the TokenRing configuration system:
// Configuration schema is automatically validated
export default {
templates: {
// Template name -> Template function mapping
summarize: async (input: string) => ({
inputs: [input],
}),
translateToFrench: async (input: string) => ({
inputs: [input],
system: "You are a professional translator.",
}),
research: async (input: string) => ({
inputs: [input],
activeTools: ["websearch", "wikipedia"],
nextTemplate: "summarizeFindings",
}),
}
};
The package provides a configuration schema that can be used for validation:
import { TemplateConfigSchema } from "@tokenring-ai/template";
const config = {
templates: TemplateConfigSchema.parse({
summarize: async (input: string) => ({
inputs: [input],
}),
})
};
Error Handling
The package includes comprehensive error handling:
- Missing Templates: Clear error when template not found
- Circular References: Detection and prevention of template chain loops
- Invalid Inputs: Validation of required parameters
- Tool State: Proper restoration of tool states even on errors
Error Examples
// Missing template
try {
await templateService.runTemplate({ templateName: "nonexistent", input: "test" }, agent);
} catch (error) {
console.log(error.message); // "Template not found: nonexistent"
}
// Circular reference
const templateWithCircularRef = async (input: string) => ({
inputs: [input],
nextTemplate: "anotherTemplate", // This could create a circular reference
});
Integration with TokenRing Ecosystem
Plugin Architecture
The package does not have a plugin.ts file. Templates must be registered manually in your application configuration, and the TemplateService can be accessed via the agent system:
export default {
templates: {
myTemplate: myTemplateFunction,
anotherTemplate: anotherTemplateFunction,
}
}
Service Dependencies
- ChatService: For chat execution and tool management
- Agent: For template execution context
State Management
- Tool State: Automatically preserved and restored during template execution
- Context: Supports selective context reset via
resetparameter - Chain Tracking: Prevents circular references in template chains
Development
Creating Templates
- Define your template function:
import { TemplateChatRequest } from "@tokenring-ai/template";
export async function myCustomTemplate(input: string): Promise<TemplateChatRequest> {
return {
inputs: [input],
// Add your template logic here
};
}
- Register it in your configuration:
export default {
templates: {
myCustomTemplate: myCustomTemplate,
}
}
- Use it via the TemplateService:
const result = await templateService.runTemplate(
{ templateName: "myCustomTemplate", input: "Your input here" },
agent
);
Testing Templates
// Test your template function directly
const chatRequest = await myCustomTemplate("test input");
console.log(chatRequest.inputs); // ["test input"]
console.log(chatRequest.nextTemplate); // undefined if no chaining
Running Tests
bun run test
API Reference
TemplateService Methods
listTemplates(): string[]
Returns an array of all registered template names.
getTemplateByName(name: string): TemplateFunction | undefined
Retrieves a template function by name.
runTemplate({ templateName, input, visitedTemplates? }, agent): Promise<TemplateResult>
Executes a template with the given input.
Parameters:
templateName: Name of the template to runinput: Input text for the templatevisitedTemplates: Array to track template chain (internal use)
Returns:
interface TemplateResult {
ok: boolean;
output?: string;
response?: any;
error?: string;
nextTemplateResult?: TemplateResult; // For chained templates
}
License
MIT
Version
0.2.0