AI Instruction Builder
The AI instruction builder generates all four text agent configuration fields — purpose, custom_instructions, escalation_instructions, and restricted_topics — from a natural language description. It uses structured output to produce a consistent JSON object, and supports iterative refinement through predefined actions or free-text edits.
How It Works
Section titled “How It Works”- You describe the agent in plain language (e.g., “A customer support agent for an e-commerce store”)
- The builder sends your description plus organization context to Claude Sonnet 4.6 via OpenRouter
- The LLM returns a structured 4-field JSON object enforced by a
schemars::JsonSchemaschema - All four form fields populate at once
After generating, you refine with toolbar actions (Improve, Make Concise, Fix, etc.) or a free-text custom edit. Each refinement replaces all four fields atomically. A Revert button restores the previous state.
Response Type
Section titled “Response Type”#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, schemars::JsonSchema)]#[schemars(deny_unknown_fields)]pub struct TextAgentAiResponse { pub purpose: String, pub custom_instructions: String, pub escalation_instructions: String, pub restricted_topics: String,}The schemars::JsonSchema derive enables OpenAI structured output via aisdk .schema::<TextAgentAiResponse>(), guaranteeing valid JSON with all four fields present.
API Endpoints
Section titled “API Endpoints”All endpoints require authentication and TextAgent:Collection:Create permission.
Generate
Section titled “Generate”POST /api/ai-builder/text-agent/generateCreates all four fields from a description. Organization context (profile, hours, contact info) is automatically appended.
// Request{ "user_description": "A customer support agent for an e-commerce store that handles order inquiries" }
// Response{ "purpose": "You are a customer support agent for [Store Name]...", "custom_instructions": "## Personality & Tone\n- Friendly and helpful...", "escalation_instructions": "Escalate to human when:\n- User requests...", "restricted_topics": "- Do not discuss competitor products..."}Edit (Predefined Action)
Section titled “Edit (Predefined Action)”POST /api/ai-builder/text-agent/editRefines all four fields using a predefined action. The current field values are sent along with the action.
// Request{ "action": "Improve", "current": { "purpose": "...", "custom_instructions": "...", "escalation_instructions": "...", "restricted_topics": "..." }}Available actions:
| Action | Effect |
|---|---|
Improve | General quality pass across all fields |
MakeConcise | Shorten while preserving meaning |
ImproveTone | Refine conversational tone for SMS/WhatsApp |
AddExamples | Inject sample messages and scenarios |
Fix | Correct grammar, inconsistencies, formatting |
StrengthenSafety | Add guardrails and boundary rules |
AddPersonality | Make the agent voice more distinctive |
EnhanceWithOrgData | Re-inject organization context into instructions |
The EnhanceWithOrgData action re-fetches organization profile and hours data and includes it in the prompt. Other actions operate only on the current field values.
Custom Edit
Section titled “Custom Edit”POST /api/ai-builder/text-agent/custom-editApplies a free-text instruction to refine the current fields.
// Request{ "edit_instruction": "Add a Spanish greeting option for bilingual support", "current": { "purpose": "...", "custom_instructions": "...", "escalation_instructions": "...", "restricted_topics": "..." }}All three endpoints return the same TextAgentAiResponse shape.
Prompt Templates
Section titled “Prompt Templates”Each action maps to a dedicated prompt template in src/shared/ai_builder/prompts/:
| File | Purpose |
|---|---|
text_agent_object_generate.md | Initial generation from description |
text_agent_object_improve.md | Quality improvement |
text_agent_object_make_concise.md | Conciseness pass |
text_agent_object_fix.md | Error and inconsistency fixes |
text_agent_object_custom_edit.md | Free-text edit handling |
Prompts are tailored for text messaging — they enforce short messages (1–3 sentences), conversational tone, sparing emoji use, and async messaging patterns.
Organization Context
Section titled “Organization Context”The generate endpoint and EnhanceWithOrgData action inject organization data into the prompt. This data comes from the organization_profile and organization_hours tables:
- Business name, industry, description, services
- Contact info (phone, email, website, address)
- Languages and timezone
- Operating hours per day of week
- After-hours message and emergency contact
UI Integration
Section titled “UI Integration”The builder component sits above the Purpose field in the text agent create/edit form. It provides:
- A text input for the initial description with a Generate All Fields button
- A toolbar with the eight refinement action buttons
- A custom edit input with an Apply button
- A Revert button that restores all four fields to their pre-edit state (single-level undo)
- Skeleton loading UI during generation
- Inline error messages on failure
After AI generation, all four textarea fields remain manually editable.
Module Structure
Section titled “Module Structure”src/shared/ai_builder/├── types/│ ├── ai_builder_area_type.rs # AiBuilderArea enum (VoiceAgent | TextAgent)│ ├── text_agent_ai_response_type.rs # 4-field structured output│ ├── text_agent_generate_request_type.rs│ ├── text_agent_edit_request_type.rs│ └── text_agent_custom_edit_request_type.rs├── api/│ ├── text_agent_generate_api.rs # POST /api/ai-builder/text-agent/generate│ ├── text_agent_edit_api.rs # POST /api/ai-builder/text-agent/edit│ └── text_agent_custom_edit_api.rs # POST /api/ai-builder/text-agent/custom-edit├── prompts/ # 10 text-agent-specific prompt templates└── components/ ├── ai_generate_instructions_component.rs └── ai_instruction_toolbar_component.rsThe shared/ai_builder/ module also contains the voice agent builder. Both share the AiBuilderArea enum and reusable UI components, but use separate types, endpoints, and prompts.