|
|
@@ -248,4 +248,203 @@ describe("getLiteLLMModels", () => {
|
|
|
|
|
|
expect(result).toEqual({})
|
|
|
})
|
|
|
+
|
|
|
+ it("uses fallback computer use detection when supports_computer_use is not available", async () => {
|
|
|
+ const mockResponse = {
|
|
|
+ data: {
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ model_name: "claude-3-5-sonnet-latest",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 4096,
|
|
|
+ max_input_tokens: 200000,
|
|
|
+ supports_vision: true,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ // Note: no supports_computer_use field
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "anthropic/claude-3-5-sonnet-latest", // This should match the fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ model_name: "gpt-4-turbo",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 8192,
|
|
|
+ max_input_tokens: 128000,
|
|
|
+ supports_vision: false,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ // Note: no supports_computer_use field
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "openai/gpt-4-turbo", // This should NOT match the fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ mockedAxios.get.mockResolvedValue(mockResponse)
|
|
|
+
|
|
|
+ const result = await getLiteLLMModels("test-api-key", "http://localhost:4000")
|
|
|
+
|
|
|
+ expect(result["claude-3-5-sonnet-latest"]).toEqual({
|
|
|
+ maxTokens: 4096,
|
|
|
+ contextWindow: 200000,
|
|
|
+ supportsImages: true,
|
|
|
+ supportsComputerUse: true, // Should be true due to fallback
|
|
|
+ supportsPromptCache: false,
|
|
|
+ inputPrice: undefined,
|
|
|
+ outputPrice: undefined,
|
|
|
+ description: "claude-3-5-sonnet-latest via LiteLLM proxy",
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(result["gpt-4-turbo"]).toEqual({
|
|
|
+ maxTokens: 8192,
|
|
|
+ contextWindow: 128000,
|
|
|
+ supportsImages: false,
|
|
|
+ supportsComputerUse: false, // Should be false as it's not in fallback list
|
|
|
+ supportsPromptCache: false,
|
|
|
+ inputPrice: undefined,
|
|
|
+ outputPrice: undefined,
|
|
|
+ description: "gpt-4-turbo via LiteLLM proxy",
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it("prioritizes explicit supports_computer_use over fallback detection", async () => {
|
|
|
+ const mockResponse = {
|
|
|
+ data: {
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ model_name: "claude-3-5-sonnet-latest",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 4096,
|
|
|
+ max_input_tokens: 200000,
|
|
|
+ supports_vision: true,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ supports_computer_use: false, // Explicitly set to false
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "anthropic/claude-3-5-sonnet-latest", // This matches fallback list but should be ignored
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ model_name: "custom-model",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 8192,
|
|
|
+ max_input_tokens: 128000,
|
|
|
+ supports_vision: false,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ supports_computer_use: true, // Explicitly set to true
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "custom/custom-model", // This would NOT match fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ model_name: "another-custom-model",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 8192,
|
|
|
+ max_input_tokens: 128000,
|
|
|
+ supports_vision: false,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ supports_computer_use: false, // Explicitly set to false
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "custom/another-custom-model", // This would NOT match fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ mockedAxios.get.mockResolvedValue(mockResponse)
|
|
|
+
|
|
|
+ const result = await getLiteLLMModels("test-api-key", "http://localhost:4000")
|
|
|
+
|
|
|
+ expect(result["claude-3-5-sonnet-latest"]).toEqual({
|
|
|
+ maxTokens: 4096,
|
|
|
+ contextWindow: 200000,
|
|
|
+ supportsImages: true,
|
|
|
+ supportsComputerUse: false, // False because explicitly set to false (fallback ignored)
|
|
|
+ supportsPromptCache: false,
|
|
|
+ inputPrice: undefined,
|
|
|
+ outputPrice: undefined,
|
|
|
+ description: "claude-3-5-sonnet-latest via LiteLLM proxy",
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(result["custom-model"]).toEqual({
|
|
|
+ maxTokens: 8192,
|
|
|
+ contextWindow: 128000,
|
|
|
+ supportsImages: false,
|
|
|
+ supportsComputerUse: true, // True because explicitly set to true
|
|
|
+ supportsPromptCache: false,
|
|
|
+ inputPrice: undefined,
|
|
|
+ outputPrice: undefined,
|
|
|
+ description: "custom-model via LiteLLM proxy",
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(result["another-custom-model"]).toEqual({
|
|
|
+ maxTokens: 8192,
|
|
|
+ contextWindow: 128000,
|
|
|
+ supportsImages: false,
|
|
|
+ supportsComputerUse: false, // False because explicitly set to false
|
|
|
+ supportsPromptCache: false,
|
|
|
+ inputPrice: undefined,
|
|
|
+ outputPrice: undefined,
|
|
|
+ description: "another-custom-model via LiteLLM proxy",
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ it("handles fallback detection with various model name formats", async () => {
|
|
|
+ const mockResponse = {
|
|
|
+ data: {
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ model_name: "vertex-claude",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 4096,
|
|
|
+ max_input_tokens: 200000,
|
|
|
+ supports_vision: true,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "vertex_ai/claude-3-5-sonnet", // Should match fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ model_name: "openrouter-claude",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 4096,
|
|
|
+ max_input_tokens: 200000,
|
|
|
+ supports_vision: true,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "openrouter/anthropic/claude-3.5-sonnet", // Should match fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ model_name: "bedrock-claude",
|
|
|
+ model_info: {
|
|
|
+ max_tokens: 4096,
|
|
|
+ max_input_tokens: 200000,
|
|
|
+ supports_vision: true,
|
|
|
+ supports_prompt_caching: false,
|
|
|
+ },
|
|
|
+ litellm_params: {
|
|
|
+ model: "anthropic.claude-3-5-sonnet-20241022-v2:0", // Should match fallback list
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ mockedAxios.get.mockResolvedValue(mockResponse)
|
|
|
+
|
|
|
+ const result = await getLiteLLMModels("test-api-key", "http://localhost:4000")
|
|
|
+
|
|
|
+ expect(result["vertex-claude"].supportsComputerUse).toBe(true)
|
|
|
+ expect(result["openrouter-claude"].supportsComputerUse).toBe(true)
|
|
|
+ expect(result["bedrock-claude"].supportsComputerUse).toBe(true)
|
|
|
+ })
|
|
|
})
|