You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add voice recording, transcription, and audio player components
- Implemented `AudioPlayer` for custom audio playback controls.
- Added `useAudioRecorder` hook for managing microphone audio recording with visual feedback.
- Introduced audio transcription API integration using OpenAI Whisper.
- Created `blobToBase64` utility to encode recorded blobs for API consumption.
- Added IndexedDB-based `recording-store` for saving in-progress recordings.
- Developed `VoiceAutofillSection` for guided recording, playback, transcription, and editing.
age: 'Number. Age in years (between 18 and 100).',
459
484
gender: `String. One of: ${validChoices.pref_gender?.join(', ')}. If multiple mentioned, use the most likely one. Infer if you have enough evidence`,
485
+
gender_details:
486
+
'String. Free-form elaboration on their gender identity, only if they say more than the label itself.',
487
+
orientation: `Array. Any of: ${validChoices.orientation?.join(', ')}. Only if stated — never infer from the gender of a partner or of who they are looking for.`,
488
+
orientation_details:
489
+
'String. Free-form elaboration on their orientation, only if they say more than the label itself.',
460
490
height_in_inches: 'Number. Height converted to inches.',
461
491
city: 'String. Current city of residence (English spelling).',
462
492
country: 'String. Current country of residence (English spelling).',
@@ -498,6 +528,11 @@ export async function callLLM(
498
528
big5_agreeableness: 'Number 0–100. Only if explicitly self-reported, never infer.',
499
529
big5_neuroticism: 'Number 0–100. Only if explicitly self-reported, never infer.',
500
530
531
+
// Neurotype is an identity here, not a diagnosis: only ever take the person's own words for it.
532
+
neurotype: `Array. Any of: ${validChoices.neurotype?.join(', ')}. Only if they identify this way themselves — never infer it from how they describe their personality, focus, energy or social life.`,
533
+
neurotype_details:
534
+
'String. Free-form elaboration on their neurotype, only if they say more than the label itself.',
535
+
501
536
// Beliefs
502
537
religion: `Array. Any of: ${validChoices.religion?.join(', ')}`,
503
538
religious_beliefs:
@@ -511,7 +546,7 @@ export async function callLLM(
511
546
'Number. Minimum preferred age of match (higher than 18, only if mentioned, do NOT infer).',
512
547
pref_age_max:
513
548
'Number. Maximum preferred age of match (lower than 100, only if mentioned, do NOT infer).',
514
-
pref_gender: `Array. Any of: ${validChoices.pref_gender?.join(', ')}`,
549
+
pref_gender: `Array. Any of: ${validChoices.pref_gender?.join(', ')}. Only the genders they actually name as sought. If they say gender does not matter to them, or is unimportant to their attraction, OMIT this field — an omitted field already means "no preference", so listing every option instead is both wrong and unreadable.`,
515
550
pref_relation_styles: `Array. Any of: ${validChoices.pref_relation_styles?.join(', ')}`,
516
551
pref_romantic_styles: `Array. Any of: ${validChoices.pref_romantic_styles?.join(', ')}`,
517
552
relationship_status: `Array. Any of: ${validChoices.relationship_status?.join(', ')}`,
@@ -523,6 +558,8 @@ export async function callLLM(
523
558
headline:
524
559
'String. Summary of who they are, in their own voice (first person). Maximum 200 characters total. Cannot be null.',
525
560
keywords: 'Array of 3–6 short tags summarising the person.',
561
+
accessibility_notes:
562
+
'String. Practical things that help someone meet them well — access needs, energy levels, sensory preferences, venue preferences. Only if mentioned; never infer a disability, and keep their own framing and wording.',
526
563
links: `Object. Key is any of: ${SITE_ORDER.join(', ')}.`,
527
564
528
565
// Taxonomies — match existing labels first, only add new if truly no close match exists
@@ -531,7 +568,25 @@ export async function callLLM(
531
568
work: `Array. Use only existing labels, do not add new if no close match. Any of: ${validChoices.work?.join(', ')}`,
532
569
}
533
570
534
-
constEXTRACTION_PROMPT=`You are a profile information extraction expert analyzing text from a personal webpage, bio, or similar source.
571
+
// For text and URL sources the bio is the source material itself, stored verbatim. A speech
572
+
// transcript makes a poor bio (filler words, false starts, no paragraphs), so for voice we ask
573
+
// the model to write it instead.
574
+
if(isVoice){
575
+
PROFILE_FIELDS.bio=
576
+
'String. A first-person bio written from what the person said, in their own voice and their '+
577
+
'own language. Keep their wording and personality wherever you can; only clean up filler '+
578
+
'words, false starts, repetitions and transcription noise, and organise it into '+
579
+
'paragraphs. Separate each paragraph from the next with a BLANK LINE, i.e. two newline '+
580
+
'characters ("\\n\\n") — a single newline is not enough. Never add facts, opinions or '+
581
+
'flourishes they did not say, and never write about them in the third person. Plain text '+
582
+
'only — no markdown.'
583
+
}
584
+
585
+
constEXTRACTION_PROMPT=`You are a profile information extraction expert analyzing ${
586
+
isVoice
587
+
? 'a speech-to-text transcript of someone talking about themselves out loud'
588
+
: 'text from a personal webpage, bio, or similar source'
589
+
}.
535
590
536
591
TASK: Extract structured profile data and return it as a single valid JSON object.
537
592
@@ -540,12 +595,20 @@ RULES:
540
595
- Omit the key in the output for missing fields
541
596
- For taxonomy fields (interests, causes, work): match existing labels first; only add a new label if truly no existing one is close
542
597
- For big5 scores: only populate if the person explicitly states a test result — never infer from personality description
543
-
- Return valid JSON only — no markdown, no explanation, no extra text
598
+
- Never answer a multi-choice field by selecting every option it offers. An expression of openness or indifference ("gender doesn't matter to me", "I'm open to anything") is not a selection of all values — omit the field, which already means "no preference"
599
+
- Return valid JSON only — no markdown, no explanation, no extra text${
600
+
isVoice
601
+
? `
602
+
- The transcript is spoken language: expect filler words, false starts, self-corrections and speech-recognition errors. Read past them, and when the person corrects themselves keep the corrected version
603
+
- Ignore anything the person says to the recorder rather than about themselves (e.g. "let me start over", "what else should I say")
604
+
- Spoken numbers, places and names may be mis-transcribed; only fill a field when you are confident what was meant`
605
+
: ''
606
+
}
544
607
545
608
SCHEMA (each value describes the expected type and accepted values):
546
609
${JSON.stringify(PROFILE_FIELDS,null,2)}
547
610
548
-
TEXT TO ANALYZE:
611
+
${isVoice ? 'TRANSCRIPT TO ANALYZE' : 'TEXT TO ANALYZE'}:
0 commit comments