All files / src/core-entities llm-call-log.entity.ts

100% Statements 17/17
100% Branches 0/0
100% Functions 0/0
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 10246x 46x 46x                                     46x             46x                 46x               46x           46x           46x               46x             46x             46x             46x             46x           46x    
import { Entity, Column, Index } from 'typeorm';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { BaseEntity } from '../core-entities/base.entity';
 
/**
 * LlmCallLog records every request made to an LLM provider.
 *
 * Each log captures:
 * - Request details (provider, model, request body)
 * - Response details (response body, status code, latency)
 * - Token usage (input, output, cached tokens)
 * - Error information if the request failed
 *
 * Use these logs to:
 * - Monitor LLM usage and costs
 * - Debug failed requests
 * - Analyze token consumption patterns
 * - Track latency across providers
 */
@Entity('llm_call_logs')
@Index('IDX_llm_call_logs_created_at', ['created_at'])
export class LlmCallLog extends BaseEntity {
  @ApiPropertyOptional({
    description: 'UUID of the session input that triggered this call',
    format: 'uuid',
  })
  @Index()
  @Column({ type: 'varchar', nullable: true })
  session_input_id: string | null;
 
  @ApiProperty({
    description: 'LLM provider used for this request',
    enum: ['zai', 'openrouter', 'gemini', 'alibaba', 'ollama', 'openai'],
    example: 'gemini',
  })
  @Index()
  @Column({ type: 'text' })
  provider: 'zai' | 'openrouter' | 'gemini' | 'alibaba' | 'ollama' | 'openai';
 
  @ApiProperty({
    description: 'Model identifier used for this request',
    example: 'gemini-2.0-flash',
  })
  @Index()
  @Column({ type: 'text' })
  model_id: string;
 
  @ApiProperty({
    description: 'Full request body sent to the provider (JSON string)',
  })
  @Column({ type: 'text' })
  request_body: string;
 
  @ApiPropertyOptional({
    description: 'Full response body received from the provider',
  })
  @Column({ type: 'text', nullable: true })
  response_body: string | null;
 
  @ApiPropertyOptional({
    description: 'HTTP status code of the response',
    example: 200,
  })
  @Index()
  @Column({ type: 'integer', nullable: true })
  status_code: number | null;
 
  @ApiPropertyOptional({
    description: 'Request latency in milliseconds',
    example: 2500,
  })
  @Column({ type: 'integer', nullable: true })
  latency_ms: number | null;
 
  @ApiPropertyOptional({
    description: 'Number of input tokens used',
    example: 5000,
  })
  @Column({ type: 'integer', nullable: true })
  input_tokens: number | null;
 
  @ApiPropertyOptional({
    description: 'Number of output tokens generated',
    example: 800,
  })
  @Column({ type: 'integer', nullable: true })
  output_tokens: number | null;
 
  @ApiPropertyOptional({
    description: 'Number of cached tokens used (for context caching)',
    example: 3000,
  })
  @Column({ type: 'integer', nullable: true })
  cached_tokens: number | null;
 
  @ApiPropertyOptional({
    description: 'Error message if the request failed',
  })
  @Column({ type: 'text', nullable: true })
  error_message: string | null;
}