Class: Embedding::CoverageReport::Breakdowns

Inherits:
Object
  • Object
show all
Includes:
Calculations
Defined in:
app/queries/embedding/coverage_report.rb

Overview

Detailed pipeline diagnostics shown below the source coverage rows.

Constant Summary collapse

EMPTY_IMAGE =
{
  total: 0, with_fingerprint: 0, with_unified: 0, with_vision: 0,
  fully_complete: 0, orphaned_embeddings: 0, orphaned_vision: 0,
  fingerprint_coverage: 0.0, unified_coverage: 0.0,
  vision_coverage: 0.0, coverage: 0.0
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(candidate_scopes:, searchable_embeddings:) ⇒ Breakdowns

Returns a new instance of Breakdowns.



276
277
278
279
# File 'app/queries/embedding/coverage_report.rb', line 276

def initialize(candidate_scopes:, searchable_embeddings:)
  @candidate_scopes = candidate_scopes
  @searchable_embeddings = searchable_embeddings
end

Instance Method Details

#activity(total:, with_embedding:) ⇒ Object



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'app/queries/embedding/coverage_report.rb', line 349

def activity(total:, with_embedding:)
  return { total_eligible: 0 } unless total.to_i.positive?

  eligible = candidate_scopes.fetch('Activity')
  embeddings = searchable_embeddings.where(
    embeddable_type: 'Activity',
    embeddable_id: eligible.select(:id)
  )

  {
    total_all: Activity.count,
    total_eligible: total,
    with_embedding: with_embedding,
    coverage: coverage_percentage(with_embedding, total),
    oldest_embedded: embeddings.minimum(:created_at),
    newest_embedded: embeddings.maximum(:created_at)
  }
end

#call_recordObject



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'app/queries/embedding/coverage_report.rb', line 322

def call_record
  total_with_audio = calls_with_transcribable_audio.count
  embedding_candidates = CallRecord.transcription_state_completed.with_transcript
  embedding_candidate_count = embedding_candidates.count
  with_embedding = embedding_candidates.where(id: searchable_embedding_ids('CallRecord')).count
  transcribed = CallRecord.transcription_state_completed.count

  {
    total: CallRecord.count,
    total_with_audio: total_with_audio,
    transcribed: transcribed,
    processing: CallRecord.transcription_state_processing.count,
    pending: calls_with_transcribable_audio.transcription_state_pending.count,
    errors: CallRecord.transcription_state_error.count,
    too_short: CallRecord.transcription_state_too_short.count,
    no_audio: CallRecord.transcription_state_no_audio.count,
    with_summary: CallRecord.where.not(ai_summary: nil).count,
    embedding_candidates: embedding_candidate_count,
    with_embedding: with_embedding,
    transcription_coverage: coverage_percentage(transcribed, total_with_audio),
    embedding_coverage: coverage_percentage(with_embedding, embedding_candidate_count),
    inbound: CallRecord.call_direction_inbound.transcription_state_completed.count,
    outbound: CallRecord.call_direction_outbound.transcription_state_completed.count,
    outcomes: call_outcomes
  }
end

#communication(total:, with_embedding:) ⇒ Object



368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'app/queries/embedding/coverage_report.rb', line 368

def communication(total:, with_embedding:)
  eligible = candidate_scopes.fetch('Communication')
  return { total_eligible: 0 } unless total.to_i.positive?

  directions = eligible.group(:direction).count
  {
    total_eligible: total,
    inbound: directions['inbound'].to_i,
    outbound: directions['outbound'].to_i,
    with_embedding: with_embedding,
    coverage: coverage_percentage(with_embedding, total)
  }
end

#imageObject



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'app/queries/embedding/coverage_report.rb', line 292

def image
  images = Image.active
  total = images.count
  return EMPTY_IMAGE if total.zero?

  searchable = images.where(id: searchable_embedding_ids('Image'))
  with_vision = images.where.not(ai_visual_description: [nil, ''])
  with_fingerprint_count = images.where.not(fingerprint: nil).count
  with_unified_count = searchable.count
  with_vision_count = with_vision.count
  fully_complete = searchable
                   .where.not(fingerprint: nil)
                   .where.not(ai_visual_description: [nil, ''])
                   .count

  {
    total: total,
    with_fingerprint: with_fingerprint_count,
    with_unified: with_unified_count,
    with_vision: with_vision_count,
    fully_complete: fully_complete,
    orphaned_embeddings: searchable.where(ai_visual_description: [nil, '']).count,
    orphaned_vision: with_vision.where.not(id: searchable_embedding_ids('Image')).count,
    fingerprint_coverage: coverage_percentage(with_fingerprint_count, total),
    unified_coverage: coverage_percentage(with_unified_count, total),
    vision_coverage: coverage_percentage(with_vision_count, total),
    coverage: coverage_percentage(fully_complete, total)
  }
end

#videoObject



281
282
283
284
285
286
287
288
289
290
# File 'app/queries/embedding/coverage_report.rb', line 281

def video
  videos = Video.active.cloudflare_videos
  {
    no_spoken_words: videos.where(video_has_no_spoken_words: true).count,
    awaiting_transcript: videos
                         .where(video_has_no_spoken_words: [false, nil])
                         .where(transcript: [nil, ''])
                         .count
  }
end