index.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { Anthropic } from "@anthropic-ai/sdk"
  2. import OpenAI from "openai"
  3. import type { ProviderSettings, ModelInfo, ToolProtocol } from "@roo-code/types"
  4. import { ApiStream } from "./transform/stream"
  5. import {
  6. GlamaHandler,
  7. AnthropicHandler,
  8. AwsBedrockHandler,
  9. CerebrasHandler,
  10. OpenRouterHandler,
  11. VertexHandler,
  12. AnthropicVertexHandler,
  13. OpenAiHandler,
  14. LmStudioHandler,
  15. GeminiHandler,
  16. OpenAiNativeHandler,
  17. DeepSeekHandler,
  18. MoonshotHandler,
  19. MistralHandler,
  20. VsCodeLmHandler,
  21. UnboundHandler,
  22. RequestyHandler,
  23. HumanRelayHandler,
  24. FakeAIHandler,
  25. XAIHandler,
  26. GroqHandler,
  27. HuggingFaceHandler,
  28. ChutesHandler,
  29. LiteLLMHandler,
  30. ClaudeCodeHandler,
  31. QwenCodeHandler,
  32. SambaNovaHandler,
  33. IOIntelligenceHandler,
  34. DoubaoHandler,
  35. ZAiHandler,
  36. FireworksHandler,
  37. RooHandler,
  38. FeatherlessHandler,
  39. VercelAiGatewayHandler,
  40. DeepInfraHandler,
  41. MiniMaxHandler,
  42. BasetenHandler,
  43. } from "./providers"
  44. import { NativeOllamaHandler } from "./providers/native-ollama"
  45. export interface SingleCompletionHandler {
  46. completePrompt(prompt: string): Promise<string>
  47. }
  48. export interface ApiHandlerCreateMessageMetadata {
  49. /**
  50. * Task ID used for tracking and provider-specific features:
  51. * - DeepInfra: Used as prompt_cache_key for caching
  52. * - Roo: Sent as X-Roo-Task-ID header
  53. * - Requesty: Sent as trace_id
  54. * - Unbound: Sent in unbound_metadata
  55. */
  56. taskId: string
  57. /**
  58. * Current mode slug for provider-specific tracking:
  59. * - Requesty: Sent in extra metadata
  60. * - Unbound: Sent in unbound_metadata
  61. */
  62. mode?: string
  63. suppressPreviousResponseId?: boolean
  64. /**
  65. * Controls whether the response should be stored for 30 days in OpenAI's Responses API.
  66. * When true (default), responses are stored and can be referenced in future requests
  67. * using the previous_response_id for efficient conversation continuity.
  68. * Set to false to opt out of response storage for privacy or compliance reasons.
  69. * @default true
  70. */
  71. store?: boolean
  72. /**
  73. * Optional array of tool definitions to pass to the model.
  74. * For OpenAI-compatible providers, these are ChatCompletionTool definitions.
  75. */
  76. tools?: OpenAI.Chat.ChatCompletionTool[]
  77. /**
  78. * Controls which (if any) tool is called by the model.
  79. * Can be "none", "auto", "required", or a specific tool choice.
  80. */
  81. tool_choice?: OpenAI.Chat.ChatCompletionCreateParams["tool_choice"]
  82. /**
  83. * The tool protocol being used (XML or Native).
  84. * Used by providers to determine whether to include native tool definitions.
  85. */
  86. toolProtocol?: ToolProtocol
  87. }
  88. export interface ApiHandler {
  89. createMessage(
  90. systemPrompt: string,
  91. messages: Anthropic.Messages.MessageParam[],
  92. metadata?: ApiHandlerCreateMessageMetadata,
  93. ): ApiStream
  94. getModel(): { id: string; info: ModelInfo }
  95. /**
  96. * Counts tokens for content blocks
  97. * All providers extend BaseProvider which provides a default tiktoken implementation,
  98. * but they can override this to use their native token counting endpoints
  99. *
  100. * @param content The content to count tokens for
  101. * @returns A promise resolving to the token count
  102. */
  103. countTokens(content: Array<Anthropic.Messages.ContentBlockParam>): Promise<number>
  104. }
  105. export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
  106. const { apiProvider, ...options } = configuration
  107. switch (apiProvider) {
  108. case "anthropic":
  109. return new AnthropicHandler(options)
  110. case "claude-code":
  111. return new ClaudeCodeHandler(options)
  112. case "glama":
  113. return new GlamaHandler(options)
  114. case "openrouter":
  115. return new OpenRouterHandler(options)
  116. case "bedrock":
  117. return new AwsBedrockHandler(options)
  118. case "vertex":
  119. return options.apiModelId?.startsWith("claude")
  120. ? new AnthropicVertexHandler(options)
  121. : new VertexHandler(options)
  122. case "openai":
  123. return new OpenAiHandler(options)
  124. case "ollama":
  125. return new NativeOllamaHandler(options)
  126. case "lmstudio":
  127. return new LmStudioHandler(options)
  128. case "gemini":
  129. return new GeminiHandler(options)
  130. case "openai-native":
  131. return new OpenAiNativeHandler(options)
  132. case "deepseek":
  133. return new DeepSeekHandler(options)
  134. case "doubao":
  135. return new DoubaoHandler(options)
  136. case "qwen-code":
  137. return new QwenCodeHandler(options)
  138. case "moonshot":
  139. return new MoonshotHandler(options)
  140. case "vscode-lm":
  141. return new VsCodeLmHandler(options)
  142. case "mistral":
  143. return new MistralHandler(options)
  144. case "unbound":
  145. return new UnboundHandler(options)
  146. case "requesty":
  147. return new RequestyHandler(options)
  148. case "human-relay":
  149. return new HumanRelayHandler()
  150. case "fake-ai":
  151. return new FakeAIHandler(options)
  152. case "xai":
  153. return new XAIHandler(options)
  154. case "groq":
  155. return new GroqHandler(options)
  156. case "deepinfra":
  157. return new DeepInfraHandler(options)
  158. case "huggingface":
  159. return new HuggingFaceHandler(options)
  160. case "chutes":
  161. return new ChutesHandler(options)
  162. case "litellm":
  163. return new LiteLLMHandler(options)
  164. case "cerebras":
  165. return new CerebrasHandler(options)
  166. case "sambanova":
  167. return new SambaNovaHandler(options)
  168. case "zai":
  169. return new ZAiHandler(options)
  170. case "fireworks":
  171. return new FireworksHandler(options)
  172. case "io-intelligence":
  173. return new IOIntelligenceHandler(options)
  174. case "roo":
  175. // Never throw exceptions from provider constructors
  176. // The provider-proxy server will handle authentication and return appropriate error codes
  177. return new RooHandler(options)
  178. case "featherless":
  179. return new FeatherlessHandler(options)
  180. case "vercel-ai-gateway":
  181. return new VercelAiGatewayHandler(options)
  182. case "minimax":
  183. return new MiniMaxHandler(options)
  184. case "baseten":
  185. return new BasetenHandler(options)
  186. default:
  187. apiProvider satisfies "gemini-cli" | undefined
  188. return new AnthropicHandler(options)
  189. }
  190. }