Action Schema Format
Added in version 1.0: New optimized action schema format for reduced prompt sizes and improved LLM efficiency.
Overview
Synthetic Heart uses a structured three-tier action schema format designed to optimize LLM prompt size while maintaining full functionality and comprehensive documentation. This format separates concerns between prompt efficiency, validation, and detailed guidance.
The three tiers work together:
Schema Tier: JSON Schema for structure and validation
Brief Tier: Concise description for LLM prompts
Examples Tier: Comprehensive documentation for error correction
Why Three Tiers?
Problem: Traditional action descriptions included everything (schema, examples, instructions) in LLM prompts, leading to excessive token usage and potential context limits.
Solution: Separate what the LLM needs for generation (schema + brief) from what it needs for error correction (full examples).
LLM Prompt -> Schema + Brief (minimal, efficient)
LLM Error -> Corrector uses Schema + Brief + Examples (comprehensive)
Schema Tier
The schema tier defines the action’s structure using JSON Schema standards. This is used for:
Validation: Automatic payload validation before execution
LLM Guidance: Provides structure information in prompts
Type Safety: Ensures correct data types and required fields
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The message content to send"
},
"priority": {
"type": "string",
"enum": ["low", "normal", "high"],
"description": "Message priority level"
},
"interface_path": {
"type": "string",
"description": "Hierarchical interface path (e.g., 'telegram_bot/chat_id/thread_id')"
}
},
"required": ["message"]
}
Supported Field Types:
Type |
Description |
|---|---|
|
Text values |
|
Integer or floating point numbers |
|
True/false values |
|
Lists or arrays of values |
|
Nested objects with their own properties |
Schema Validation Rules:
required: Array of field names that must be presentenum: Restricts values to specific optionsdescription: Human-readable explanation of the fieldtype: JSON Schema type validation
Brief Tier
The brief tier provides a concise, one-line description of what the action does. This appears in LLM prompts and should be:
Under 100 characters
Action-oriented (what it does, not how)
Clear and specific
"brief": "Send a message to a Discord channel"
Good Examples:
"brief": "Schedule a reminder for future delivery"
"brief": "Add an entry to the personal diary"
"brief": "Retrieve weather information for a location"
Poor Examples:
"brief": "This action allows you to send messages through the Discord interface by providing message content and optionally specifying priority and recipient" # Too long
"brief": "Message sender" # Too vague
Examples Tier
The examples tier contains comprehensive documentation used only when the LLM makes mistakes. This includes:
Detailed descriptions with context and edge cases
Usage instructions and best practices
Multiple examples covering different scenarios
Common pitfalls and error scenarios
"examples": {
"description": "Send a message through Discord with optional priority and recipient targeting. Messages are delivered asynchronously and support rich text formatting.",
"instructions": {
"when_to_use": "Use this action to communicate with users through Discord channels or direct messages.",
"common_pitfalls": [
"Ensure recipient exists and bot has permission to message them",
"High priority messages may be rate-limited",
"Empty messages will be rejected"
],
"notes": [
"Messages support Discord markdown formatting",
"Bot must be in the target server/channel",
"Rate limits apply based on bot permissions"
]
},
"examples": [
{
"scenario": "Send a simple message to a channel",
"payload": {
"message": "Hello everyone!"
}
},
{
"scenario": "Send high-priority message to specific user",
"payload": {
"message": "Urgent: System maintenance in 5 minutes",
"priority": "high",
"interface_path": "discord_interface/guild123/channel456"
}
},
{
"scenario": "Send formatted message with priority",
"payload": {
"message": "**Important Update:** New features available",
"priority": "normal"
}
}
]
}
Complete Action Definition
Here’s a complete action definition combining all three tiers:
def get_supported_actions(self) -> dict:
return {
"message_discord": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The message content to send"
},
"priority": {
"type": "string",
"enum": ["low", "normal", "high"],
"description": "Message priority level"
},
"recipient": {
"type": "string",
"description": "Target recipient (@user or #channel)"
}
},
"required": ["message"]
},
"brief": "Send a message to a Discord channel",
"examples": {
"description": "Send a message through Discord with optional priority and recipient targeting.",
"instructions": {
"when_to_use": "Use to communicate with Discord users and channels.",
"common_pitfalls": [
"Bot must have send permissions in target channel",
"Rate limits may delay high-priority messages"
]
},
"examples": [
{
"scenario": "Basic channel message",
"payload": {"message": "Hello world!"}
},
{
"scenario": "Priority message to user",
"payload": {
"message": "Meeting in 10 minutes",
"priority": "high",
"interface_path": "discord_interface/guild123/user456"
}
}
]
}
}
}
Migration Guide
From Old Format:
# Old format (still supported)
"my_action": {
"description": "Do something with a value",
"required_fields": ["value"],
"optional_fields": ["option"],
"instructions": {...}
}
To New Format:
# New optimized format
"my_action": {
"schema": {
"type": "object",
"properties": {
"value": {"type": "string", "description": "The value to process"},
"option": {"type": "boolean", "description": "Optional flag"}
},
"required": ["value"]
},
"brief": "Do something with a value",
"examples": {
"description": "Do something with a value and optional configuration",
"instructions": {...},
"examples": [...]
}
}
Automatic Conversion:
The system automatically converts old format actions to new format. No immediate migration required, but new plugins should use the new format for optimal performance.
Best Practices
Schema Design:
Use appropriate JSON Schema types for all fields
Include
enumconstraints where applicableProvide clear, concise field descriptions
Mark truly required fields in the
requiredarray
Brief Descriptions:
Keep under 100 characters
Start with action verb (Send, Get, Create, etc.)
Focus on outcome, not implementation
Be specific about the action’s purpose
Examples Documentation:
Cover primary use cases first
Include edge cases and error scenarios
Document rate limits, permissions, and constraints
Provide realistic payload examples
Performance Considerations:
The
brieffield appears in every LLM prompt - keep it minimalThe
examplestier is only loaded during error correctionWell-designed schemas reduce validation errors and corrector usage
Validation:
Test schemas with various payloads
Ensure
requiredfields are actually required for the actionValidate enum values are appropriate and complete
Note: when LLM responses are parsed by the interface, any unregistered
top‑level keys (for example a stray "message" field alongside
"actions") will cause the system to invoke the corrector before
attempting execution. This guards against silent drops of unwanted metadata
and prompts the model to resend a clean actions‑only response.
For implementation examples, see plugins/ai_diary.py (new format) or plugins/terminal.py (legacy format automatically converted).