diff --git a/providertests/openrouter_test.go b/providertests/openrouter_test.go index 77bccae84b3d0ea6ef3aa62438f782e0d42c754c..2456aafb7ac07973ca2f611cf971dc8de7fb4e2d 100644 --- a/providertests/openrouter_test.go +++ b/providertests/openrouter_test.go @@ -24,6 +24,7 @@ func TestOpenRouterCommon(t *testing.T) { claudeSonnet4(), grok4FastFree(), gemini25Flash(), + gemini20Flash(), } for _, model := range models { @@ -123,6 +124,23 @@ func gemini25Flash() openrouterModel { } } +func gemini20Flash() openrouterModel { + return openrouterModel{ + name: "gemini-2.0-flash", + builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) { + provider := openrouter.New( + openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")), + openrouter.WithHTTPClient(&http.Client{Transport: r}), + ) + return provider.LanguageModel("google/gemini-2.0-flash-001") + }, + providers: []string{ + "google-ai-studio", + "google-vertex", + }, + } +} + func claudeSonnet4() openrouterModel { return openrouterModel{ name: "claude-sonnet-4", diff --git a/providertests/testdata/TestOpenRouterCommon/multi_tool_gemini-2.0-flash_google-ai-studio.yaml b/providertests/testdata/TestOpenRouterCommon/multi_tool_gemini-2.0-flash_google-ai-studio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1a356df89cb74268d32f2fe8ff8bd73f264de0ab --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/multi_tool_gemini-2.0-flash_google-ai-studio.yaml @@ -0,0 +1,63 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 881 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n{\"id\":\"gen-1758703932-ESZQxMiMAimhFoBOekmM\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703932,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"tool_0_add_5VvKfmbHYCUCv59xdW4C\",\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}},{\"index\":1,\"id\":\"tool_1_multiply_y0o5frupUfLUmo8tP0ao\",\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}}]}}],\"usage\":{\"prompt_tokens\":57,\"completion_tokens\":10,\"total_tokens\":67,\"cost\":0.0000097,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000057,\"upstream_inference_completions_cost\":0.000004},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 889.012458ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 1324 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_0_add_5VvKfmbHYCUCv59xdW4C","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"tool_1_multiply_y0o5frupUfLUmo8tP0ao","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"tool_0_add_5VvKfmbHYCUCv59xdW4C","role":"tool"},{"content":"6","tool_call_id":"tool_1_multiply_y0o5frupUfLUmo8tP0ao","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n{\"id\":\"gen-1758703933-o9AfTE1ljG5FO9Py339H\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703933,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.\\n\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":111,\"completion_tokens\":26,\"total_tokens\":137,\"cost\":0.0000215,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000111,\"upstream_inference_completions_cost\":0.0000104},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 581.596625ms diff --git a/providertests/testdata/TestOpenRouterCommon/multi_tool_gemini-2.0-flash_google-vertex.yaml b/providertests/testdata/TestOpenRouterCommon/multi_tool_gemini-2.0-flash_google-vertex.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94b4f91e4bc8b9d82883d0fb346284884ef9790a --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/multi_tool_gemini-2.0-flash_google-vertex.yaml @@ -0,0 +1,63 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 878 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-vertex"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n\n \n\n \n{\"id\":\"gen-1758703944-4yTVzEmbhHCDx3U1PJKt\",\"provider\":\"Google\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703944,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"tool_0_add_AsS4AGt4KpG6XYKLSr4M\",\"type\":\"function\",\"function\":{\"name\":\"add\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}},{\"index\":1,\"id\":\"tool_1_multiply_8WbNDznbYqrzIU1jmuVj\",\"type\":\"function\",\"function\":{\"name\":\"multiply\",\"arguments\":\"{\\\"a\\\":2,\\\"b\\\":3}\"}}]}}],\"usage\":{\"prompt_tokens\":57,\"completion_tokens\":10,\"total_tokens\":67,\"cost\":0.00001455,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00000855,\"upstream_inference_completions_cost\":0.000006},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 1.725530459s + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 1321 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_0_add_AsS4AGt4KpG6XYKLSr4M","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"tool_1_multiply_8WbNDznbYqrzIU1jmuVj","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"tool_0_add_AsS4AGt4KpG6XYKLSr4M","role":"tool"},{"content":"6","tool_call_id":"tool_1_multiply_8WbNDznbYqrzIU1jmuVj","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"usage":{"include":true},"provider":{"only":["google-vertex"]}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n\n \n\n \n{\"id\":\"gen-1758703945-pmPsolThmNVr8GrVxsbc\",\"provider\":\"Google\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703945,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.\\n\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":111,\"completion_tokens\":26,\"total_tokens\":137,\"cost\":0.00003225,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00001665,\"upstream_inference_completions_cost\":0.0000156},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 1.586302583s diff --git a/providertests/testdata/TestOpenRouterCommon/multi_tool_streaming_gemini-2.0-flash_google-ai-studio.yaml b/providertests/testdata/TestOpenRouterCommon/multi_tool_streaming_gemini-2.0-flash_google-ai-studio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..861bf1d9440211924157335a0bfc7d8db152aa83 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/multi_tool_streaming_gemini-2.0-flash_google-ai-studio.yaml @@ -0,0 +1,77 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 935 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703934-Rtb5kDReumqEhPdGCARc","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703934,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"tool_0_add_QUgtUEa5j5Sy0298PIiK","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"index":1,"id":"tool_1_multiply_qI2Q7dpLvKyYS8vuhjhe","type":"function","function":{"name":"multiply","arguments":"{\"a\":2,\"b\":3}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703934-Rtb5kDReumqEhPdGCARc","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703934,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":57,"completion_tokens":10,"total_tokens":67,"cost":0.0000097,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000057,"upstream_inference_completions_cost":0.000004},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 774.011208ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 1378 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_0_add_QUgtUEa5j5Sy0298PIiK","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"tool_1_multiply_qI2Q7dpLvKyYS8vuhjhe","function":{"arguments":"{\"a\":2,\"b\":3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"tool_0_add_QUgtUEa5j5Sy0298PIiK","role":"tool"},{"content":"6","tool_call_id":"tool_1_multiply_qI2Q7dpLvKyYS8vuhjhe","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703934-ood4uQFxP3G0U7aQ85Cb","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703934,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703934-ood4uQFxP3G0U7aQ85Cb","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703934,"choices":[{"index":0,"delta":{"role":"assistant","content":" sum of 2 and 3 is 5, and the product of "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703934-ood4uQFxP3G0U7aQ85Cb","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703934,"choices":[{"index":0,"delta":{"role":"assistant","content":"2 and 3 is 6.\n"},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703934-ood4uQFxP3G0U7aQ85Cb","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703934,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":111,"completion_tokens":26,"total_tokens":137,"cost":0.0000215,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000111,"upstream_inference_completions_cost":0.0000104},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 690.55875ms diff --git a/providertests/testdata/TestOpenRouterCommon/multi_tool_streaming_gemini-2.0-flash_google-vertex.yaml b/providertests/testdata/TestOpenRouterCommon/multi_tool_streaming_gemini-2.0-flash_google-vertex.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e6b10fdeac8d05a8bcc189813c7a7eb2fe175ab5 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/multi_tool_streaming_gemini-2.0-flash_google-vertex.yaml @@ -0,0 +1,77 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 932 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-vertex"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703947-wpyNk0Zt4KfcjxKpFNbh","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703947,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"tool_0_add_4ywtlwXZLBlEzNwsgl7X","type":"function","function":{"name":"add","arguments":"{\"a\":2,\"b\":3}"}},{"index":1,"id":"tool_1_multiply_IO1TeYk7qGsd8TUNbTMo","type":"function","function":{"name":"multiply","arguments":"{\"b\":3,\"a\":2}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703947-wpyNk0Zt4KfcjxKpFNbh","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703947,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":57,"completion_tokens":10,"total_tokens":67,"cost":0.00001455,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00000855,"upstream_inference_completions_cost":0.000006},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 1.76056725s + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 1375 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. Always use both add and multiply at the same time.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"tool_0_add_4ywtlwXZLBlEzNwsgl7X","function":{"arguments":"{\"a\":2,\"b\":3}","name":"add"},"type":"function"},{"id":"tool_1_multiply_IO1TeYk7qGsd8TUNbTMo","function":{"arguments":"{\"b\":3,\"a\":2}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"tool_0_add_4ywtlwXZLBlEzNwsgl7X","role":"tool"},{"content":"6","tool_call_id":"tool_1_multiply_IO1TeYk7qGsd8TUNbTMo","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"add","strict":false,"description":"Add two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"},{"function":{"name":"multiply","strict":false,"description":"Multiply two numbers","parameters":{"properties":{"a":{"description":"first number","type":"integer"},"b":{"description":"second number","type":"integer"}},"required":["a","b"],"type":"object"}},"type":"function"}],"provider":{"only":["google-vertex"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703949-vSEB1mgAvJLaK3sCOhpF","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703949,"choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703949-vSEB1mgAvJLaK3sCOhpF","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703949,"choices":[{"index":0,"delta":{"role":"assistant","content":" sum of 2 and 3 is 5, and the product of "},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703949-vSEB1mgAvJLaK3sCOhpF","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703949,"choices":[{"index":0,"delta":{"role":"assistant","content":"2 and 3 is 6.\n"},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703949-vSEB1mgAvJLaK3sCOhpF","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703949,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":110,"completion_tokens":26,"total_tokens":136,"cost":0.0000321,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000165,"upstream_inference_completions_cost":0.0000156},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 1.658690625s diff --git a/providertests/testdata/TestOpenRouterCommon/simple_gemini-2.0-flash_google-ai-studio.yaml b/providertests/testdata/TestOpenRouterCommon/simple_gemini-2.0-flash_google-ai-studio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..745113c29ab2a65e163d331781688a05f20b305b --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/simple_gemini-2.0-flash_google-ai-studio.yaml @@ -0,0 +1,33 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 243 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"provider":{"only":["google-ai-studio"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n{\"id\":\"gen-1758703927-oXMBmCZ6gCQRj6rj9n2n\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703927,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Olá!\\n\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":9,\"completion_tokens\":3,\"total_tokens\":12,\"cost\":0.0000021,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":9e-7,\"upstream_inference_completions_cost\":0.0000012},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 1.207296209s diff --git a/providertests/testdata/TestOpenRouterCommon/simple_gemini-2.0-flash_google-vertex.yaml b/providertests/testdata/TestOpenRouterCommon/simple_gemini-2.0-flash_google-vertex.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dc1c9a56deeec669a21b522f5566bf5caecf44a6 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/simple_gemini-2.0-flash_google-vertex.yaml @@ -0,0 +1,33 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 240 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"usage":{"include":true},"provider":{"only":["google-vertex"]}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n\n \n\n \n{\"id\":\"gen-1758703935-Q19sDnw0r2IUsDLwFgXP\",\"provider\":\"Google\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703935,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"Olá!\\n\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":9,\"completion_tokens\":3,\"total_tokens\":12,\"cost\":0.00000315,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.00000135,\"upstream_inference_completions_cost\":0.0000018},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 1.447432458s diff --git a/providertests/testdata/TestOpenRouterCommon/simple_streaming_gemini-2.0-flash_google-ai-studio.yaml b/providertests/testdata/TestOpenRouterCommon/simple_streaming_gemini-2.0-flash_google-ai-studio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d92b0f9ed8c425996b5df9ca9ced60909c8c1d97 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/simple_streaming_gemini-2.0-flash_google-ai-studio.yaml @@ -0,0 +1,40 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 297 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"provider":{"only":["google-ai-studio"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703928-EupDIa9KxpLlcvQZeCZt","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703928,"choices":[{"index":0,"delta":{"role":"assistant","content":"Olá"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703928-EupDIa9KxpLlcvQZeCZt","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703928,"choices":[{"index":0,"delta":{"role":"assistant","content":"!\n"},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703928-EupDIa9KxpLlcvQZeCZt","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703928,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":9,"completion_tokens":3,"total_tokens":12,"cost":0.0000021,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":9e-7,"upstream_inference_completions_cost":0.0000012},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 1.027754375s diff --git a/providertests/testdata/TestOpenRouterCommon/simple_streaming_gemini-2.0-flash_google-vertex.yaml b/providertests/testdata/TestOpenRouterCommon/simple_streaming_gemini-2.0-flash_google-vertex.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6c28354f22d8f0e2b6670ab743655d30421a886e --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/simple_streaming_gemini-2.0-flash_google-vertex.yaml @@ -0,0 +1,40 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 294 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"provider":{"only":["google-vertex"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703937-c3zARIw7rBbUWPdGUrr7","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703937,"choices":[{"index":0,"delta":{"role":"assistant","content":"Olá"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703937-c3zARIw7rBbUWPdGUrr7","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703937,"choices":[{"index":0,"delta":{"role":"assistant","content":"!\n"},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703937-c3zARIw7rBbUWPdGUrr7","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703937,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":9,"completion_tokens":3,"total_tokens":12,"cost":0.00000315,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00000135,"upstream_inference_completions_cost":0.0000018},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 1.292658542s diff --git a/providertests/testdata/TestOpenRouterCommon/tool_gemini-2.0-flash_google-ai-studio.yaml b/providertests/testdata/TestOpenRouterCommon/tool_gemini-2.0-flash_google-ai-studio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d6dec0093d60a871a0f619e8fe0f1751d11d9ee2 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/tool_gemini-2.0-flash_google-ai-studio.yaml @@ -0,0 +1,63 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 535 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n{\"id\":\"gen-1758703929-eTRziOOBgqacZppoqJWF\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703929,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"tool_0_weather_ybikNXXUG7fijRORpBnF\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":28,\"completion_tokens\":3,\"total_tokens\":31,\"cost\":0.000004,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000028,\"upstream_inference_completions_cost\":0.0000012},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 673.25875ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 792 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_0_weather_ybikNXXUG7fijRORpBnF","function":{"arguments":"{\"location\":\"Florence\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"tool_0_weather_ybikNXXUG7fijRORpBnF","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n{\"id\":\"gen-1758703930-c9DOyE8qRm9vet9KAJ8L\",\"provider\":\"Google AI Studio\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703930,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"It is 40 C in Florence.\\n\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":52,\"completion_tokens\":10,\"total_tokens\":62,\"cost\":0.0000092,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000052,\"upstream_inference_completions_cost\":0.000004},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 660.390958ms diff --git a/providertests/testdata/TestOpenRouterCommon/tool_gemini-2.0-flash_google-vertex.yaml b/providertests/testdata/TestOpenRouterCommon/tool_gemini-2.0-flash_google-vertex.yaml new file mode 100644 index 0000000000000000000000000000000000000000..97078db832da5839c4f74b84a2d8ff52f3a21f55 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/tool_gemini-2.0-flash_google-vertex.yaml @@ -0,0 +1,63 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 532 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-vertex"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n\n \n\n \n{\"id\":\"gen-1758703938-shnrHjNsW5ms8GbSxsNI\",\"provider\":\"Google\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703938,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null,\"reasoning\":null,\"tool_calls\":[{\"index\":0,\"id\":\"tool_0_weather_rt8zo8rCm5SqDRklpJa9\",\"type\":\"function\",\"function\":{\"name\":\"weather\",\"arguments\":\"{\\\"location\\\":\\\"Florence,Italy\\\"}\"}}]}}],\"usage\":{\"prompt_tokens\":28,\"completion_tokens\":5,\"total_tokens\":33,\"cost\":0.0000072,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000042,\"upstream_inference_completions_cost\":0.000003},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 1.584211583s + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 795 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_0_weather_rt8zo8rCm5SqDRklpJa9","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"tool_0_weather_rt8zo8rCm5SqDRklpJa9","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-vertex"]},"usage":{"include":true}}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + uncompressed: true + body: "\n \n{\"id\":\"gen-1758703940-IAESUZpd9prOKc5TxS7t\",\"provider\":\"Google\",\"model\":\"google/gemini-2.0-flash-001\",\"object\":\"chat.completion\",\"created\":1758703940,\"choices\":[{\"logprobs\":null,\"finish_reason\":\"stop\",\"native_finish_reason\":\"STOP\",\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"It's 40 C in Florence, Italy.\\n\",\"refusal\":null,\"reasoning\":null}}],\"usage\":{\"prompt_tokens\":56,\"completion_tokens\":13,\"total_tokens\":69,\"cost\":0.0000162,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":null,\"upstream_inference_prompt_cost\":0.0000084,\"upstream_inference_completions_cost\":0.0000078},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0}}}" + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 720.270583ms diff --git a/providertests/testdata/TestOpenRouterCommon/tool_streaming_gemini-2.0-flash_google-ai-studio.yaml b/providertests/testdata/TestOpenRouterCommon/tool_streaming_gemini-2.0-flash_google-ai-studio.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c7fbb05974bfa1decbe7b15918ad952b1144a10d --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/tool_streaming_gemini-2.0-flash_google-ai-studio.yaml @@ -0,0 +1,75 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 589 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703931-fLH0HcaxrY4SZ4NQ6tWw","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703931,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"tool_0_weather_LVdXlqzFjnkcE0NQt7y4","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence,Italy\"}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703931-fLH0HcaxrY4SZ4NQ6tWw","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703931,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":28,"completion_tokens":5,"total_tokens":33,"cost":0.0000048,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000028,"upstream_inference_completions_cost":0.000002},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 660.108041ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 852 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_0_weather_LVdXlqzFjnkcE0NQt7y4","function":{"arguments":"{\"location\":\"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"tool_0_weather_LVdXlqzFjnkcE0NQt7y4","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-ai-studio"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703931-bgiUu4SqXlRVJMRRTs9D","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703931,"choices":[{"index":0,"delta":{"role":"assistant","content":"It"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703931-bgiUu4SqXlRVJMRRTs9D","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703931,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s 40 C in Florence, Italy.\n"},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703931-bgiUu4SqXlRVJMRRTs9D","provider":"Google AI Studio","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703931,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":57,"completion_tokens":13,"total_tokens":70,"cost":0.0000109,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000057,"upstream_inference_completions_cost":0.0000052},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 532.710958ms diff --git a/providertests/testdata/TestOpenRouterCommon/tool_streaming_gemini-2.0-flash_google-vertex.yaml b/providertests/testdata/TestOpenRouterCommon/tool_streaming_gemini-2.0-flash_google-vertex.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4350c7f104fb24a6ae077a31f29333ad23891469 --- /dev/null +++ b/providertests/testdata/TestOpenRouterCommon/tool_streaming_gemini-2.0-flash_google-vertex.yaml @@ -0,0 +1,75 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 586 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"provider":{"only":["google-vertex"]},"usage":{"include":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703940-DXian3wpzFWByfegIT9z","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703940,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"tool_0_weather_n9f6uGvWGqhx8tjnmWp0","type":"function","function":{"name":"weather","arguments":"{\"location\":\"Florence\"}"}}]},"finish_reason":"tool_calls","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703940-DXian3wpzFWByfegIT9z","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703940,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":28,"completion_tokens":3,"total_tokens":31,"cost":0.000006,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.0000042,"upstream_inference_completions_cost":0.0000018},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 1.394811041s + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 843 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"tool_0_weather_n9f6uGvWGqhx8tjnmWp0","function":{"arguments":"{\"location\":\"Florence\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"tool_0_weather_n9f6uGvWGqhx8tjnmWp0","role":"tool"}],"model":"google/gemini-2.0-flash-001","max_tokens":4000,"stream_options":{"include_usage":true},"tool_choice":"auto","tools":[{"function":{"name":"weather","strict":false,"description":"Get weather information for a location","parameters":{"properties":{"location":{"description":"the city","type":"string"}},"required":["location"],"type":"object"}},"type":"function"}],"usage":{"include":true},"provider":{"only":["google-vertex"]},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.3.0 + url: https://openrouter.ai/api/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"gen-1758703942-YRiZ3CR5l6JctjRyrGlG","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703942,"choices":[{"index":0,"delta":{"role":"assistant","content":"It"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + + data: {"id":"gen-1758703942-YRiZ3CR5l6JctjRyrGlG","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703942,"choices":[{"index":0,"delta":{"role":"assistant","content":"'s 40 C in Florence.\n"},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]} + + data: {"id":"gen-1758703942-YRiZ3CR5l6JctjRyrGlG","provider":"Google","model":"google/gemini-2.0-flash-001","object":"chat.completion.chunk","created":1758703942,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":55,"completion_tokens":11,"total_tokens":66,"cost":0.00001485,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"cost_details":{"upstream_inference_cost":null,"upstream_inference_prompt_cost":0.00000825,"upstream_inference_completions_cost":0.0000066},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + + data: [DONE] + + headers: + Content-Type: + - text/event-stream + status: 200 OK + code: 200 + duration: 1.7370605s