Spaces:
Configuration error
Configuration error
Download src/embed.ts from Curtec/reachy-conversation: direct link, hf CLI and curl.
- Browser
- Download file 2.86 kB
-
https://huggingface.co/spaces/Curtec/reachy-conversation/resolve/main/src/embed.ts
- Command line
-
hf download hf://spaces/Curtec/reachy-conversation/src/embed.ts
-
curl -L -o embed.ts https://huggingface.co/spaces/Curtec/reachy-conversation/resolve/main/src/embed.ts
2.86 kB
| import { connectToHost } from "@pollen-robotics/reachy-mini-sdk/host/embed"; | |
| import { ConversationManager } from "./conversation.ts"; | |
| import { AnimationEngine } from "./animations.ts"; | |
| import { SpeechManager } from "./speech.ts"; | |
| import { UIManager } from "./ui.ts"; | |
| import type { ReachyMini } from "@pollen-robotics/reachy-mini-sdk"; | |
| // Simple safe return to home pose | |
| async function safelyReturnToPose(reachy: ReachyMini) { | |
| try { | |
| reachy.setMotorMode("enabled"); | |
| reachy.setHeadRpyDeg(0, 0, 0); | |
| reachy.setAntennasDeg(0, 0); | |
| reachy.setBodyYawDeg(0); | |
| } catch (e) { | |
| console.error("Failed to return to safe pose:", e); | |
| } | |
| } | |
| export async function main() { | |
| const handle = await connectToHost(); | |
| const reachy = handle.reachy as ReachyMini; | |
| document.documentElement.setAttribute("data-theme", handle.theme); | |
| handle.onThemeChange((t) => document.documentElement.setAttribute("data-theme", t)); | |
| const animations = new AnimationEngine(reachy); | |
| const speech = new SpeechManager(); | |
| const conversation = new ConversationManager(); | |
| const ui = new UIManager({ | |
| onSendMessage: (text) => conversation.sendMessage(text), | |
| onStartListening: () => speech.startListening(), | |
| onStopListening: () => speech.stopListening(), | |
| onConnectOllama: (url, model) => conversation.connectOllama(url, model), | |
| }); | |
| // Handle incoming speech-to-text results | |
| speech.onResult((text) => { | |
| conversation.sendMessage(text); | |
| }); | |
| // When a new conversation message arrives | |
| conversation.onMessage(async (msg) => { | |
| ui.addMessage(msg.role, msg.content); | |
| if (msg.role === "assistant") { | |
| // Animate while speaking | |
| await animations.animateSpeaking(msg.content); | |
| // Speak the response | |
| await speech.speak(msg.content); | |
| animations.stopSpeaking(); | |
| } | |
| }); | |
| // Conversation lull → dance | |
| let lullTimer: ReturnType<typeof setTimeout> | null = null; | |
| const LULL_TIMEOUT_MS = 8000; // 8 seconds of inactivity | |
| function resetLullTimer() { | |
| if (lullTimer) clearTimeout(lullTimer); | |
| lullTimer = setTimeout(async () => { | |
| ui.showStatus("dancing"); | |
| await animations.doRandomDance(); | |
| ui.showStatus("idle"); | |
| }, LULL_TIMEOUT_MS); | |
| } | |
| conversation.onActivity(resetLullTimer); | |
| ui.onActivity(resetLullTimer); | |
| // Safe teardown | |
| handle.onLeave(() => { | |
| if (lullTimer) clearTimeout(lullTimer); | |
| speech.destroy(); | |
| safelyReturnToPose(reachy); | |
| }); | |
| // Initial greeting | |
| setTimeout(() => { | |
| conversation.sendSystem("You are Reachy, a friendly and expressive robot. Keep responses short and engaging."); | |
| }, 1000); | |
| } | |
| void main().catch((err) => { | |
| console.error("[embed] Boot failed:", err); | |
| window.parent.postMessage( | |
| { source: "reachy-mini", type: "embed:error", version: 1, message: String(err), fatal: true }, | |
| window.location.origin, | |
| ); | |
| }); | |