Appearance
Build Wizard β
The Build Wizard is a conversational, AI-powered interface for creating agents without filling out forms. An AI assistant guides you through the process via natural chat, asking questions and creating your agent automatically.
Overview β
Path: /build or /build/{purpose-slug}
What is it: A 4-step wizard where you chat with an AI Build Wizard that creates your agent on your behalf using the Gnosari Manager MCP (Model Context Protocol).
Key Innovation: No form fields β everything happens through conversation. The Build Wizard agent creates your agent by calling MCP tools in the background.
Wizard Flow β
The wizard follows a 4-step flow (verified against app/composables/features/useStreamlinedAgentWizard.ts):
Step Definitions β
| Step | Key | Component | Can Skip? | Description |
|---|---|---|---|---|
| 0 | purpose | Step0Purpose | No | Select agent type |
| 1 | auth | Step1Auth | Yes* | Login or register |
| 2 | customize | Step2Customize | No | Chat with Build Wizard |
| 3 | success | Step3Success | No | View created agent |
*Auto-skips if already authenticated
Step 0: Purpose β
Goal: Select the type of Gnosari you want to create.
Family-Split Grid β
The wizard presents 41 purpose templates (source: @neomanex/gnosari-agent-purposes, verified via usePurposeFilter.ts) split into two families, action templates leading:
| Family | Group heading | What it is |
|---|---|---|
action | "What do you need done?" | 5 outcome-first templates: ask-someone, recurring-checkin, collect-from-many, qualify-leads, answer-for-me. Framed around the job the Gnosari performs, not a persona |
assistant | "Or start from a ready-made assistant" | The 36 original persona templates (AI Representative, Customer Support, Booking Assistant, etc.) |
Both groups pass through the same search box and industry filter row. An empty group (e.g. a search with zero action-template matches) simply hides β the other group still renders.
Above the grid: a 3-step flow strip sets the mental model before any card is shown β "Pick what your Gnosari does" β "Teach it in a short chat" β "Share it anywhere β website, link, or QR" (with embed/link/QR icons on the third step). This "create β teach β share" strip is what makes template names like "Lead Qualifier" legible to a first-time visitor.
Below the grid: a help card for undecided users, offering a one-click shortcut into the "AI Representative" (my-personal-ai) template.
Purpose Card β
Each card shows: icon, color theme, name, a tagline (one-liner, always visible) that expands to the full description only once the card is selected, up to 3 feature badges, and a "Built for {industry}" badge when an industry filter is active and the template is purpose-built for it (otherwise a "Popular" badge on popular templates).
Each purpose includes:
- Icon and color theme
- Tagline and description
- Default instructions
- Pre-selected traits
- Custom questions for the wizard
family('assistant' | 'action') and, for action templates, ajobid- A
channelsblock (embed / link / qr copy) for the Step 3 share surface
Making a Selection β
Action: Click on a purpose card to select it.
What happens:
- Purpose is set in wizard state (
state.agentType) - Continue button becomes enabled
- Clicking Continue advances to Auth step (or Customize if already logged in)
Direct Links: You can link directly to a specific purpose via /build/{purpose-slug}:
/build/personal-aiβ AI Representative/build/social-buddyβ Social Buddy/build/customer-supportβ Customer Support/build/qualify-leadsβ Qualify Leads (action family)- etc.
Effect of direct links: Wizard initializes with pre-selected purpose and skips directly to Auth step.
Filtering: A search box and a horizontally-scrolling row of industry chips narrow the grid. Selecting an industry mirrors to ?industry= so a campaign link can deep-link straight into a pre-filtered catalog; a ?job= deep link similarly pre-filters to a single job/verb.
Step 1: Auth β
Goal: Ensure user is authenticated before agent creation.
Auto-Skip Behavior β
If user is already authenticated:
- Step automatically skips
- Wizard advances directly to Customize step
- No authentication UI shown
If user is NOT authenticated:
- Login/Register form displayed
- User can choose to login or create account
- On successful auth, wizard advances to Customize
Auth Component Features β
Fields:
- Password
- "Remember me" checkbox
Actions:
- Login button
- "Don't have an account? Register" link
- Social auth (if configured)
Validation:
- Real-time email format validation
- Password minimum length check
- Clear error messages on failed auth
State Watching: The wizard watches auth.isAuthenticated and automatically advances when it changes to true.
Step 2: Customize β
Goal: Chat with the Build Wizard to configure and create your agent.
How It Works β
The Build Wizard is an AI agent that:
- Asks purpose-specific questions
- Collects your answers via conversation
- Calls Gnosari Manager MCP tools to create your agent
- Emits a
conversation.completedevent when done
No form fields: All configuration happens through natural language conversation.
Auto-Message: Purpose Description Seeds the First Chat Message β
When the Customize step opens, the wizard auto-sends the first chat message on the user's behalf (500ms delay) β it does not wait for the user to type anything (verified in Step2Customize.vue):
- If the selected purpose has a
description, the message is: "Hello! I want to create a {name}. Here is what I need it to do: {description}" β the purpose's one-linedescriptionstring flows directly into this auto-message so the Build Wizard agent (which has no built-in knowledge of template types) knows what the selected template is about from turn one. - If no purpose is resolved (or it has no
description), the message falls back to a name-only greeting.
Conversation Flow β
The Build Wizard asks questions based on the selected purpose. Questions are defined in useAgentPurposes.ts for each purpose type.
Example for "AI Representative" purpose:
Question ID: about_youType: textareaLabel: "Tell your AI everything about you" Help Text: "The more you share, the better your AI can represent you. Include your bio, what you do, your links, fun facts - anything someone might ask about!"
Required: Yes Validation: minLength: 50, maxLength: 5000
The wizard will:
- Greet you and explain what it's building
- Ask the purpose-specific question
- Validate your answer (length, format)
- Confirm details with you
- Create the agent via MCP
- Emit
conversation.completedevent
Session Management β
Session ID: A chat session is created when you enter the Customize step.
State tracking:
state.sessionId: Current chat session IDstate.conversationCompleted: Set totruewhen wizard finishesstate.createdAgentId: Agent ID returned by MCPstate.createdAgentName: Agent name returned by MCPstate.createdAgentVisibility: Public, private, or password-protected
Continue button behavior:
- Disabled until
conversation.completedevent received - Enabled when agent creation succeeds
- Clicking advances to Success step
What Happens in the Background β
The Build Wizard calls MCP tools to create your agent:
1. Build Wizard analyzes your answers
2. Constructs agent configuration (name, description, instructions, etc.)
3. Calls Gnosari Manager MCP: mcp__gnosari_manager__create_agent(...)
4. Agent created in database
5. Build Wizard emits conversation.completed event with agent details
6. Step2Customize verifies the claimed agent_id against GET /api/agents/{id}
7. Only on a verified 200: wizard state updates with createdAgentId, createdAgentName
8. Continue button becomes enabledYou see: Natural conversation, then a brief "verifyingβ¦" line while step 6 runs Behind the scenes: Structured API calls via MCP, followed by an authoritative read-back (see Agent Creation Failures below β conversation.completed is a claim from the wizard LLM, not proof)
Step 3: Success β
Goal: Confirm agent creation and provide next actions.
What You See β
Agent Created Card:
- Agent name
- Agent description
- "View Agent" button
- "Chat with Agent" button
- "Embed Widget" button
Created Agent Info (from wizard state):
state.createdAgentId: Navigate to/gnosaris/{id}state.createdAgentName: Display in success messagestate.createdAgentVisibility: Show public link if applicable
Available Actions β
| Action | Button | Destination |
|---|---|---|
| View Agent | Primary | /gnosaris/{id} (agent detail page) |
| Chat with Agent | Secondary | /chat?agent={id} (start conversation) |
| Embed Widget | Secondary | /gnosaris/{id}/embed (get embed code) |
| Create Another | Link | /build (restart wizard) |
No Continue button: This is the final step. Users choose their next action via buttons.
Public Link Display β
If visibility is PUBLIC:
- Show published URL:
https://joina.chat/{agent-uri} - "Copy Link" button
- "Open in New Tab" button
If visibility is PRIVATE or PASSWORD_PROTECTED:
- Show "Agent is private" message
- Link to change access level in settings
Not-Found State β
Path: /build/success (verified against app/pages/build/success.vue)
Because Step 2 now only ever navigates here with a verified id, this state is the escape hatch for everything else that can point at this page: no ?id query param at all, a stale/bookmarked link, a mistyped id, or a cross-account id (404s the same way by convention).
Trigger: ?id missing on mount, or the authoritative GET /api/agents/{id} read returns 404.
Distinct from the generic Error State: not-found knows the Gnosari isn't there; the error state means the load failed for an unknown reason. The two never share copy β no success wording can render in the not-found branch (a separate v-else-if block, not a text swap inside the success branch), and the tab title is reactive to which state is showing.
What you see: An empty-state card ("not found" title/body) with two actions β Build a Gnosari (/build) and View your Gnosaris (/gnosaris).
Wizard State Management β
The wizard maintains state via useStreamlinedAgentWizard() composable.
State Structure β
typescript
interface StreamlinedWizardState {
agentType: string | null // Selected purpose ID
sessionId: string | null // Chat session ID
conversationCompleted: boolean // Has Build Wizard finished?
createdAgentId: number | null // Created agent ID
createdAgentName: string | null // Created agent name
createdAgentVisibility: string | null // 'public', 'private', 'password_protected'
}Default state:
typescript
{
agentType: null,
sessionId: null,
conversationCompleted: false,
createdAgentId: null,
createdAgentName: null,
createdAgentVisibility: null
}State Transitions β
Purpose Step:
- User selects purpose β
setAgentType(purposeId)βstate.agentTypeset
Auth Step:
- User authenticates β
auth.isAuthenticatedchanges β wizard advances
Customize Step:
- Chat session created β
setSessionId(sessionId)βstate.sessionIdset - Wizard completes β
setCreatedAgent(id, name, visibility)β state updated
Success Step:
- Display
state.createdAgentId,state.createdAgentName
Progress Tracking β
Completion Percentage β
The wizard displays a progress bar calculated based on current step:
Formula (from useStreamlinedAgentWizard.ts):
typescript
const completionPercentage = computed(() => {
const index = currentStepIndex.value
if (index === -1) return 0
if (currentStep.value === 'success') return 100
return Math.round((index / (WIZARD_STEPS.length - 1)) * 100)
})Progress values:
- Purpose: 0%
- Auth: 33%
- Customize: 67%
- Success: 100%
Step Navigation β
Current Step: Displayed in wizard header with step name and icon
Breadcrumbs: Show completed steps and current step (steps are not clickable β linear flow)
Can Proceed: Continue button only enabled when step requirements met:
- Purpose:
!!state.agentType - Auth:
auth.isAuthenticated - Customize:
state.conversationCompleted - Success: N/A (final step)
Navigation Controls β
Continue Button β
Visibility: Shown on Purpose and Customize steps only (not Auth or Success)
Enabled state:
- Purpose: Enabled when agent type selected
- Customize: Enabled when
conversation.completedevent received
Action: Calls nextStep() β advances to next step in sequence
Back Button β
Visibility: Shown on all steps except Purpose (first step)
Behavior:
- Calls
previousStep()β goes to previous step - Auto-skips Auth step when going back if user is authenticated
Example: On Customize step, clicking Back goes to Purpose (skips Auth) if authenticated.
Exit/Cancel β
Warning: Wizard tracks unsaved progress via hasUnsavedProgress:
- Returns
falseon Success step (agent already created) - Returns
falseifcreatedAgentIdexists (agent created) - Returns
trueif purpose selected or session started
Exit confirmation:
- If
hasUnsavedProgress === true, show confirmation dialog - "Are you sure you want to leave? Your progress will be lost."
- "Stay" / "Leave" buttons
Purpose-Specific Questions β
Each agent purpose defines custom questions that the Build Wizard asks during the Customize step.
Question Configuration β
Questions are defined in useAgentPurposes.ts for each purpose. Example structure:
typescript
{
id: 'about_you',
type: 'textarea',
label: 'Tell your AI everything about you',
helpText: 'The more you share, the better...',
placeholder: 'Example: I\'m Sarah, a freelance photographer...',
required: true,
validation: { minLength: 50, maxLength: 5000 },
rows: 14
}Question Types β
| Type | UI Component | Validation |
|---|---|---|
textarea | Multi-line text input | minLength, maxLength, required |
text | Single-line input | minLength, maxLength, required |
select | Dropdown | required, options |
multiselect | Multi-select | required, options, minItems, maxItems |
Build Wizard asks these as conversational questions, not form fields.
Build Instructions Function β
Each purpose has a buildInstructions() function that transforms user answers into agent instructions:
typescript
buildInstructions: (answers: QuestionAnswers): string => {
const aboutYou = getStringAnswer(answers, 'about_you')
return `You are an AI clone representing your creator.
About your creator:
${aboutYou}
Your goal is to help visitors learn about your creator authentically.`
}This function:
- Receives user answers from conversation
- Constructs final agent instructions
- Returned to MCP for agent creation
Error Handling β
Authentication Failures β
Symptoms: Login/register fails on Auth step
Handling:
- Display error message below form
- User can retry
- Wizard does NOT auto-advance until successful auth
Conversation Failures β
Symptoms: Build Wizard encounters error during Customize step
Handling:
- Display error message in chat interface
- "Retry" button to restart conversation
- Session preserved β user doesn't lose progress
Agent Creation Failures β
Symptoms: The Build Wizard emits conversation.completed with an agent_id, but the id doesn't verify.
Why verification exists: conversation.completed metadata is authored by the Build Wizard LLM itself β a documented passthrough, not a database guarantee. Step2Customize.vue treats it as a claim and confirms it with an authoritative account-scoped read (GET /api/agents/{id}) before showing any success UI. No verified 200, no celebration.
Handling (verified against Step2Customize.vue):
- On
conversation.completed, a "verifyingβ¦" line appears in the chat surface (#after-messagesslot onGnosariChat) while the read-back runs. - Verified (200): the server's own
id/name/access_levelβ never the event's claim β populate wizard state; completion modal shows. - Verified absence (404): treated as failure immediately, no retry consumed β the agent genuinely doesn't exist.
- Unknown (network error, 5xx, timeout): retried once (5s ceiling per attempt, ~10s worst case) before falling back to failure β a transient blip on the read must not provoke a second create.
- On failure: a
CreateFailureNoticecard renders in the same slot with a Retry button. Retry callsreopenConversation()on the chat session (un-latches it without touching messages orsessionId) and sends a retry prompt into the SAME session β no wizard reset, nothing re-asked, all prior answers preserved.
Missing agent_id entirely (Build Wizard finished without one): treated as an immediate failure β same CreateFailureNotice + retry path, no verification round-trip.
Network Errors β
Symptoms: Connection lost during wizard
Handling:
- Local state preserved in wizard composable
- Reconnection attempts automatically
- User can refresh page and continue from current step
Technical Implementation β
Step 0 Component Decomposition β
Step0Purpose.vue is a thin presentational shell; filtering/family-split state lives in a composable, and each grid region is its own sub-component (app/components/wizard/agent/steps/):
| Piece | Role |
|---|---|
usePurposeFilter.ts (composable) | Search + industry filter state, ?industry= deep-link mirroring, the actionPurposes/assistantPurposes family split, and the "Built for {industry}" badge helper |
Step0FlowStrip.vue | The static 3-step "create β teach β share" strip under the heading |
Step0FilterBar.vue | Search input + scrollable industry-chip row |
Step0PurposeGroup.vue | One family group (title + hint + card grid) β rendered once per family |
Step0PurposeHelp.vue | The "undecided? start with your AI clone" help card |
Step 2 Creation-Verification Components β
| Piece | Role |
|---|---|
Step2Customize.vue | Owns verifying/createFailed/retrying state, the verifyCreatedAgent() read-back, and the #after-messages slot content passed into GnosariChat |
CreateFailureNotice.vue (app/components/wizard/agent/steps/) | The failure card (label/title/message/retry button) rendered when verification fails |
Gnosari Terminology β
The Build Wizard's chrome consistently calls the thing being created a "Gnosari" β never "chatbot" or "AI assistant" (e.g. page title "Build Your Gnosari", exit-confirmation copy, success-step "Chat with your Gnosari", "Your Gnosari's Link"). Keep new copy consistent with this term.
Composable: useStreamlinedAgentWizard() β
Location: app/composables/features/useStreamlinedAgentWizard.ts
Exports:
typescript
{
// State (readonly)
steps, // All step definitions
currentStep, // Current step key
currentStepIndex, // 0-based index
currentStepDefinition, // Current step object
state, // Wizard state (readonly)
// Navigation
goToStep, // Navigate to specific step
nextStep, // Advance to next step
previousStep, // Go back to previous step
// State setters
setAgentType, // Set selected purpose
setSessionId, // Set chat session ID
setCreatedAgent, // Set created agent details
initWithPurpose, // Initialize with pre-selected purpose
reset, // Reset wizard to initial state
// Computed
canProceed, // Can user click Continue?
showContinueButton, // Should Continue button be visible?
completionPercentage, // 0-100 progress value
hasUnsavedProgress // Should warn on exit?
}Usage in components:
vue
<script setup lang="ts">
const wizard = useStreamlinedAgentWizard()
const handleContinue = () => {
wizard.nextStep()
}
const handlePurposeSelect = (purposeId: string) => {
wizard.setAgentType(purposeId)
}
</script>Best Practices β
When to Use the Wizard β
Use Build Wizard for:
- First-time agent creation
- Quick setup with minimal configuration
- Users unfamiliar with agent concepts
- Mobile users (conversational UI works better on small screens)
Use Advanced Form for:
- Complex multi-agent setups
- Precise control over all configuration options
- Bulk agent creation
- Power users who prefer forms
Writing Good Answers β
For "About You" questions (AI Representative):
- Include your bio, expertise, links, contact info
- Write naturally β the AI adapts to your writing style
- Add FAQs people might ask
- Keep it under 2000 words (optimal for RAG retrieval)
For "Knowledge Base" questions (Customer Support):
- Provide URLs to documentation, not raw text
- Organize by topic (product docs, billing, troubleshooting)
- Update regularly β knowledge goes stale
For "Event Details" questions (Event Helper):
- Include date, time, location
- RSVP instructions
- Dress code, parking, special instructions
- Link to event page for details
Testing Your Agent β
After wizard completes:
- Click "Chat with Agent" to test conversation quality
- Ask common questions users might ask
- Check if answers are accurate and on-brand
- Refine instructions if needed via Advanced Form
Troubleshooting β
Continue Button Disabled β
On Purpose step: No agent type selected
- Fix: Click on a purpose card
On Customize step: Conversation not completed
- Fix: Continue chatting with Build Wizard until it confirms agent creation
Auth Step Not Skipping β
Problem: Already logged in but Auth step still shows
- Cause: Auth state not loaded yet
- Fix: Refresh page, or wait 1-2 seconds for auth check
Session Lost on Refresh β
Problem: Refreshing page during Customize step loses chat session
- Cause: Session ID not persisted in URL
- Fix: Wizard restarts β this is expected behavior (chat sessions are ephemeral)
Agent Created But Not Visible β
Problem: Success step shows agent created, but not in agent list
- Cause: Cache not refreshed
- Fix: Navigate to
/gnosarisand refresh page
Next Steps β
- Agent Configuration: Customize agent further via advanced form
- Agent Purposes: Learn about all 41 purpose templates in depth
- Chat Widget: Embed your new agent on your website
- Knowledge Sources: Add RAG knowledge to your agent