import type { ThreadSnapshot } from "@rakazo/contracts"; import type { BotPersonaProfile } from "./bot-persona"; /** UX/UI/product-design specialists — client workshop Voice flow, not executive handoff. */ export function isClientWorkshopSpecialty(input: { name: string; title: string; description: string; }): boolean { const haystack = `${input.name} ${input.title} ${input.description}`.toLowerCase(); return ( haystack.includes("ux designer") || haystack.includes("ux/ui") || haystack.includes("ui designer") || haystack.includes("product design") || haystack.includes("voice first") || (haystack.includes("design") && (haystack.includes("lead") || haystack.includes("product") || haystack.includes("ux"))) ); } export interface OutgoingHandoff { messageId: string; toBotId: string; toBotName?: string; text: string; } /** Most recent handoff this bot initiated (fromBotId === botId). */ export function extractOutgoingHandoff( snapshot: ThreadSnapshot | null, botId: string, ): OutgoingHandoff | null { if (!snapshot) return null; const members = snapshot.members ?? []; for (const message of [...snapshot.messages].reverse()) { for (let index = message.blocks.length - 1; index >= 0; index -= 1) { const block = message.blocks[index]; if (block?.kind !== "handoff" || block.fromBotId !== botId) continue; const member = members.find((entry) => entry.botId === block.toBotId); return { messageId: message.id, toBotId: block.toBotId, toBotName: member?.name, text: block.text.trim(), }; } } return null; } /** Short spoken line when Voice opens on a bot that just handed work off — no task brief. */ export function voiceHandoffTransferLine( profile: BotPersonaProfile, targetName: string | undefined, ): string { const target = targetName?.trim() || "a specialist"; switch (profile.archetype) { case "cto-executive": return `This goes to ${target} now. Hang up to continue in text.`; case "chief-operator": return `Transferred to ${target}. Hang up to continue in text.`; default: return `Handed to ${target}. Hang up to continue in text.`; } } export function voiceHandoffIdleCaption(targetName: string | undefined): string { const target = targetName?.trim(); return target ? `Handed to ${target} — hang up to continue in text.` : `Handed to a specialist — hang up to continue in text.`; }