All files / src/providers/openai OpenAIProvider.ts

84.37% Statements 27/32
66.66% Branches 4/6
77.27% Functions 17/22
84.37% Lines 27/32

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                                                                                48x 2x 2x 2x 2x 1x 2x       18x       48x 48x 48x 48x 48x 48x 48x 48x 48x 48x       80x                     50x               23x       3x       4x       2x       3x       2x       5x      
import {
  Provider,
  ChatRequest,
  ChatResponse,
  ModelInfo,
  ChatChunk,
  ImageRequest,
  ImageResponse,
  TranscriptionRequest,
  TranscriptionResponse,
  ModerationRequest,
  ModerationResponse,
  EmbeddingRequest,
  EmbeddingResponse
} from "../Provider.js";
import { BaseProvider } from "../BaseProvider.js";
import { Capabilities } from "./Capabilities.js";
import { OpenAIChat } from "./Chat.js";
import { OpenAIStreaming } from "./Streaming.js";
import { OpenAIModels } from "./Models.js";
import { OpenAIImage } from "./Image.js";
import { OpenAITranscription } from "./Transcription.js";
import { OpenAIModeration } from "./Moderation.js";
import { OpenAIEmbedding } from "./Embedding.js";
 
export interface OpenAIProviderOptions {
  apiKey: string;
  baseUrl?: string;
}
 
export class OpenAIProvider extends BaseProvider implements Provider {
  protected baseUrl: string;
  protected chatHandler: OpenAIChat;
  protected streamingHandler: OpenAIStreaming;
  protected modelsHandler: OpenAIModels;
  protected imageHandler: OpenAIImage;
  protected transcriptionHandler: OpenAITranscription;
  protected moderationHandler: OpenAIModeration;
  protected embeddingHandler: OpenAIEmbedding;
 
  public capabilities = {
    supportsVision: (model: string) => Capabilities.supportsVision(model),
    supportsTools: (model: string) => Capabilities.supportsTools(model),
    supportsStructuredOutput: (model: string) => Capabilities.supportsStructuredOutput(model),
    supportsEmbeddings: (model: string) => Capabilities.supportsEmbeddings(model),
    supportsImageGeneration: (model: string) => Capabilities.supportsImageGeneration(model),
    supportsTranscription: (model: string) => Capabilities.supportsTranscription(model),
    supportsModeration: (model: string) => Capabilities.supportsModeration(model),
    supportsReasoning: (model: string) => Capabilities.supportsReasoning(model),
    supportsDeveloperRole: (modelId: string) =>
      this.baseUrl.includes("api.openai.com") && Capabilities.supportsDeveloperRole(modelId),
    getContextWindow: (model: string) => Capabilities.getContextWindow(model) || null
  };
 
  constructor(protected readonly options: OpenAIProviderOptions) {
    super();
    this.baseUrl = options.baseUrl ?? "https://api.openai.com/v1";
    this.chatHandler = new OpenAIChat(this, options.apiKey);
    this.streamingHandler = new OpenAIStreaming(this, options.apiKey);
    this.modelsHandler = new OpenAIModels(this.baseUrl, options.apiKey);
    this.imageHandler = new OpenAIImage(this.baseUrl, options.apiKey);
    this.transcriptionHandler = new OpenAITranscription(this.baseUrl, options.apiKey);
    this.moderationHandler = new OpenAIModeration(this.baseUrl, options.apiKey);
    this.embeddingHandler = new OpenAIEmbedding(this.baseUrl, options.apiKey);
  }
 
  public apiBase(): string {
    return this.baseUrl;
  }
 
  public headers(): Record<string, string> {
    return {
      Authorization: `Bearer ${this.options.apiKey}`,
      "Content-Type": "application/json"
    };
  }
 
  protected providerName(): string {
    return "OpenAI";
  }
 
  public override defaultModel(_feature?: string): string {
    return "gpt-4o";
  }
 
  async chat(request: ChatRequest): Promise<ChatResponse> {
    return this.chatHandler.execute(request);
  }
 
  async *stream(request: ChatRequest): AsyncGenerator<ChatChunk> {
    yield* this.streamingHandler.execute(request);
  }
 
  async listModels(): Promise<ModelInfo[]> {
    return this.modelsHandler.execute();
  }
 
  async paint(request: ImageRequest): Promise<ImageResponse> {
    return this.imageHandler.execute(request);
  }
 
  async transcribe(request: TranscriptionRequest): Promise<TranscriptionResponse> {
    return this.transcriptionHandler.execute(request);
  }
 
  async moderate(request: ModerationRequest): Promise<ModerationResponse> {
    return this.moderationHandler.execute(request);
  }
 
  async embed(request: EmbeddingRequest): Promise<EmbeddingResponse> {
    return this.embeddingHandler.execute(request);
  }
}