Skip to content

Commit 6d198a6

Browse files
committed
Add demo for structured output about generating recipes
1 parent f9da9c0 commit 6d198a6

File tree

24 files changed

+573
-101
lines changed

24 files changed

+573
-101
lines changed
Lines changed: 1 addition & 0 deletions
Loading

ai.symfony.com/assets/styles/app.css

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,14 @@ button#themeToggle {
215215
color: white;
216216
}
217217

218+
.demo-audio .demo-icon { background: linear-gradient(180deg, #42DEEE, #7069B0); }
218219
.demo-blog .demo-icon { background: linear-gradient(180deg, #433F77, #C43BC2); }
219-
.demo-youtube .demo-icon { background: linear-gradient(180deg, #C05920, #CF781A); }
220-
.demo-wikipedia .demo-icon { background: linear-gradient(180deg, #1CA574, #56AB48); }
221220
.demo-crop .demo-icon { background: linear-gradient(180deg, #85A72B, #97BC43); }
222-
.demo-audio .demo-icon { background: linear-gradient(180deg, #42DEEE, #7069B0); }
223-
.demo-video .demo-icon { background: linear-gradient(180deg, #3B9D87, #35A781); }
221+
.demo-recipe .demo-icon { background: linear-gradient(180deg, #83A659, #71BCB8); }
224222
.demo-turbo .demo-icon { background: linear-gradient(180deg, #E94E77, #D68189); }
223+
.demo-video .demo-icon { background: linear-gradient(180deg, #3B9D87, #35A781); }
224+
.demo-wikipedia .demo-icon { background: linear-gradient(180deg, #1CA574, #56AB48); }
225+
.demo-youtube .demo-icon { background: linear-gradient(180deg, #C05920, #CF781A); }
225226

226227
.footer-meta {
227228
font-size: 0.8rem;

ai.symfony.com/templates/homepage.html.twig

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -169,43 +169,42 @@
169169

170170
<div class="row g-4">
171171
<div class="col-md-6">
172-
<article class="demo-blog sf-ai-card sf-ai-card-hover h-100">
172+
<article class="demo-youtube sf-ai-card sf-ai-card-hover h-100">
173173
<div class="position-relative card-body p-3 p-lg-4 d-flex gap-3 align-items-start">
174-
<div class="demo-icon bg-primary bg-opacity-10 text-primary flex-shrink-0">
175-
{{ ux_icon('logos:symfony-letters', {width: 36, height: 36}) }}
174+
<div class="demo-icon bg-warning bg-opacity-10 text-warning flex-shrink-0">
175+
{{ ux_icon('tabler:brand-youtube', {width: 42, height: 42}) }}
176176
</div>
177177
<div class="flex-grow-1">
178178
<div class="d-flex align-items-start gap-2 mb-1">
179179
<h3 class="h5 ff-title fw-bold mb-0">
180-
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Symfony Blog Bot</a>
180+
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Youtube Transcript Bot</a>
181181
</h3>
182182
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
183183
</div>
184184
<p class="text-balance mb-0 text-muted small">
185-
Retrieval Augmented Generation (RAG) based on Symfony's blog dumped to a
186-
vector store.
185+
Question answering started with a YouTube video ID which gets converted
186+
into a transcript.
187187
</p>
188188
</div>
189189
</div>
190190
</article>
191191
</div>
192192

193193
<div class="col-md-6">
194-
<article class="demo-youtube sf-ai-card sf-ai-card-hover h-100">
194+
<article class="demo-recipe sf-ai-card sf-ai-card-hover h-100">
195195
<div class="position-relative card-body p-3 p-lg-4 d-flex gap-3 align-items-start">
196196
<div class="demo-icon bg-warning bg-opacity-10 text-warning flex-shrink-0">
197-
{{ ux_icon('tabler:brand-youtube', {width: 42, height: 42}) }}
197+
{{ ux_icon('mdi:cook', {width: 42, height: 42}) }}
198198
</div>
199199
<div class="flex-grow-1">
200200
<div class="d-flex align-items-start gap-2 mb-1">
201201
<h3 class="h5 ff-title fw-bold mb-0">
202-
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Youtube Transcript Bot</a>
202+
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Recipe Bot</a>
203203
</h3>
204204
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
205205
</div>
206206
<p class="text-balance mb-0 text-muted small">
207-
Question answering started with a YouTube video ID which gets converted
208-
into a transcript.
207+
Chatbot for proposing cooking recipes - powered by structured output.
209208
</p>
210209
</div>
211210
</div>
@@ -235,20 +234,21 @@
235234
</div>
236235

237236
<div class="col-md-6">
238-
<article class="demo-crop sf-ai-card sf-ai-card-hover h-100">
237+
<article class="demo-blog sf-ai-card sf-ai-card-hover h-100">
239238
<div class="position-relative card-body p-3 p-lg-4 d-flex gap-3 align-items-start">
240-
<div class="demo-icon bg-success bg-opacity-10 text-success flex-shrink-0">
241-
{{ ux_icon('tabler:crop', {width: 42, height: 42}) }}
239+
<div class="demo-icon bg-primary bg-opacity-10 text-primary flex-shrink-0">
240+
{{ ux_icon('logos:symfony-letters', {width: 36, height: 36}) }}
242241
</div>
243242
<div class="flex-grow-1">
244243
<div class="d-flex align-items-start gap-2 mb-1">
245244
<h3 class="h5 ff-title fw-bold mb-0">
246-
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Smart Cropping</a>
245+
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Symfony Blog Bot</a>
247246
</h3>
248247
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
249248
</div>
250249
<p class="text-balance mb-0 text-muted small">
251-
AI-assisted image cropping to focus on key elements on the image while resizing.
250+
Retrieval Augmented Generation (RAG) based on Symfony's blog dumped to a
251+
vector store.
252252
</p>
253253
</div>
254254
</div>
@@ -264,13 +264,13 @@
264264
<div class="flex-grow-1">
265265
<div class="d-flex align-items-start gap-2 mb-1">
266266
<h3 class="h5 ff-title fw-bold mb-0">
267-
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Audio Bot</a>
267+
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Audio Bot + Subagent</a>
268268
</h3>
269269
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
270270
</div>
271271
<p class="text-balance mb-0 text-muted small">
272-
Simple demonstration of speech to text with Whisper in combination with
273-
GPT.
272+
Demonstration of speech-to-text & text-to-speech and a subagent, combining 4
273+
models in total.
274274
</p>
275275
</div>
276276
</div>
@@ -291,8 +291,28 @@
291291
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
292292
</div>
293293
<p class="text-balance mb-0 text-muted small">
294-
Simple demonstration of vision capabilities of GPT in combination with
295-
your webcam.
294+
Demonstration of vision capabilities of GPT in combination with your webcam.
295+
</p>
296+
</div>
297+
</div>
298+
</article>
299+
</div>
300+
301+
<div class="col-md-6">
302+
<article class="demo-crop sf-ai-card sf-ai-card-hover h-100">
303+
<div class="position-relative card-body p-3 p-lg-4 d-flex gap-3 align-items-start">
304+
<div class="demo-icon bg-success bg-opacity-10 text-success flex-shrink-0">
305+
{{ ux_icon('tabler:crop', {width: 42, height: 42}) }}
306+
</div>
307+
<div class="flex-grow-1">
308+
<div class="d-flex align-items-start gap-2 mb-1">
309+
<h3 class="h5 ff-title fw-bold mb-0">
310+
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Smart Image Cropping</a>
311+
</h3>
312+
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
313+
</div>
314+
<p class="text-balance mb-0 text-muted small">
315+
AI-assisted image cropping to focus on key elements on the image while resizing.
296316
</p>
297317
</div>
298318
</div>
@@ -308,12 +328,13 @@
308328
<div class="flex-grow-1">
309329
<div class="d-flex align-items-start gap-2 mb-1">
310330
<h3 class="h5 ff-title fw-bold mb-0">
311-
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Turbo stream Bot</a>
331+
<a href="https://github.com/symfony/ai-demo" class="stretched-link">Turbo Stream Bot</a>
312332
</h3>
313333
{{ ux_icon('tabler:arrow-right', {width: 24, height: 24, class: 'ms-1'}) }}
314334
</div>
315335
<p class="text-balance mb-0 text-muted small">
316-
Simple demonstration of text streaming capabilities.
336+
Demonstration of streaming text responses in combination with markdown based on
337+
Turbo and SSE.
317338
</p>
318339
</div>
319340
</div>

demo/assets/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import './styles/app.css';
44
import './styles/audio.css';
55
import './styles/blog.css';
66
import './styles/crop.css';
7+
import './styles/recipe.css';
78
import './styles/stream.css';
89
import './styles/youtube.css';
910
import './styles/video.css';
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
import { getComponent } from '@symfony/ux-live-component';
3+
4+
export default class extends Controller {
5+
async initialize() {
6+
this.component = await getComponent(this.element);
7+
8+
const input = document.getElementById('chat-message');
9+
input.addEventListener('keypress', (event) => {
10+
if (event.key === 'Enter') {
11+
this.submitMessage();
12+
}
13+
});
14+
input.focus();
15+
16+
const resetButton = document.getElementById('chat-reset');
17+
resetButton.addEventListener('click', (event) => {
18+
this.component.action('reset');
19+
});
20+
21+
const submitButton = document.getElementById('chat-submit');
22+
submitButton.addEventListener('click', (event) => {
23+
this.submitMessage();
24+
});
25+
26+
this.component.on('loading.state:started', (e,r) => {
27+
if (r.actions.includes('reset')) {
28+
return;
29+
}
30+
document.getElementById('welcome')?.remove();
31+
document.getElementById('recipe-card')?.setAttribute('class', 'd-none');
32+
document.getElementById('loading-message').removeAttribute('class');
33+
});
34+
35+
this.component.on('loading.state:finished', () => {
36+
document.getElementById('loading-message').setAttribute('class', 'd-none');
37+
document.getElementById('recipe-card')?.removeAttribute('class');
38+
});
39+
};
40+
41+
submitMessage() {
42+
const input = document.getElementById('chat-message');
43+
const message = input.value;
44+
this.component.action('submit', { message });
45+
input.value = '';
46+
}
47+
}
Lines changed: 1 addition & 0 deletions
Loading

demo/assets/icons/mdi/clock.svg

Lines changed: 1 addition & 0 deletions
Loading

demo/assets/icons/mdi/cook.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading

demo/assets/icons/mdi/leaf.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)