C.W.K.
Stream
Lesson 02 of 04 · published

generateContent() & Streaming

~12 min · typescript, generation, streaming

Level 0Spark
0 XP0/35 lessons0/10 achievements
0/140 XP to next level140 XP to go0% complete

The same API, TypeScript shape

The TS SDK mirrors Python's surface but with TypeScript-friendly object args. Where Python takes model='...', contents='...' as kwargs, TypeScript takes a single object: { model, contents, config }.

response.text is a property

The biggest gotcha when porting from the legacy SDK: response.text is a property, not a method. If you write response.text(), you'll get a "string is not callable" error.

Streaming uses generateContentStream

The streaming function is named differently and returns an async iterable directly:

  • ai.models.generateContent(...) — single response, awaitable.
  • ai.models.generateContentStream(...) — async iterable of chunks.

Use for await to consume the stream. chunk.text on each chunk gives you the partial text.

Code

Single-shot generate·typescript
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Why is the sky blue?',
});
console.log(response.text);

// With config
const response2 = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Explain quantum entanglement.',
  config: {
    systemInstruction: 'You are a precise but warm tutor.',
    maxOutputTokens: 500,
    temperature: 0.3,
    topP: 0.9,
    topK: 40,
  },
});
Reading the response·typescript
// 90% case: just the text
console.log(response.text);  // string

// Function calls (Track 5)
console.log(response.functionCalls);  // FunctionCall[] | undefined

// Finish reason — always check before trusting text
const finishReason = response.candidates?.[0]?.finishReason;
if (finishReason !== 'STOP') {
  throw new Error(`Generation did not finish cleanly: ${finishReason}`);
}

// Token counts
console.log(response.usageMetadata?.totalTokenCount);
Streaming·typescript
const stream = await ai.models.generateContentStream({
  model: 'gemini-2.5-flash',
  contents: 'Write a 200-word story.',
});

let finalUsage;
for await (const chunk of stream) {
  if (chunk.text) {
    process.stdout.write(chunk.text);
  }
  if (chunk.usageMetadata) {
    finalUsage = chunk.usageMetadata;
  }
}
console.log(`\n[total tokens: ${finalUsage?.totalTokenCount}]`);

External links

Exercise

Write a small Node script stream.mjs that takes a prompt as process.argv[2] and streams Flash's response to stdout. Then write a tiny Express endpoint that proxies the stream to a browser via SSE. The proxy lesson is in Track 4; for now, just confirm you can pipe Gemini → server → terminal.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.