MCPcopy Create free account
hub / github.com/adcontextprotocol/adcp / createTavusRouter

Function createTavusRouter

server/src/routes/tavus.ts:328–628  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

326});
327
328export function createTavusRouter() {
329 // Page router: serves GET /video
330 const pageRouter = Router();
331 pageRouter.get("/", (_req, res) => {
332 // Daily.co iframe needs camera, microphone, and autoplay permissions
333 res.setHeader("Permissions-Policy", "camera=*, microphone=*, autoplay=*");
334 res.sendFile(path.join(__dirname, "../../public/video.html"));
335 });
336
337 // API router: POST /api/addie/video/session
338 const apiRouter = Router();
339
340 apiRouter.post("/session", optionalAuth, sessionRateLimiter, async (req, res) => {
341 if (!req.user) {
342 return res.status(401).json({ error: "Please log in to start a video call." });
343 }
344
345 const tavusApiKey = process.env.TAVUS_API_KEY;
346 const personaId = process.env.TAVUS_PERSONA_ID;
347
348 if (!tavusApiKey || !personaId) {
349 return res.status(503).json({ error: "Video chat not configured" });
350 }
351
352 try {
353 const conversationName = `addie-${uuidv4()}`;
354 const rawDisplayName = [req.user.firstName, req.user.lastName].filter(Boolean).join(" ") || req.user.email;
355 const displayName = rawDisplayName.replace(/[\[\]<>{}]/g, "").slice(0, 100);
356
357 // Create a thread to track this video conversation
358 const threadService = getThreadService();
359 const thread = await threadService.getOrCreateThread({
360 channel: "video",
361 external_id: conversationName,
362 user_type: "workos",
363 user_id: req.user.id,
364 user_display_name: displayName,
365 context: { persona_id: personaId },
366 });
367
368 const response = await fetch("https://tavusapi.com/v2/conversations", {
369 method: "POST",
370 headers: {
371 "Content-Type": "application/json",
372 "x-api-key": tavusApiKey,
373 },
374 body: JSON.stringify({
375 persona_id: personaId,
376 conversation_name: conversationName,
377 custom_greeting: `Hi ${displayName.split(" ")[0]}, I'm Addie! How can I help you today?`,
378 // Tavus appends this to the system message sent to our LLM endpoint,
379 // letting us correlate LLM calls back to the thread.
380 conversational_context: `[conductor:thread_id=${thread.thread_id}] The user's name is ${displayName}.`,
381 }),
382 });
383
384 if (!response.ok) {
385 const errorText = await response.text();

Callers 1

setupRoutesMethod · 0.85

Calls 15

getThreadServiceFunction · 0.85
validateLlmSecretFunction · 0.85
initializeTavusClientFunction · 0.85
buildThreadContextFunction · 0.85
sanitizeInputFunction · 0.85
buildVoiceRequestToolsFunction · 0.85
sanitizeSpeakerNameFunction · 0.85
sendChunkFunction · 0.85
resolveUserTierFromDbFunction · 0.85
getOrCreateThreadMethod · 0.80
warnMethod · 0.80
getThreadMethod · 0.80

Tested by

no test coverage detected