Alright, let's run this and see what happens. Take your bets on Xylos. Will it be Xylos? Will it be Xylos? Come on, come on, come on.
The first breath of Olyndria felt like liquid moonlight.

Wonderful. And then we can see some fascinating little logs here, which we'll get to in a second.
Filling Ellara's lungs with an ozone tang she'd only ever read about in ancient star logs.
Okay the important bit though are these logs just after it here.
In the first log we can see that only two facts have been added. Then we zoom to the next log we can see there are four facts here.

Then going further down we end up with six and then finally it looks like eight logs here if I'm counting correctly. Probably not. Oh no, six logs but some of them are very long.
Very cool. The way this is working is that we have a streamText call here, which is exactly the same. Apart from the fact that you don't need to await this, await does nothing here because we're streaming. So as soon as the information is available, then we're good to go. The important part though, is this for await loop down the bottom here.
const factsResult = streamText({model,prompt: `Give me some facts about the imaginary planet. Here's the story: ${finalText}`,output: Output.object({schema: z.object({facts: z.array(z.string()).describe(
This is where we do our awaiting, where we're awaiting the next chunk of the factsResult.partialOutputStream and then logging that chunk. And as we can see, this is typed. It's typed as:
const chunk: PartialObject<{facts: string[];}>
This means that we can actually log this directly, if we want to chunk.facts, for instance. And as we can see too from the output, it's always the most up-to-date version of that object.
In other words, if we were to log out something from the normal streamText, it would log out each chunk delta individually. Whereas here, it's always giving us the most up-to-date version of the object, which I think is a sensible compromise.

There is a deprecated v5 version of this too in the second solution here, where you have streamObject. Again, this is a very, very similar API and it will continue to work in v6. It's just instead of partialOutputStream, it's now partialObjectStream and you don't need to pass in Output.object here, you just pass the schema directly into streamObject.
V5 Version:
// The old way: use streamObject directly instead of streamText + Output.objectconst factsResult = streamObject({model,prompt: `Give me some facts about the imaginary planet. Here's the story: ${finalText}`,schema: z.object({facts: z.array(z.string()).describe(
Now one final caveat here, I've obviously added these videos since the AI SDK 6 came out, but a lot of exercises in this course were built for version 5. And so many of them do use this streamObject syntax.
So I'd say feel free, whenever you see a streamObject call in this course, just replace it in your head with a streamText call with Output.object since they behave exactly the same way apart from you get partialOutputStream versus partialObjectStream. That's like the only difference.
So with that caveat out the way, nice work and I'll see you in the next one.