All files / src/providers/deepseek DeepSeekProvider.ts

58.33% Statements 14/24
100% Branches 2/2
44.44% Functions 8/18
58.33% Lines 14/24

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                                    19x 1x 1x 1x                   19x 19x 19x 19x 19x 19x                             30x               8x       3x       2x          
import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk } from "../Provider.js";
import { BaseProvider } from "../BaseProvider.js";
import { DeepSeekChat } from "./Chat.js";
import { DeepSeekModels } from "./Models.js";
import { DeepSeekStreaming } from "./Streaming.js";
import { Capabilities } from "./Capabilities.js";
 
export interface DeepSeekProviderOptions {
  apiKey: string;
  baseUrl?: string;
}
 
export class DeepSeekProvider extends BaseProvider implements Provider {
  private readonly baseUrl: string;
  private readonly chatHandler: DeepSeekChat;
  private readonly streamingHandler: DeepSeekStreaming;
  private readonly modelsHandler: DeepSeekModels;
 
  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: (_model: string) => false,
    getContextWindow: (model: string) => Capabilities.getContextWindow(model)
  };
 
  constructor(private readonly options: DeepSeekProviderOptions) {
    super();
    this.baseUrl = options.baseUrl ?? "https://api.deepseek.com";
    this.chatHandler = new DeepSeekChat(this.baseUrl, options.apiKey);
    this.streamingHandler = new DeepSeekStreaming(this.baseUrl, options.apiKey);
    this.modelsHandler = new DeepSeekModels(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 "DeepSeek";
  }
 
  public override defaultModel(_feature?: string): string {
    return "deepseek-chat";
  }
 
  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();
  }
 
  // Other features (paint, transcribe, moderate, embed) will use BaseProvider's default implementations
}