Skip to content

Commit e1cc4fd

Browse files
Podcast notes AI prefix (#686)
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent 8d73300 commit e1cc4fd

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

app/routes/calls_.record/new.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { H4, Paragraph } from '#app/components/typography.tsx'
1212
import { type RootLoaderType } from '#app/root.tsx'
1313
import { CallKentTextToSpeech } from '#app/routes/resources/calls/text-to-speech.tsx'
1414
import { type KCDHandle } from '#app/types.ts'
15+
import { formatCallKentTextToSpeechNotes } from '#app/utils/call-kent-text-to-speech.ts'
1516
import { getEnv } from '#app/utils/env.server.ts'
1617
import { type SerializeFrom } from '#app/utils/serialize-from.ts'
1718
import { type Route } from './+types/new'
@@ -156,11 +157,12 @@ export default function RecordScreen({
156157
<CallKentTextToSpeech
157158
onAcceptAudio={({ audio, questionText }) => {
158159
setAudio(audio)
159-
const cleanedQuestion = questionText.trim()
160+
const formattedNotes =
161+
formatCallKentTextToSpeechNotes(questionText)
160162
setPrefill({
161163
fields: {
162164
title: 'Call Kent question',
163-
notes: cleanedQuestion,
165+
notes: formattedNotes,
164166
},
165167
errors: {},
166168
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { expect, test } from 'vitest'
2+
import {
3+
AI_VOICE_DISCLOSURE_PREFIX,
4+
formatCallKentTextToSpeechNotes,
5+
} from '../call-kent-text-to-speech.ts'
6+
7+
test('formats typed-question notes with AI disclosure prefix', () => {
8+
const notes = formatCallKentTextToSpeechNotes(' Hello from a typed call. ')
9+
expect(notes).toBe(
10+
`${AI_VOICE_DISCLOSURE_PREFIX}\nTyped question: Hello from a typed call.`,
11+
)
12+
})
13+
14+
test('preserves internal newlines in typed question', () => {
15+
const question = 'First line\nSecond line'
16+
const notes = formatCallKentTextToSpeechNotes(question)
17+
expect(notes).toBe(
18+
`${AI_VOICE_DISCLOSURE_PREFIX}\nTyped question: ${question}`,
19+
)
20+
})
21+
22+
test('removes duplicate AI disclosure from typed question', () => {
23+
const question = `${AI_VOICE_DISCLOSURE_PREFIX} Hello from a typed call.`
24+
const notes = formatCallKentTextToSpeechNotes(question)
25+
expect(notes).toBe(
26+
`${AI_VOICE_DISCLOSURE_PREFIX}\nTyped question: Hello from a typed call.`,
27+
)
28+
})
29+
30+
test('returns empty string for empty input', () => {
31+
expect(formatCallKentTextToSpeechNotes('')).toBe('')
32+
})
33+
34+
test('returns empty string for whitespace-only input', () => {
35+
expect(formatCallKentTextToSpeechNotes(' ')).toBe('')
36+
})

app/utils/call-kent-text-to-speech.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ export const callKentTextToSpeechConstraints = {
1010

1111
export const AI_VOICE_DISCLOSURE_PREFIX = `This caller's voice was generated by AI.`
1212

13+
export function formatCallKentTextToSpeechNotes(questionText: string) {
14+
const cleaned = questionText.trim()
15+
if (!cleaned) return cleaned
16+
17+
// Callers can paste the disclosure prefix into the textarea. Avoid duplicating
18+
// it when formatting notes for the call record.
19+
const prefixLower = AI_VOICE_DISCLOSURE_PREFIX.toLowerCase()
20+
const questionBody = cleaned.toLowerCase().startsWith(prefixLower)
21+
? cleaned.slice(AI_VOICE_DISCLOSURE_PREFIX.length).trimStart()
22+
: cleaned
23+
return `${AI_VOICE_DISCLOSURE_PREFIX}\nTyped question: ${questionBody}`
24+
}
25+
1326
// @cf/deepgram/aura-2-en supports many speakers; we offer a curated subset.
1427
const auraSpeakers = [
1528
'apollo',

docs/agents/project-context.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,10 @@ reference:
3939
It's populated on first request or via `npm run prime-cache:mocks`.
4040
- Content is filesystem-based: blog posts are MDX files in `content/blog/`.
4141
Changes to content files are auto-detected by the dev server's file watcher.
42+
43+
## Cloud / headless manual testing
44+
45+
- In cloud VMs, Chrome may block camera/microphone access by default. Visiting
46+
`/calls/record/new` can hit the route ErrorBoundary unless `localhost` is
47+
allowed mic/camera access in site settings (even if you intend to use the
48+
typed question → text-to-speech path).

0 commit comments

Comments
 (0)