Skip to content

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.

  1. You describe the agent in plain language (e.g., “A customer support agent for an e-commerce store”)
  2. The builder sends your description plus organization context to Claude Sonnet 4.6 via OpenRouter
  3. The LLM returns a structured 4-field JSON object enforced by a schemars::JsonSchema schema
  4. 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.

#[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.

All endpoints require authentication and TextAgent:Collection:Create permission.

POST /api/ai-builder/text-agent/generate

Creates 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..."
}
POST /api/ai-builder/text-agent/edit

Refines 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:

ActionEffect
ImproveGeneral quality pass across all fields
MakeConciseShorten while preserving meaning
ImproveToneRefine conversational tone for SMS/WhatsApp
AddExamplesInject sample messages and scenarios
FixCorrect grammar, inconsistencies, formatting
StrengthenSafetyAdd guardrails and boundary rules
AddPersonalityMake the agent voice more distinctive
EnhanceWithOrgDataRe-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.

POST /api/ai-builder/text-agent/custom-edit

Applies 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.

Each action maps to a dedicated prompt template in src/shared/ai_builder/prompts/:

FilePurpose
text_agent_object_generate.mdInitial generation from description
text_agent_object_improve.mdQuality improvement
text_agent_object_make_concise.mdConciseness pass
text_agent_object_fix.mdError and inconsistency fixes
text_agent_object_custom_edit.mdFree-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.

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

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.

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.rs

The 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.