All files / src/chat ChatResponse.ts

70.37% Statements 19/27
100% Branches 0/0
63.15% Functions 12/19
70.37% Lines 19/27

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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118                    215x 215x 215x 215x 215x 215x   215x       1x     1x     4x                                 1x     1x     1x             29x                       1x                                   226x             2x                               6x 6x            
import { Usage, ThinkingResult } from "../providers/Provider.js";
import { ToolCall } from "./Tool.js";
 
/**
 * Enhanced string that includes token usage metadata.
 * Behaves like a regular string but has .usage and .input_tokens etc.
 */
export class ChatResponseString extends String {
  constructor(
    content: string,
    public readonly usage: Usage,
    public readonly model: string,
    public readonly provider: string,
    public readonly thinking?: ThinkingResult,
    public readonly reasoning?: string | null,
    public readonly tool_calls?: ToolCall[]
  ) {
    super(content);
  }
 
  get input_tokens() {
    return this.usage.input_tokens;
  }
  get output_tokens() {
    return this.usage.output_tokens;
  }
  get total_tokens() {
    return this.usage.total_tokens;
  }
  get cached_tokens() {
    return this.usage.cached_tokens;
  }
  get cost() {
    return this.usage.cost;
  }
  get input_cost() {
    return this.usage.input_cost;
  }
  get output_cost() {
    return this.usage.output_cost;
  }
 
  // --- CamelCase Aliases (for Developer Delight) ---
  get inputTokens() {
    return this.input_tokens;
  }
  get outputTokens() {
    return this.output_tokens;
  }
  get totalTokens() {
    return this.total_tokens;
  }
  get cachedTokens() {
    return this.cached_tokens;
  }
 
  get content(): string {
    return this.valueOf();
  }
 
  get model_id(): string {
    return this.model;
  }
 
  /**
   * Returns a serializable object containing all response metadata.
   * Perfect for database persistence.
   */
  get meta() {
    return {
      usage: this.usage,
      model: this.model,
      provider: this.provider,
      thinking: this.thinking,
      reasoning: this.reasoning,
      tool_calls: this.tool_calls
    };
  }
 
  /**
   * Alias for meta (backwards compatibility)
   */
  get raw() {
    return this.meta;
  }
 
  toString() {
    return this.valueOf();
  }
 
  /**
   * Return a new ChatResponseString with modified content but preserved metadata.
   */
  withContent(newContent: string): ChatResponseString {
    return new ChatResponseString(
      newContent,
      this.usage,
      this.model,
      this.provider,
      this.thinking,
      this.reasoning,
      this.tool_calls
    );
  }
 
  /**
   * Attempt to parse the content as JSON.
   * Returns the parsed object or null if parsing fails.
   */
  get parsed(): unknown {
    try {
      return JSON.parse(this.valueOf());
    } catch {
      return null;
    }
  }
}