stream method

  1. @override
Stream<String> stream({
  1. required String apiKey,
  2. required String model,
  3. required ChatRequest request,
})
override

Token-streaming chat. Each event is an incremental delta — concatenating every event yields the same string chat would return. Closes the stream cleanly on end-of-message; errors are surfaced via the stream.

Implementation

@override
Stream<String> stream({
  required String apiKey,
  required String model,
  required ChatRequest request,
}) async* {
  final body = jsonEncode(_buildPayload(model, request, stream: true));
  final byteStream = await openSsePost(
    uri: Uri.parse('$_baseUrl/messages'),
    headers: {
      ..._headers(apiKey),
      'Accept': 'text/event-stream',
    },
    body: body,
    providerLabel: 'Anthropic',
    client: _http,
  );
  // Anthropic stream events:
  //  - content_block_delta → { delta: { type: 'text_delta', text } }
  //  - message_stop → end of stream
  // Other events (message_start, ping, etc.) are ignored here.
  await for (final event in decodeSseStream(byteStream)) {
    if (event.event == 'message_stop') return;
    if (event.event != 'content_block_delta') continue;
    if (event.data.isEmpty) continue;
    final json = jsonDecode(event.data) as Map<String, Object?>;
    final delta = json['delta'] as Map<String, Object?>?;
    if (delta == null) continue;
    if (delta['type'] != 'text_delta') continue;
    final text = delta['text'] as String?;
    if (text != null && text.isNotEmpty) yield text;
  }
}