All files / src/providers/anthropic AnthropicProvider.ts

75% Statements 18/24
100% Branches 2/2
66.66% Functions 12/18
75% Lines 18/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 74                                    20x 2x 1x 1x 1x 1x 1x 1x           20x 20x 20x 20x 20x 20x                               28x               9x       1x       2x          
import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk } from "../Provider.js";
import { BaseProvider } from "../BaseProvider.js";
import { Capabilities } from "./Capabilities.js";
import { AnthropicChat } from "./Chat.js";
import { AnthropicStreaming } from "./Streaming.js";
import { AnthropicModels } from "./Models.js";
 
export interface AnthropicProviderOptions {
  apiKey: string;
  baseUrl?: string;
}
 
export class AnthropicProvider extends BaseProvider implements Provider {
  private readonly baseUrl: string;
  private readonly chatHandler: AnthropicChat;
  private readonly streamHandler: AnthropicStreaming;
  private readonly modelsHandler: AnthropicModels;
 
  public capabilities = {
    supportsVision: (model: string) => Capabilities.supportsVision(model),
    supportsTools: (model: string) => Capabilities.supportsTools(model),
    supportsStructuredOutput: (model: string) => Capabilities.supportsJsonMode(model),
    supportsEmbeddings: (_model: string) => false,
    supportsImageGeneration: (_model: string) => false,
    supportsTranscription: (_model: string) => false,
    supportsModeration: (_model: string) => false,
    supportsReasoning: (_model: string) => false,
    supportsDeveloperRole: (_model: string) => true,
    getContextWindow: (model: string) => Capabilities.getContextWindow(model)
  };
 
  constructor(private readonly options: AnthropicProviderOptions) {
    super();
    this.baseUrl = options.baseUrl ?? "https://api.anthropic.com/v1";
    this.chatHandler = new AnthropicChat(this.baseUrl, options.apiKey);
    this.streamHandler = new AnthropicStreaming(this.baseUrl, options.apiKey);
    this.modelsHandler = new AnthropicModels(this.baseUrl, options.apiKey);
  }
 
  public apiBase(): string {
    return this.baseUrl;
  }
 
  public headers(): Record<string, string> {
    return {
      "x-api-key": this.options.apiKey,
      "anthropic-version": "2023-06-01",
      "Content-Type": "application/json"
    };
  }
 
  protected providerName(): string {
    return "Anthropic";
  }
 
  public override defaultModel(_feature?: string): string {
    return "claude-3-5-haiku-20241022";
  }
 
  async chat(request: ChatRequest): Promise<ChatResponse> {
    return this.chatHandler.execute(request);
  }
 
  async *stream(request: ChatRequest): AsyncGenerator<ChatChunk> {
    yield* this.streamHandler.execute(request);
  }
 
  async listModels(): Promise<ModelInfo[]> {
    return this.modelsHandler.execute();
  }
 
  // Unsupported features will use BaseProvider's default implementations
}