Guided Scripted Practice

Presenter mode with predetermined avatar lines and host-controlled learner turns.

When to use this pattern

Use guided scripted practice when avatar lines are predetermined (lessons, drills, rehearsal) and the host app owns turn flow and feedback. The avatar speaks scripted lines via speak(); learner speech is captured between explicit Start and Stop controls; scoring or hints stay in your UI — not in the avatar conversation output.

Session setup

Mint or start a presenter session with manual speech input. The player-owned start button unlocks audio and requests the microphone once.

const experience = await Experience.startSession({
  experienceId: 'exp_01DEMO1SPANISHCAFE',
  mode: 'presenter',
  speechInputMode: 'manual'
});

experience.on('started', async () => {
  await experience.speak({ text: 'Welcome to the lesson.' });
});

await experience.attach({ container: '#avatar' });

Turn loop

Typical sequence for each scripted line:

  1. await experience.speak({ text: line }) — avatar delivers the tutor line
  2. await experience.startListening() — learner taps Start
  3. await experience.stopListening() — learner taps Stop; pauses do not finalize
  4. Run host-side feedback (pronunciation, rubric, etc.) on utterance.text
  5. Wait for your Next control, then repeat with the next line
async function runPracticeTurn(line) {
  await experience.speak({ text: line });
  await experience.startListening();
}

async function finishPracticeTurn(line) {
  const utterance = await experience.stopListening();
  const feedback = await getReadingFeedback({
    expectedText: line,
    spokenText: utterance.text
  });
  showFeedback(feedback);
  // Host Next button calls runPracticeTurn(nextLine).
}

History and events

Scripted assistant lines and finalized user utterances appear in getConversation(). Feedback objects are application state unless you store them separately. Listen for characterSpeechStarted / characterSpeechEnded, userTranscript, userSpeechStarted / userSpeechEnded, and listeningState — see Events.

For automatic capture without Start/Stop buttons, see Listen Once Capture. For browser-owned replies after each utterance, see Custom Conversation Processor.

Runnable examples

Clone and run the guided-practice examples from examples.liforma.ai:

  • Vanilla JavaScript — port 4002 with ./start guided-practice
  • SvelteKit./start sveltekit (Spanish Tutor on 4001, guided practice on 4002)

Full API detail: Experience API speech section.