feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
'use client' ;
2026-04-06 14:43:27 -04:00
import { createContext , useContext , useState , useRef , useCallback , useEffect , type ReactNode } from 'react' ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
import type { WizardFormData } from './WizardContainer' ;
// ─── Types ───────────────────────────────────────────────────────────────────
export interface TranscriptEntry {
role : 'user' | 'agent' ;
text : string ;
timestamp : number ;
}
type ConnectionStatus = 'idle' | 'connecting' | 'active' | 'ending' | 'error' ;
2026-04-06 14:43:27 -04:00
export interface PendingContact {
name : string ;
email : string ;
}
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
interface VoiceAgentContextValue {
status : ConnectionStatus ;
errorMessage : string | null ;
isMicActive : boolean ;
toggleMic : ( ) = > void ;
transcript : TranscriptEntry [ ] ;
selections : Partial < WizardFormData > ;
isAnalyzingSite : boolean ;
2026-03-28 14:58:56 +01:00
isGeneratingBrief : boolean ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
userAmplitude : number ;
agentAmplitude : number ;
startConversation : ( ) = > Promise < void > ;
endConversation : ( ) = > void ;
completedBrief : string | null ;
completedFormData : WizardFormData | null ;
2026-04-06 14:43:27 -04:00
pendingContact : PendingContact | null ;
confirmContact : ( ) = > void ;
updatePendingContact : ( field : 'name' | 'email' , value : string ) = > void ;
canReconnect : boolean ;
reconnect : ( ) = > Promise < void > ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
// ─── Context ─────────────────────────────────────────────────────────────────
const VoiceAgentContext = createContext < VoiceAgentContextValue | null > ( null ) ;
export function useVoiceAgent() {
const ctx = useContext ( VoiceAgentContext ) ;
if ( ! ctx ) throw new Error ( 'useVoiceAgent must be used within VoiceAgentProvider' ) ;
return ctx ;
}
// ─── Audio Helpers ───────────────────────────────────────────────────────────
function int16ToFloat32 ( int16 : Int16Array ) : Float32Array {
const float32 = new Float32Array ( int16 . length ) ;
for ( let i = 0 ; i < int16 . length ; i ++ ) {
float32 [ i ] = int16 [ i ] / 32768 ;
}
return float32 ;
}
function base64ToInt16 ( base64 : string ) : Int16Array {
const binary = atob ( base64 ) ;
const bytes = new Uint8Array ( binary . length ) ;
for ( let i = 0 ; i < binary . length ; i ++ ) {
bytes [ i ] = binary . charCodeAt ( i ) ;
}
return new Int16Array ( bytes . buffer ) ;
}
function arrayBufferToBase64 ( buffer : ArrayBuffer ) : string {
const bytes = new Uint8Array ( buffer ) ;
let binary = '' ;
for ( let i = 0 ; i < bytes . length ; i ++ ) {
binary += String . fromCharCode ( bytes [ i ] ) ;
}
return btoa ( binary ) ;
}
// ─── Audio Worklet Processor Code ────────────────────────────────────────────
const WORKLET_CODE = `
class AudioRecordingWorklet extends AudioWorkletProcessor {
buffer = new Int16Array ( 2048 ) ;
bufferWriteIndex = 0 ;
process ( inputs ) {
if ( inputs [ 0 ] . length ) {
const channel0 = inputs [ 0 ] [ 0 ] ;
for ( let i = 0 ; i < channel0 . length ; i ++ ) {
const sample = Math . max ( - 1 , Math . min ( 1 , channel0 [ i ] ) ) ;
this . buffer [ this . bufferWriteIndex ++ ] = sample * 32767 ;
if ( this . bufferWriteIndex >= this . buffer . length ) {
this . port . postMessage ( {
event : 'chunk' ,
data : { int16arrayBuffer : this.buffer.slice ( 0 , this . bufferWriteIndex ) . buffer } ,
} ) ;
this . bufferWriteIndex = 0 ;
}
}
}
return true ;
}
}
registerProcessor ( 'audio-recorder-worklet' , AudioRecordingWorklet ) ;
` ;
// ─── Default Form Data (mirror WizardContainer) ─────────────────────────────
const DEFAULT_FORM_DATA : WizardFormData = {
services : [ ] ,
aiEnabled : false ,
aiTypes : [ ] ,
industry : null ,
scope : '' ,
timeline : null ,
name : '' ,
company : '' ,
email : '' ,
phone : '' ,
contactPreference : 'email' ,
currentSiteUrl : '' ,
currentSiteThoughts : '' ,
} ;
// ─── Provider Component ──────────────────────────────────────────────────────
interface VoiceAgentProviderProps {
locale : string ;
children : ReactNode ;
}
export default function VoiceAgentProvider ( { locale , children } : VoiceAgentProviderProps ) {
const [ status , setStatus ] = useState < ConnectionStatus > ( 'idle' ) ;
const [ errorMessage , setErrorMessage ] = useState < string | null > ( null ) ;
const [ isMicActive , setIsMicActive ] = useState ( true ) ;
const [ transcript , setTranscript ] = useState < TranscriptEntry [ ] > ( [ ] ) ;
const [ selections , setSelections ] = useState < Partial < WizardFormData > > ( { } ) ;
const [ isAnalyzingSite , setIsAnalyzingSite ] = useState ( false ) ;
2026-03-28 14:58:56 +01:00
const [ isGeneratingBrief , setIsGeneratingBrief ] = useState ( false ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const [ userAmplitude , setUserAmplitude ] = useState ( 0 ) ;
const [ agentAmplitude , setAgentAmplitude ] = useState ( 0 ) ;
const [ completedBrief , setCompletedBrief ] = useState < string | null > ( null ) ;
const [ completedFormData , setCompletedFormData ] = useState < WizardFormData | null > ( null ) ;
2026-04-06 14:43:27 -04:00
const [ pendingContact , setPendingContact ] = useState < PendingContact | null > ( null ) ;
const [ canReconnect , setCanReconnect ] = useState ( false ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
2026-03-28 14:42:04 +01:00
const turnCompleteRef = useRef ( true ) ;
2026-03-28 14:51:26 +01:00
const briefSubmittedRef = useRef ( false ) ;
2026-04-06 14:43:27 -04:00
const pendingContactRef = useRef < PendingContact | null > ( null ) ;
const reconnectTranscriptRef = useRef < TranscriptEntry [ ] > ( [ ] ) ;
const statusRef = useRef < ConnectionStatus > ( 'idle' ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const wsRef = useRef < WebSocket | null > ( null ) ;
const mediaStreamRef = useRef < MediaStream | null > ( null ) ;
const audioContextRef = useRef < AudioContext | null > ( null ) ;
const playbackContextRef = useRef < AudioContext | null > ( null ) ;
const nextStartTimeRef = useRef ( 0 ) ;
const analyserRef = useRef < AnalyserNode | null > ( null ) ;
const animFrameRef = useRef < number > ( 0 ) ;
2026-04-06 14:43:27 -04:00
// Keep statusRef in sync for use in closures
useEffect ( ( ) = > { statusRef . current = status ; } , [ status ] ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const addTranscript = useCallback ( ( role : 'user' | 'agent' , text : string ) = > {
2026-03-28 14:42:04 +01:00
setTranscript ( ( prev ) = > {
const last = prev [ prev . length - 1 ] ;
// Append to last entry if same role and turn is still ongoing
if ( last && last . role === role && ! turnCompleteRef . current ) {
return [ . . . prev . slice ( 0 , - 1 ) , { . . . last , text : last.text + text } ] ;
}
turnCompleteRef . current = false ;
return [ . . . prev , { role , text , timestamp : Date.now ( ) } ] ;
} ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
} , [ ] ) ;
const trackAmplitude = useCallback ( ( ) = > {
if ( ! analyserRef . current ) return ;
const data = new Uint8Array ( analyserRef . current . fftSize ) ;
analyserRef . current . getByteTimeDomainData ( data ) ;
let sum = 0 ;
for ( let i = 0 ; i < data . length ; i ++ ) {
const v = ( data [ i ] - 128 ) / 128 ;
sum += v * v ;
}
setUserAmplitude ( Math . sqrt ( sum / data . length ) ) ;
animFrameRef . current = requestAnimationFrame ( trackAmplitude ) ;
} , [ ] ) ;
const handleToolCall = useCallback (
async ( name : string , args : Record < string , unknown > , callId : string ) = > {
if ( name === 'update_selections' ) {
setSelections ( ( prev ) = > ( { . . . prev , . . . ( args as Partial < WizardFormData > ) } ) ) ;
return JSON . stringify ( { success : true } ) ;
}
if ( name === 'analyze_website' ) {
setIsAnalyzingSite ( true ) ;
try {
const res = await fetch ( '/api/analyze-site' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' } ,
body : JSON.stringify ( { url : args.url } ) ,
} ) ;
const data = await res . json ( ) ;
setIsAnalyzingSite ( false ) ;
return JSON . stringify ( data ) ;
} catch {
setIsAnalyzingSite ( false ) ;
return JSON . stringify ( { success : false , summary : "I wasn't able to analyze that site." } ) ;
}
}
2026-04-06 14:43:27 -04:00
if ( name === 'request_contact' ) {
const { name : contactName , email : contactEmail } = args as { name : string ; email : string } ;
const contact = { name : contactName , email : contactEmail } ;
setPendingContact ( contact ) ;
pendingContactRef . current = contact ;
2026-04-06 15:52:53 -04:00
// Respond immediately so Gemini doesn't timeout waiting for a tool response.
// The agent is told to wait — user confirmation comes as a text message via confirmContact().
return JSON . stringify ( { success : true , message : 'Contact card is now shown on screen. Wait for the user to review and confirm before calling complete_brief. Do not proceed until you hear confirmation.' } ) ;
2026-04-06 14:43:27 -04:00
}
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
if ( name === 'complete_brief' ) {
2026-03-28 14:51:26 +01:00
// Prevent duplicate submissions
if ( briefSubmittedRef . current ) return JSON . stringify ( { success : true , message : 'Brief already submitted' } ) ;
briefSubmittedRef . current = true ;
2026-03-28 14:58:56 +01:00
setIsGeneratingBrief ( true ) ;
2026-03-28 14:51:26 +01:00
console . log ( '[VoiceAgent] complete_brief called, generating...' ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
try {
2026-03-28 15:11:18 +01:00
const toolArgs = args as Partial < WizardFormData > & { conversationSummary? : string } ;
const summary = toolArgs . conversationSummary ? ? '' ;
const existingScope = toolArgs . scope ? ? '' ;
const combinedScope = [ existingScope , summary ] . filter ( Boolean ) . join ( '\n\n' ) ;
2026-04-06 14:43:27 -04:00
// Use confirmed contact details from the on-screen card if available
const contactName = pendingContactRef . current ? . name ? ? toolArgs . name ? ? '' ;
const contactEmail = pendingContactRef . current ? . email ? ? toolArgs . email ? ? '' ;
const formData = { . . . DEFAULT_FORM_DATA , . . . toolArgs , name : contactName , email : contactEmail , scope : combinedScope , locale } ;
2026-03-28 15:11:18 +01:00
delete ( formData as Record < string , unknown > ) . conversationSummary ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const res = await fetch ( '/api/configure' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' } ,
body : JSON.stringify ( formData ) ,
} ) ;
const data = ( await res . json ( ) ) as { success : boolean ; brief? : string } ;
2026-03-28 14:51:26 +01:00
console . log ( '[VoiceAgent] Brief API response:' , data . success ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
if ( data . success && data . brief ) {
setCompletedBrief ( data . brief ) ;
setCompletedFormData ( formData as WizardFormData ) ;
2026-03-28 14:51:26 +01:00
console . log ( '[VoiceAgent] completedBrief and completedFormData set' ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
2026-03-28 14:51:26 +01:00
return JSON . stringify ( { success : true } ) ;
} catch ( err ) {
console . error ( '[VoiceAgent] Brief generation failed:' , err ) ;
briefSubmittedRef . current = false ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
return JSON . stringify ( { success : false , error : 'Brief generation failed' } ) ;
}
}
return JSON . stringify ( { error : ` Unknown tool: ${ name } ` } ) ;
} ,
[ locale ] ,
) ;
const playAudioChunk = useCallback ( ( base64Audio : string ) = > {
2026-03-28 14:34:19 +01:00
if ( ! playbackContextRef . current ) return ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const ctx = playbackContextRef . current ;
const int16 = base64ToInt16 ( base64Audio ) ;
const float32 = int16ToFloat32 ( int16 ) ;
const buffer = ctx . createBuffer ( 1 , float32 . length , 24000 ) ;
buffer . copyToChannel ( new Float32Array ( float32 ) , 0 ) ;
const source = ctx . createBufferSource ( ) ;
source . buffer = buffer ;
source . connect ( ctx . destination ) ;
if ( nextStartTimeRef . current < ctx . currentTime ) {
nextStartTimeRef . current = ctx . currentTime ;
}
source . start ( nextStartTimeRef . current ) ;
nextStartTimeRef . current += buffer . duration ;
const amplitude = Math . sqrt ( float32 . reduce ( ( sum , v ) = > sum + v * v , 0 ) / float32 . length ) ;
setAgentAmplitude ( amplitude ) ;
} , [ ] ) ;
const startConversation = useCallback ( async ( ) = > {
setStatus ( 'connecting' ) ;
setErrorMessage ( null ) ;
2026-04-06 14:43:27 -04:00
setCanReconnect ( false ) ;
// Only reset transcript/selections on fresh start (not reconnect)
if ( reconnectTranscriptRef . current . length === 0 ) {
setTranscript ( [ ] ) ;
setSelections ( { } ) ;
setPendingContact ( null ) ;
pendingContactRef . current = null ;
}
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
setCompletedBrief ( null ) ;
setCompletedFormData ( null ) ;
2026-03-28 14:51:26 +01:00
briefSubmittedRef . current = false ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
try {
const tokenRes = await fetch ( '/api/gemini-token' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' } ,
body : JSON.stringify ( { locale } ) ,
} ) ;
const tokenData = await tokenRes . json ( ) ;
2026-03-28 14:04:20 +01:00
if ( ! tokenData . success ) throw new Error ( ` Token generation failed: ${ tokenData . error ? ? tokenRes . status } ` ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const { apiKey , model , config } = tokenData ;
const stream = await navigator . mediaDevices . getUserMedia ( {
2026-03-28 14:34:19 +01:00
audio : { channelCount : 1 , echoCancellation : true , noiseSuppression : true } ,
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
} ) ;
mediaStreamRef . current = stream ;
2026-03-28 14:34:19 +01:00
// Create AudioContexts during user gesture (required on mobile)
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const audioCtx = new AudioContext ( { sampleRate : 16000 } ) ;
audioContextRef . current = audioCtx ;
2026-03-28 14:34:19 +01:00
// Playback context MUST be created here (user gesture) for mobile
playbackContextRef . current = new AudioContext ( { sampleRate : 24000 } ) ;
nextStartTimeRef . current = playbackContextRef . current . currentTime ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const source = audioCtx . createMediaStreamSource ( stream ) ;
const analyser = audioCtx . createAnalyser ( ) ;
analyser . fftSize = 256 ;
source . connect ( analyser ) ;
analyserRef . current = analyser ;
// Register AudioWorklet
const workletBlob = new Blob ( [ WORKLET_CODE ] , { type : 'application/javascript' } ) ;
const workletUrl = URL . createObjectURL ( workletBlob ) ;
await audioCtx . audioWorklet . addModule ( workletUrl ) ;
URL . revokeObjectURL ( workletUrl ) ;
const workletNode = new AudioWorkletNode ( audioCtx , 'audio-recorder-worklet' ) ;
source . connect ( workletNode ) ;
workletNode . connect ( audioCtx . destination ) ;
// Open WebSocket to Gemini Live API
const wsUrl = ` wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key= ${ apiKey } ` ;
2026-03-28 14:19:57 +01:00
console . log ( '[VoiceAgent] Connecting to WebSocket...' ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const ws = new WebSocket ( wsUrl ) ;
wsRef . current = ws ;
2026-03-28 14:19:57 +01:00
// Timeout if setup doesn't complete within 10 seconds
const setupTimeout = setTimeout ( ( ) = > {
if ( ws . readyState !== WebSocket . CLOSED ) {
console . error ( '[VoiceAgent] Setup timed out after 10s' ) ;
ws . close ( ) ;
setStatus ( 'error' ) ;
setErrorMessage ( 'Connection timed out. Please try again.' ) ;
}
} , 10 _000 ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
ws . onopen = ( ) = > {
2026-03-28 14:27:11 +01:00
console . log ( '[VoiceAgent] WebSocket opened, sending setup...' ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
ws . send ( JSON . stringify ( {
2026-03-28 14:27:11 +01:00
setup : {
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
model : ` models/ ${ model } ` ,
2026-03-28 14:27:11 +01:00
generationConfig : {
responseModalities : config.responseModalities ,
speechConfig : config.speechConfig ,
} ,
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
systemInstruction : {
parts : [ { text : config.systemInstruction } ] ,
} ,
tools : config.tools ,
} ,
} ) ) ;
} ;
// Send audio chunks from worklet
workletNode . port . onmessage = ( event ) = > {
if ( event . data . event === 'chunk' && ws . readyState === WebSocket . OPEN ) {
const base64 = arrayBufferToBase64 ( event . data . data . int16arrayBuffer ) ;
ws . send ( JSON . stringify ( {
realtimeInput : {
2026-03-28 14:15:42 +01:00
audio : {
data : base64 ,
mimeType : 'audio/pcm;rate=16000' ,
} ,
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
} ,
} ) ) ;
}
} ;
ws . onmessage = async ( event ) = > {
2026-03-28 14:27:11 +01:00
let raw : string ;
if ( event . data instanceof Blob ) {
raw = await event . data . text ( ) ;
} else {
raw = event . data as string ;
}
const msg = JSON . parse ( raw ) ;
2026-03-28 14:15:42 +01:00
console . log ( '[VoiceAgent] Message:' , JSON . stringify ( msg ) . slice ( 0 , 200 ) ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
2026-03-28 14:15:42 +01:00
// Setup complete — Gemini sends back a setupComplete message
if ( msg . setupComplete !== undefined ) {
console . log ( '[VoiceAgent] Setup complete, session active' ) ;
2026-03-28 14:19:57 +01:00
clearTimeout ( setupTimeout ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
setStatus ( 'active' ) ;
trackAmplitude ( ) ;
2026-04-06 14:43:27 -04:00
// If reconnecting, seed with prior conversation context
const priorTranscript = reconnectTranscriptRef . current ;
if ( priorTranscript . length > 0 ) {
const summary = priorTranscript
. map ( ( e ) = > ` ${ e . role === 'user' ? 'User' : 'Agent' } : ${ e . text } ` )
. join ( '\n' ) ;
ws . send ( JSON . stringify ( {
realtimeInput : {
text : ` We were having a conversation but got disconnected. Here is what was discussed so far: \ n \ n ${ summary } \ n \ nPlease acknowledge the reconnection briefly and continue where we left off. ` ,
} ,
} ) ) ;
reconnectTranscriptRef . current = [ ] ;
} else {
// Prompt the agent to introduce itself
ws . send ( JSON . stringify ( {
realtimeInput : {
text : 'Hello, please introduce yourself.' ,
} ,
} ) ) ;
}
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
return ;
}
// Server content (audio + text)
if ( msg . serverContent ) {
const parts = msg . serverContent . modelTurn ? . parts ;
if ( parts ) {
for ( const part of parts ) {
2026-03-28 14:34:19 +01:00
if ( part . inlineData ) {
console . log ( '[VoiceAgent] Audio chunk received, mime:' , part . inlineData . mimeType , 'len:' , part . inlineData . data ? . length ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
playAudioChunk ( part . inlineData . data ) ;
}
if ( part . text ) {
2026-03-28 14:34:19 +01:00
console . log ( '[VoiceAgent] Text:' , part . text ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
addTranscript ( 'agent' , part . text ) ;
}
}
}
// Input transcription
if ( msg . serverContent . inputTranscription ? . text ) {
addTranscript ( 'user' , msg . serverContent . inputTranscription . text ) ;
}
// Output transcription
if ( msg . serverContent . outputTranscription ? . text ) {
addTranscript ( 'agent' , msg . serverContent . outputTranscription . text ) ;
}
2026-03-28 14:42:04 +01:00
// Turn complete — next output starts a new transcript entry
if ( msg . serverContent . turnComplete || msg . serverContent . generationComplete ) {
turnCompleteRef . current = true ;
}
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
// Tool call
if ( msg . toolCall ) {
const calls = msg . toolCall . functionCalls ;
if ( calls ) {
const responses = [ ] ;
for ( const call of calls ) {
const result = await handleToolCall ( call . name , call . args ? ? { } , call . id ) ;
2026-04-06 15:52:53 -04:00
responses . push ( { id : call.id , name : call.name , response : { result } } ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
2026-04-06 15:52:53 -04:00
ws . send ( JSON . stringify ( { toolResponse : { functionResponses : responses } } ) ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
}
} ;
2026-03-28 14:04:20 +01:00
ws . onerror = ( e ) = > {
console . error ( '[VoiceAgent] WebSocket error:' , e ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
setStatus ( 'error' ) ;
setErrorMessage ( 'Connection error. Please try again.' ) ;
} ;
2026-03-28 14:04:20 +01:00
ws . onclose = ( e ) = > {
console . log ( '[VoiceAgent] WebSocket closed:' , e . code , e . reason ) ;
2026-04-06 14:43:27 -04:00
// Clean up audio but preserve transcript and selections
cancelAnimationFrame ( animFrameRef . current ) ;
if ( mediaStreamRef . current ) {
mediaStreamRef . current . getTracks ( ) . forEach ( ( track ) = > track . stop ( ) ) ;
mediaStreamRef . current = null ;
}
if ( audioContextRef . current ) {
void audioContextRef . current . close ( ) ;
audioContextRef . current = null ;
}
if ( playbackContextRef . current ) {
void playbackContextRef . current . close ( ) ;
playbackContextRef . current = null ;
}
wsRef . current = null ;
setUserAmplitude ( 0 ) ;
setAgentAmplitude ( 0 ) ;
// If we weren't intentionally ending, allow reconnect
if ( statusRef . current !== 'ending' && ! briefSubmittedRef . current ) {
setStatus ( 'error' ) ;
setErrorMessage ( null ) ;
setCanReconnect ( true ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
} ;
} catch ( error ) {
2026-03-28 14:04:20 +01:00
console . error ( '[VoiceAgent] Start failed:' , error ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
setStatus ( 'error' ) ;
if ( error instanceof DOMException && error . name === 'NotAllowedError' ) {
setErrorMessage ( 'Microphone access was denied.' ) ;
} else {
2026-03-28 14:04:20 +01:00
const msg = error instanceof Error ? error . message : 'Unknown error' ;
setErrorMessage ( ` Failed to start: ${ msg } ` ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
}
}
2026-04-06 14:43:27 -04:00
} , [ locale , trackAmplitude , handleToolCall , playAudioChunk , addTranscript ] ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const endConversation = useCallback ( ( ) = > {
setStatus ( 'ending' ) ;
cancelAnimationFrame ( animFrameRef . current ) ;
if ( wsRef . current ) {
wsRef . current . close ( ) ;
wsRef . current = null ;
}
if ( mediaStreamRef . current ) {
mediaStreamRef . current . getTracks ( ) . forEach ( ( track ) = > track . stop ( ) ) ;
mediaStreamRef . current = null ;
}
if ( audioContextRef . current ) {
void audioContextRef . current . close ( ) ;
audioContextRef . current = null ;
}
if ( playbackContextRef . current ) {
void playbackContextRef . current . close ( ) ;
playbackContextRef . current = null ;
}
setUserAmplitude ( 0 ) ;
setAgentAmplitude ( 0 ) ;
2026-04-06 14:43:27 -04:00
setCanReconnect ( false ) ;
reconnectTranscriptRef . current = [ ] ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
setStatus ( 'idle' ) ;
} , [ ] ) ;
2026-04-06 14:43:27 -04:00
const updatePendingContact = useCallback ( ( field : 'name' | 'email' , value : string ) = > {
setPendingContact ( ( prev ) = > {
if ( ! prev ) return null ;
const updated = { . . . prev , [ field ] : value } ;
pendingContactRef . current = updated ;
return updated ;
} ) ;
} , [ ] ) ;
const confirmContact = useCallback ( ( ) = > {
if ( ! pendingContactRef . current ) return ;
2026-04-06 15:52:53 -04:00
// Send a text message to let the agent know the user confirmed their details
2026-04-06 14:43:27 -04:00
if ( wsRef . current ? . readyState === WebSocket . OPEN ) {
2026-04-06 15:52:53 -04:00
const { name , email } = pendingContactRef . current ;
2026-04-06 14:43:27 -04:00
wsRef . current . send ( JSON . stringify ( {
2026-04-06 15:52:53 -04:00
realtimeInput : {
text : ` The user has confirmed their contact details on screen. Name: ${ name } , Email: ${ email } . You may now call complete_brief. ` ,
2026-04-06 14:43:27 -04:00
} ,
} ) ) ;
2026-04-06 15:52:53 -04:00
console . log ( '[VoiceAgent] Contact confirmed, notified agent' ) ;
} else {
console . warn ( '[VoiceAgent] Cannot confirm contact — WebSocket not open' ) ;
2026-04-06 14:43:27 -04:00
}
} , [ ] ) ;
const reconnect = useCallback ( async ( ) = > {
setCanReconnect ( false ) ;
setErrorMessage ( null ) ;
// Preserve transcript for the new session to pick up context
reconnectTranscriptRef . current = transcript ;
await startConversation ( ) ;
} , [ startConversation , transcript ] ) ;
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
const toggleMic = useCallback ( ( ) = > {
if ( ! mediaStreamRef . current ) return ;
const track = mediaStreamRef . current . getAudioTracks ( ) [ 0 ] ;
if ( track ) {
track . enabled = ! track . enabled ;
setIsMicActive ( track . enabled ) ;
}
} , [ ] ) ;
const value : VoiceAgentContextValue = {
status ,
errorMessage ,
isMicActive ,
toggleMic ,
transcript ,
selections ,
isAnalyzingSite ,
2026-03-28 14:58:56 +01:00
isGeneratingBrief ,
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
userAmplitude ,
agentAmplitude ,
startConversation ,
endConversation ,
completedBrief ,
completedFormData ,
2026-04-06 14:43:27 -04:00
pendingContact ,
confirmContact ,
updatePendingContact ,
canReconnect ,
reconnect ,
feat: website analysis pipeline, voice agent, configurator improvements
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration
- Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis
- Type/Talk mode toggle with silent capability detection
- Stepped progress animation during brief generation (4 animated steps)
- URL + thoughts fields in Step 2, phone + contact preference in Step 3
- AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth
- Email redesign: branded templates with logo, proper markdown rendering for both client and admin
- French locale support for AI-generated briefs
- Smaller checkmark, compact booking CTA, expanded brief area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
} ;
return (
< VoiceAgentContext.Provider value = { value } >
{ children }
< / VoiceAgentContext.Provider >
) ;
}