embed method

  1. @override
Future<List<Float32List>> embed(
  1. List<String> texts, {
  2. EmbedPurpose purpose = EmbedPurpose.document,
})
override

Embeds texts, returning one vector per text, in order.

Implementation

@override
Future<List<Float32List>> embed(
  List<String> texts, {
  EmbedPurpose purpose = EmbedPurpose.document,
}) async {
  final out = <Float32List>[];
  for (var i = 0; i < texts.length; i += batchSize) {
    final batch = texts.sublist(i, (i + batchSize).clamp(0, texts.length));
    final json = await _http
        .postJson(joinUrl(baseUrl, 'embeddings'), _auth(apiKey, headers), {
          ...extraBody,
          'model': model,
          'input': batch,
          if (requestDimensions) 'dimensions': dimensions,
          ?purposeField: purpose.name,
        });
    final data = json['data'];
    if (data is! List || data.length != batch.length) {
      throw LlmException(
        'expected ${batch.length} embeddings, got '
        '${data is List ? data.length : 'none'}',
      );
    }
    final ordered = [...data.cast<Map>()]
      ..sort(
        (a, b) =>
            ((a['index'] as num?) ?? 0).compareTo((b['index'] as num?) ?? 0),
      );
    for (final item in ordered) {
      final raw = item['embedding'];
      if (raw is! List || raw.length != dimensions) {
        throw LlmException(
          'expected $dimensions-dimensional embeddings from $model, got '
          '${raw is List ? raw.length : 'none'}',
        );
      }
      out.add(
        Float32List.fromList([for (final v in raw) (v as num).toDouble()]),
      );
    }
  }
  return out;
}