Skip to content

Commit a3a35d9

Browse files
committed
Merge remote-tracking branch 'origin/main' into delete&rename
2 parents 34b1c2e + f97d5f9 commit a3a35d9

2 files changed

Lines changed: 60 additions & 206 deletions

File tree

content-gen/src/app/frontend/src/App.tsx

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function App() {
4747
// Brief confirmation flow
4848
const [pendingBrief, setPendingBrief] = useState<CreativeBrief | null>(null);
4949
const [confirmedBrief, setConfirmedBrief] = useState<CreativeBrief | null>(null);
50+
const [awaitingClarification, setAwaitingClarification] = useState<boolean>(false);
5051

5152
// Product selection
5253
const [selectedProducts, setSelectedProducts] = useState<Product[]>([]);
@@ -113,6 +114,7 @@ function App() {
113114
}));
114115
setMessages(loadedMessages);
115116
setPendingBrief(null);
117+
setAwaitingClarification(false);
116118
setConfirmedBrief(data.brief || null);
117119

118120
if (data.generated_content) {
@@ -176,6 +178,7 @@ function App() {
176178
setConversationId(uuidv4());
177179
setMessages([]);
178180
setPendingBrief(null);
181+
setAwaitingClarification(false);
179182
setConfirmedBrief(null);
180183
setGeneratedContent(null);
181184
setSelectedProducts([]);
@@ -202,11 +205,12 @@ function App() {
202205

203206
// If we have a pending brief and user is providing feedback, update the brief
204207
if (pendingBrief && !confirmedBrief) {
205-
// User is refining the brief conversationally
208+
// User is refining the brief or providing clarification
206209
const refinementKeywords = ['change', 'update', 'modify', 'add', 'remove', 'delete', 'set', 'make', 'should be'];
207210
const isRefinement = refinementKeywords.some(kw => content.toLowerCase().includes(kw));
208211

209-
if (isRefinement) {
212+
// If awaiting clarification, treat ANY response as a brief update
213+
if (isRefinement || awaitingClarification) {
210214
// Send the refinement request to update the brief
211215
// Combine original brief context with the refinement request
212216
const refinementPrompt = `Current creative brief:\n${JSON.stringify(pendingBrief, null, 2)}\n\nUser requested change: ${content}\n\nPlease update the brief accordingly and return the complete updated brief.`;
@@ -216,16 +220,34 @@ function App() {
216220
if (parsed.brief) {
217221
setPendingBrief(parsed.brief);
218222
}
219-
setGenerationStatus('');
220223

221-
const assistantMessage: ChatMessage = {
222-
id: uuidv4(),
223-
role: 'assistant',
224-
content: "I've updated the brief based on your feedback. Please review the changes above. Let me know if you'd like any other modifications, or click **Confirm Brief** when you're satisfied.",
225-
agent: 'PlanningAgent',
226-
timestamp: new Date().toISOString(),
227-
};
228-
setMessages(prev => [...prev, assistantMessage]);
224+
// Check if we still need more clarification
225+
if (parsed.requires_clarification && parsed.clarifying_questions) {
226+
setAwaitingClarification(true);
227+
setGenerationStatus('');
228+
229+
const assistantMessage: ChatMessage = {
230+
id: uuidv4(),
231+
role: 'assistant',
232+
content: parsed.clarifying_questions,
233+
agent: 'PlanningAgent',
234+
timestamp: new Date().toISOString(),
235+
};
236+
setMessages(prev => [...prev, assistantMessage]);
237+
} else {
238+
// Brief is now complete
239+
setAwaitingClarification(false);
240+
setGenerationStatus('');
241+
242+
const assistantMessage: ChatMessage = {
243+
id: uuidv4(),
244+
role: 'assistant',
245+
content: "I've updated the brief based on your feedback. Please review the changes above. Let me know if you'd like any other modifications, or click **Confirm Brief** when you're satisfied.",
246+
agent: 'PlanningAgent',
247+
timestamp: new Date().toISOString(),
248+
};
249+
setMessages(prev => [...prev, assistantMessage]);
250+
}
229251
} else {
230252
// General question or comment while brief is pending
231253
let fullContent = '';
@@ -307,6 +329,7 @@ function App() {
307329
if (parsed.brief) {
308330
setPendingBrief(parsed.brief);
309331
}
332+
setAwaitingClarification(true);
310333
setGenerationStatus('');
311334

312335
const assistantMessage: ChatMessage = {
@@ -322,6 +345,7 @@ function App() {
322345
if (parsed.brief) {
323346
setPendingBrief(parsed.brief);
324347
}
348+
setAwaitingClarification(false);
325349
setGenerationStatus('');
326350

327351
const assistantMessage: ChatMessage = {
@@ -410,6 +434,7 @@ function App() {
410434
await confirmBrief(pendingBrief, conversationId, userId);
411435
setConfirmedBrief(pendingBrief);
412436
setPendingBrief(null);
437+
setAwaitingClarification(false);
413438

414439
const productsResponse = await fetch('/api/products');
415440
if (productsResponse.ok) {
@@ -432,6 +457,7 @@ function App() {
432457

433458
const handleBriefCancel = useCallback(() => {
434459
setPendingBrief(null);
460+
setAwaitingClarification(false);
435461
const assistantMessage: ChatMessage = {
436462
id: uuidv4(),
437463
role: 'assistant',

content-gen/src/app/frontend/src/components/BriefReview.tsx

Lines changed: 23 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,6 @@ interface BriefReviewProps {
1212
isAwaitingResponse?: boolean;
1313
}
1414

15-
const briefFields: { key: keyof CreativeBrief; label: string; prefix?: string }[] = [
16-
{ key: 'objectives', label: 'Objective', prefix: '• ' },
17-
{ key: 'target_audience', label: 'Audience', prefix: '• ' },
18-
{ key: 'key_message', label: 'Key Message', prefix: '• ' },
19-
{ key: 'tone_and_style', label: 'Tone & Style', prefix: '• ' },
20-
{ key: 'timelines', label: 'Timelines', prefix: '• ' },
21-
{ key: 'cta', label: 'Call to Action', prefix: '• ' },
22-
];
23-
2415
// Mapping of field keys to user-friendly labels for the 9 key areas
2516
const fieldLabels: Record<keyof CreativeBrief, string> = {
2617
overview: 'Overview',
@@ -47,6 +38,22 @@ export function BriefReview({
4738
const populatedFields = allFields.filter(key => brief[key]?.trim()).length;
4839
const missingFields = allFields.filter(key => !brief[key]?.trim());
4940

41+
// Define the order and labels for display in the card
42+
const displayOrder: { key: keyof CreativeBrief; label: string }[] = [
43+
{ key: 'overview', label: 'Campaign Objective' },
44+
{ key: 'objectives', label: 'Objectives' },
45+
{ key: 'target_audience', label: 'Target Audience' },
46+
{ key: 'key_message', label: 'Key Message' },
47+
{ key: 'tone_and_style', label: 'Tone & Style' },
48+
{ key: 'visual_guidelines', label: 'Visual Guidelines' },
49+
{ key: 'deliverable', label: 'Deliverables' },
50+
{ key: 'timelines', label: 'Timelines' },
51+
{ key: 'cta', label: 'Call to Action' },
52+
];
53+
54+
// Filter to only populated fields
55+
const populatedDisplayFields = displayOrder.filter(({ key }) => brief[key]?.trim());
56+
5057
return (
5158
<div className="message assistant" style={{
5259
width: '100%',
@@ -68,116 +75,17 @@ export function BriefReview({
6875
Thanks—here's my understanding:
6976
</Text>
7077

71-
{/* Brief Fields - Bullet point list like Figma */}
72-
<div style={{
73-
display: 'flex',
74-
flexDirection: 'column',
75-
gap: '8px',
76-
marginBottom: '16px',
77-
}}>
78-
{briefFields.map(({ key, label, prefix }) => {
79-
const value = brief[key];
80-
if (!value?.trim()) return null;
81-
82-
return (
83-
<div key={key} style={{
84-
display: 'flex',
85-
alignItems: 'flex-start',
86-
gap: '4px',
87-
}}>
88-
<Text size={200} style={{ color: tokens.colorNeutralForeground1 }}>
89-
{prefix}
90-
</Text>
91-
<div>
92-
<Text
93-
weight="semibold"
94-
size={200}
95-
style={{ color: tokens.colorNeutralForeground1 }}
96-
>
97-
{label}:
98-
</Text>
99-
{' '}
100-
<Text size={200} style={{ color: tokens.colorNeutralForeground2 }}>
101-
{value}
102-
</Text>
103-
</div>
104-
</div>
105-
);
106-
})}
107-
</div>
108-
109-
{/* Additional content fields in a bordered card - like Figma */}
110-
{(brief.overview || brief.key_message || brief.visual_guidelines || brief.timelines || brief.cta) && (
78+
{/* All Brief Fields in a single bordered card */}
79+
{populatedDisplayFields.length > 0 && (
11180
<div style={{
11281
padding: '16px',
11382
backgroundColor: tokens.colorNeutralBackground2,
11483
borderRadius: '8px',
11584
marginBottom: '16px',
11685
border: `1px solid ${tokens.colorNeutralStroke2}`,
11786
}}>
118-
{/* Campaign Objective section */}
119-
{brief.overview && (
120-
<div style={{ marginBottom: '12px' }}>
121-
<Text
122-
weight="semibold"
123-
size={300}
124-
style={{
125-
color: tokens.colorNeutralForeground1,
126-
display: 'block',
127-
marginBottom: '4px',
128-
}}
129-
>
130-
Campaign Objective
131-
</Text>
132-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
133-
{brief.overview}
134-
</Text>
135-
</div>
136-
)}
137-
138-
{/* Audience section */}
139-
{brief.target_audience && (
140-
<div style={{ marginBottom: '12px' }}>
141-
<Text
142-
weight="semibold"
143-
size={300}
144-
style={{
145-
color: tokens.colorNeutralForeground1,
146-
display: 'block',
147-
marginBottom: '4px',
148-
}}
149-
>
150-
Audience
151-
</Text>
152-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
153-
{brief.target_audience}
154-
</Text>
155-
</div>
156-
)}
157-
158-
{/* Key Message section */}
159-
{brief.key_message && (
160-
<div style={{ marginBottom: '12px' }}>
161-
<Text
162-
weight="semibold"
163-
size={300}
164-
style={{
165-
color: tokens.colorNeutralForeground1,
166-
display: 'block',
167-
marginBottom: '4px',
168-
}}
169-
>
170-
Key Message
171-
</Text>
172-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
173-
{brief.key_message}
174-
</Text>
175-
</div>
176-
)}
177-
178-
{/* Visual guidelines / Creation instructions */}
179-
{brief.visual_guidelines && (
180-
<div style={{ marginBottom: '12px' }}>
87+
{populatedDisplayFields.map(({ key, label }, index) => (
88+
<div key={key} style={{ marginBottom: index < populatedDisplayFields.length - 1 ? '12px' : '0' }}>
18189
<Text
18290
weight="semibold"
18391
size={300}
@@ -187,93 +95,13 @@ export function BriefReview({
18795
marginBottom: '4px',
18896
}}
18997
>
190-
Visual Guidelines
98+
{label}
19199
</Text>
192100
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
193-
{brief.visual_guidelines}
101+
{brief[key]}
194102
</Text>
195103
</div>
196-
)}
197-
198-
{/* Tone & Style section */}
199-
{brief.tone_and_style && (
200-
<div style={{ marginBottom: '12px' }}>
201-
<Text
202-
weight="semibold"
203-
size={300}
204-
style={{
205-
color: tokens.colorNeutralForeground1,
206-
display: 'block',
207-
marginBottom: '4px',
208-
}}
209-
>
210-
Tone & Style:
211-
</Text>
212-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
213-
{brief.tone_and_style}
214-
</Text>
215-
</div>
216-
)}
217-
218-
{/* Deliverables section */}
219-
{brief.deliverable && (
220-
<div style={{ marginBottom: brief.timelines || brief.cta ? '12px' : '0' }}>
221-
<Text
222-
weight="semibold"
223-
size={300}
224-
style={{
225-
color: tokens.colorNeutralForeground1,
226-
display: 'block',
227-
marginBottom: '4px',
228-
}}
229-
>
230-
Deliverables
231-
</Text>
232-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
233-
{brief.deliverable}
234-
</Text>
235-
</div>
236-
)}
237-
238-
{/* Timelines section */}
239-
{brief.timelines && (
240-
<div style={{ marginBottom: brief.cta ? '12px' : '0' }}>
241-
<Text
242-
weight="semibold"
243-
size={300}
244-
style={{
245-
color: tokens.colorNeutralForeground1,
246-
display: 'block',
247-
marginBottom: '4px',
248-
}}
249-
>
250-
Timelines
251-
</Text>
252-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
253-
{brief.timelines}
254-
</Text>
255-
</div>
256-
)}
257-
258-
{/* Call to Action section */}
259-
{brief.cta && (
260-
<div>
261-
<Text
262-
weight="semibold"
263-
size={300}
264-
style={{
265-
color: tokens.colorNeutralForeground1,
266-
display: 'block',
267-
marginBottom: '4px',
268-
}}
269-
>
270-
Call to Action
271-
</Text>
272-
<Text size={200} style={{ color: tokens.colorNeutralForeground2, lineHeight: '1.5' }}>
273-
{brief.cta}
274-
</Text>
275-
</div>
276-
)}
104+
))}
277105
</div>
278106
)}
279107

0 commit comments

Comments
 (0)