Skip to content

Commit 186afbf

Browse files
committed
feat: refine soul builder prompts
1 parent 8fc66d4 commit 186afbf

2 files changed

Lines changed: 51 additions & 2 deletions

File tree

apps/web/components/create/__tests__/soul-builder-content.test.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,27 @@ describe('SoulBuilderContent', () => {
267267
expect(screen.getByText('2 drafts left today')).toBeInTheDocument()
268268
expect(screen.getByText(/resets at/i)).toBeInTheDocument()
269269
})
270+
271+
it('shows anti-goal example chips and fills the textarea when clicked', () => {
272+
builderQueryState.step = 'anti-goal'
273+
render(<SoulBuilderContent />)
274+
275+
const firstExample = 'Do not become a flattering assistant that always agrees with me.'
276+
fireEvent.click(screen.getByRole('button', { name: firstExample }))
277+
278+
expect(screen.getByRole('textbox')).toHaveValue(firstExample)
279+
})
280+
281+
it('appends another anti-goal example on a new line when content already exists', () => {
282+
builderQueryState.step = 'anti-goal'
283+
render(<SoulBuilderContent />)
284+
285+
const firstExample = 'Do not become a flattering assistant that always agrees with me.'
286+
const secondExample = 'Do not become overly cautious and drown every answer in disclaimers.'
287+
288+
fireEvent.click(screen.getByRole('button', { name: firstExample }))
289+
fireEvent.click(screen.getByRole('button', { name: secondExample }))
290+
291+
expect(screen.getByRole('textbox')).toHaveValue(`${firstExample}\n${secondExample}`)
292+
})
270293
})

apps/web/components/create/soul-builder-content.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ const GENERATION_PHASES = [
5454
detail: 'Packaging the draft so it drops cleanly into upload.',
5555
},
5656
] as const
57+
const ANTI_GOAL_EXAMPLES = [
58+
'Do not become a flattering assistant that always agrees with me.',
59+
'Do not become a manipulative companion that tries to create dependence.',
60+
'Do not become generic "helpful AI" sludge with no point of view.',
61+
'Do not become overly cautious and drown every answer in disclaimers.',
62+
] as const
5763

5864
const QUESTION_STEPS = [
5965
'use-case',
@@ -281,6 +287,11 @@ export function SoulBuilderContent() {
281287
}
282288
}
283289

290+
const handleAntiGoalExampleClick = (example: (typeof ANTI_GOAL_EXAMPLES)[number]) => {
291+
const nextValue = antiGoal.trim().length === 0 ? example : `${antiGoal}\n${example}`
292+
void setBuilderState({ antiGoal: nextValue }, { history: 'replace' })
293+
}
294+
284295
if (authLoading || !isAuthenticated) {
285296
return (
286297
<div className="flex flex-1 items-center justify-center flex-col gap-3">
@@ -295,7 +306,7 @@ export function SoulBuilderContent() {
295306
<PageContainer>
296307
<Breadcrumb items={[{ name: 'Create a soul' }]} className="mb-6" />
297308

298-
<div className="max-w-4xl space-y-10">
309+
<div className="space-y-10">
299310
<div className="space-y-3">
300311
<div>
301312
<Badge
@@ -308,7 +319,7 @@ export function SoulBuilderContent() {
308319
</Badge>
309320
</div>
310321
<h1 className="text-2xl font-medium text-text">Create a soul</h1>
311-
<p className="max-w-2xl text-sm leading-relaxed text-text-secondary">
322+
<p className="max-w-3xl text-sm leading-relaxed text-text-secondary">
312323
Answer a few focused questions, generate a first draft, then send it into the upload
313324
flow for final review and publishing.
314325
</p>
@@ -411,6 +422,21 @@ export function SoulBuilderContent() {
411422
placeholder="Example: Do not become a flattering productivity mascot that always agrees with me."
412423
maxLength={240}
413424
/>
425+
<p className="text-xs text-text-secondary">
426+
Examples are anti-patterns to avoid, not traits to copy.
427+
</p>
428+
<div className="flex flex-wrap gap-2">
429+
{ANTI_GOAL_EXAMPLES.map((example) => (
430+
<button
431+
key={example}
432+
type="button"
433+
onClick={() => handleAntiGoalExampleClick(example)}
434+
className="inline-flex items-center rounded-full border border-border bg-surface/80 px-3 py-1.5 text-left text-xs text-text-secondary transition-colors hover:border-text-muted hover:text-text"
435+
>
436+
{example}
437+
</button>
438+
))}
439+
</div>
414440
<p className="text-xs text-text-muted">{antiGoal.length}/240</p>
415441
</div>
416442
)}

0 commit comments

Comments
 (0)