О чём урок
Прежде чем писать какой-либо код, вызовите навык /speech-engine, чтобы изучить правильные паттерны ElevenLabs SDK. Добавьте @elevenlabs/react, @elevenlabs/elevenlabs-js, openai, dotenv и tsx. Добавьте скрипты: speech-engine:create (tsx scripts/create-engine.mts), speech-engine:enable-first-message (tsx scripts/enable-first-message.mts), speech-engine:server (tsx server.mts). Задокументируйте ELEVENLABS_API_KEY, ELEVENLABS_SPEECH_ENGINE_ID, OPENAI_API_KEY и PUBLIC_WS_URL (wss://…/ws из ngrok). Загрузите переменные окружения с помощью dotenv/config. Создайте Speech Engine с помощью elevenlabs.speechEngine.create, используя speechEngine.wsUrl из PUBLIC_WS_URL. Вызовите общий вспомогательный метод, чтобы включить overrides.firstMessage для нового ресурса. Выведите engineId и инструкции для следующих шагов. Обновите существующий Speech Engine (ELEVENLABS_SPEECH_ENGINE_ID), чтобы клиент мог установить overrides.agent.firstMessage. Экспортируйте enableFirstMessageOverride(client, speechEngineId), используя speechEngine.update с overrides: { firstMessage: true }. Общие вспомогательные методы API для ответов OpenAI: ASSISTANT_INSTRUCTIONS, isChatRole, normalizeChatMessages, transcriptToChatMessages, createAssistantReply(messages, signal) и createAssistantStream(messages, signal). Сопоставьте роль agent Speech Engine с ролью assistant OpenAI; сохраняйте ответы лаконичными. Нормализуйте историю перед отправкой в OpenAI: обрежьте содержимое, удалите пустые сообщения, ограничьте количество сообщений и длину каждого сообщения. Добавьте небольшое локальное хранилище, которое позволяет приложению Next.js передавать набранную историю чата автономному серверу Speech Engine. Храните нормализованные ChatMessage[] в .next/cache/voice-history.json по случайному historyId. Экспортируйте createVoiceHistory(messages), linkVoiceHistory(conversationId, historyId) и loadVoiceHistory(conversationId). Сохраняйте это только для демонстрации и с файловым хранением; без базы данных или слоя аутентификации. Автономный HTTP-сервер на порту 3001 с speechEngine.attach(SPEECH_ENGINE_ID, httpServer, "/ws", { debug: true, … }). onTranscript: загрузите любую набранную историю чата, связанную с session.conversationId, добавьте transcriptToChatMessages(transcript), передайте AbortSignal в createAssistantStream и session.sendResponse(stream). Кэшируйте загруженную начальную историю для каждой беседы и кратковременно повторите попытку, поскольку браузер может связать историю сразу после создания голосовой беседы. Записывайте в лог onInit, onClose и onError.
План урока
- 1. package.json
- 2. .env.example
- 3. scripts/create-engine.mts
- 4. scripts/enable-first-message.mts
- 5. lib/speech-engine-overrides.ts
- 6. lib/assistant.ts
- 7. lib/voice-history.ts
- 8. server.mts
Урок входит в полный доступ. Полный текст и видео открываются после оплаты. Первые уроки каждого курса бесплатны.