fix: use predefined values for tool calls, improve completion flow
Some checks failed
Build & Push / build-and-push (push) Has been cancelled

- System prompt now specifies exact predefined values for services/industries/timelines
- Agent instructed to call complete_brief IMMEDIATELY when name+email confirmed
- Chip labels fall back to raw value for unknown keys instead of showing i18n path
- Added completion transition logging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-28 14:49:56 +01:00
parent 66949c07d8
commit 1e41c1c07c
2 changed files with 28 additions and 9 deletions

View File

@@ -75,7 +75,9 @@ export default function VoiceAgent({ locale, onComplete }: VoiceAgentProps) {
// Handle completion // Handle completion
useEffect(() => { useEffect(() => {
if (completedBrief && completedFormData) { if (completedBrief && completedFormData) {
console.log('[VoiceAgent] Brief complete, transitioning in 1.5s...');
const timer = setTimeout(() => { const timer = setTimeout(() => {
console.log('[VoiceAgent] Calling onComplete');
onComplete(completedBrief, completedFormData); onComplete(completedBrief, completedFormData);
}, 1500); }, 1500);
return () => clearTimeout(timer); return () => clearTimeout(timer);
@@ -94,23 +96,30 @@ export default function VoiceAgent({ locale, onComplete }: VoiceAgentProps) {
['0px 0px 0px rgba(0,100,148,0)', '0px 0px 30px rgba(0,100,148,0.3)'], ['0px 0px 0px rgba(0,100,148,0)', '0px 0px 30px rgba(0,100,148,0.3)'],
); );
// Build selection chips // Build selection chips — use i18n for known keys, raw value otherwise
const KNOWN_SERVICES = ['web', 'systems', 'infrastructure'];
const KNOWN_AI_TYPES = ['teammate', 'customer-facing', 'data-intelligence', 'notsure'];
const KNOWN_INDUSTRIES = ['maritime', 'hospitality', 'technology', 'realestate', 'finance', 'ngo', 'other'];
const KNOWN_TIMELINES = ['asap', '1-3months', '3-6months', 'exploring'];
const chipLabels: string[] = []; const chipLabels: string[] = [];
if (selections.services) { if (selections.services) {
for (const svc of selections.services) { for (const svc of selections.services) {
try { chipLabels.push(t(`services.${svc}.title`)); } catch { chipLabels.push(svc); } chipLabels.push(KNOWN_SERVICES.includes(svc) ? t(`services.${svc}.title`) : svc);
} }
} }
if (selections.aiEnabled && selections.aiTypes) { if (selections.aiEnabled && selections.aiTypes) {
for (const ai of selections.aiTypes) { for (const ai of selections.aiTypes) {
try { chipLabels.push(t(`aiTypes.${ai}.title`)); } catch { chipLabels.push(ai); } chipLabels.push(KNOWN_AI_TYPES.includes(ai) ? t(`aiTypes.${ai}.title`) : ai);
} }
} }
if (selections.industry) { if (selections.industry) {
try { chipLabels.push(t(`industries.${selections.industry}`)); } catch { chipLabels.push(selections.industry); } const ind = selections.industry;
chipLabels.push(KNOWN_INDUSTRIES.includes(ind) ? t(`industries.${ind}`) : ind);
} }
if (selections.timeline) { if (selections.timeline) {
try { chipLabels.push(t(`timelines.${selections.timeline}`)); } catch { chipLabels.push(selections.timeline); } const tl = selections.timeline;
chipLabels.push(KNOWN_TIMELINES.includes(tl) ? t(`timelines.${tl}`) : tl);
} }
return ( return (

View File

@@ -93,9 +93,14 @@ Ton rôle est de guider naturellement la conversation à travers les sujets suiv
7. Enfin, leur prénom, nom et adresse e-mail pour envoyer le brief 7. Enfin, leur prénom, nom et adresse e-mail pour envoyer le brief
Instructions : Instructions :
- Appelle update_selections chaque fois qu'un point est confirmé dans la conversation. - Appelle update_selections chaque fois qu'un point est confirmé. Utilise UNIQUEMENT ces valeurs prédéfinies :
- services : "web", "systems", "infrastructure"
- aiTypes : "teammate", "customer-facing", "data-intelligence", "notsure"
- industry : "maritime", "hospitality", "technology", "realestate", "finance", "ngo", "other"
- timeline : "asap", "1-3months", "3-6months", "exploring"
Associe ce que l'utilisateur dit à la valeur prédéfinie la plus proche.
- Appelle analyze_website dès que l'utilisateur fournit une URL — puis intègre naturellement les résultats dans la discussion. - Appelle analyze_website dès que l'utilisateur fournit une URL — puis intègre naturellement les résultats dans la discussion.
- Appelle complete_brief une fois que le nom et l'e-mail sont confirmés. - Appelle complete_brief IMMÉDIATEMENT dès que le nom et l'e-mail sont confirmés. N'attends pas — appelle l'outil tout de suite. Dis quelque chose comme "Parfait, je génère votre brief maintenant".
- Garde tes réponses concises : 2 à 3 phrases maximum par tour. - Garde tes réponses concises : 2 à 3 phrases maximum par tour.
- Sois chaleureux, direct et professionnel — jamais générique. - Sois chaleureux, direct et professionnel — jamais générique.
@@ -121,9 +126,14 @@ Your role is to walk through the following topics naturally in conversation:
7. Finally, their name and email to send the brief 7. Finally, their name and email to send the brief
Instructions: Instructions:
- Call update_selections each time a data point is confirmed during the conversation. - Call update_selections each time a data point is confirmed. Use ONLY these predefined values:
- services: "web", "systems", "infrastructure"
- aiTypes: "teammate", "customer-facing", "data-intelligence", "notsure"
- industry: "maritime", "hospitality", "technology", "realestate", "finance", "ngo", "other"
- timeline: "asap", "1-3months", "3-6months", "exploring"
Map what the user says to the closest predefined value.
- Call analyze_website as soon as the user provides a URL — then discuss the findings naturally. - Call analyze_website as soon as the user provides a URL — then discuss the findings naturally.
- Call complete_brief once name and email are confirmed. - Call complete_brief IMMEDIATELY once you have confirmed the user's name and email. Do not wait — call the tool right away. Say something like "Great, I'm generating your brief now" while calling the tool.
- Keep responses concise: 23 sentences maximum per turn. - Keep responses concise: 23 sentences maximum per turn.
- Be warm, direct, and professional — never generic. - Be warm, direct, and professional — never generic.