From df4288ec508597c15ad0524d370abf1ea50e29a2 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Wed, 22 Oct 2025 10:03:28 -0300 Subject: [PATCH] test: add integration tests for hugging face (via openai-compat) (#33) --- providertests/.env.sample | 1 + providertests/openaicompat_test.go | 10 ++ .../huggingface-qwen3-coder/multi_tool.yaml | 61 +++++++++ .../multi_tool_streaming.yaml | 123 ++++++++++++++++++ .../huggingface-qwen3-coder/simple.yaml | 32 +++++ .../simple_streaming.yaml | 42 ++++++ .../huggingface-qwen3-coder/tool.yaml | 61 +++++++++ .../tool_streaming.yaml | 99 ++++++++++++++ 8 files changed, 429 insertions(+) create mode 100644 providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml create mode 100644 providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml create mode 100644 providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml create mode 100644 providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml create mode 100644 providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml create mode 100644 providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml diff --git a/providertests/.env.sample b/providertests/.env.sample index 9666bdbb267111f3c4d893b08b79df01c324a301..af90c7f05041b38a373f3139c3ea75a6b16dec30 100644 --- a/providertests/.env.sample +++ b/providertests/.env.sample @@ -4,6 +4,7 @@ FANTASY_AZURE_BASE_URL= FANTASY_BEDROCK_API_KEY= FANTASY_GEMINI_API_KEY= FANTASY_GROQ_API_KEY= +FANTASY_HUGGINGFACE_API_KEY= FANTASY_OPENAI_API_KEY= FANTASY_OPENROUTER_API_KEY= FANTASY_VERTEX_LOCATION=us-east5 diff --git a/providertests/openaicompat_test.go b/providertests/openaicompat_test.go index fa93041d95e63c7511895d3f731664d05aba9b86..6d6a70d3025cba48b31c913c807f45fe7874bcd6 100644 --- a/providertests/openaicompat_test.go +++ b/providertests/openaicompat_test.go @@ -18,6 +18,7 @@ func TestOpenAICompatibleCommon(t *testing.T) { {"xai-grok-code-fast", builderXAIGrokCodeFast, nil}, {"groq-kimi-k2", builderGroq, nil}, {"zai-glm-4.5", builderZAIGLM45, nil}, + {"huggingface-qwen3-coder", builderHuggingFace, nil}, }) } @@ -91,3 +92,12 @@ func builderGroq(r *recorder.Recorder) (fantasy.LanguageModel, error) { ) return provider.LanguageModel("moonshotai/kimi-k2-instruct-0905") } + +func builderHuggingFace(r *recorder.Recorder) (fantasy.LanguageModel, error) { + provider := openaicompat.New( + openaicompat.WithBaseURL("https://router.huggingface.co/v1"), + openaicompat.WithAPIKey(os.Getenv("FANTASY_HUGGINGFACE_API_KEY")), + openaicompat.WithHTTPClient(&http.Client{Transport: r}), + ) + return provider.LanguageModel("Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras") +} diff --git a/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d9af928327d31926e254f754a87a4091829c6ea3 --- /dev/null +++ b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool.yaml @@ -0,0 +1,61 @@ +--- +version: 2 +interactions: +- id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 849 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: '{"id":"chatcmpl-7903d21a-4ce4-4c3c-80b0-26c4486da856","choices":[{"finish_reason":"tool_calls","index":0,"message":{"tool_calls":[{"id":"636c4f780","type":"function","function":{"name":"add","arguments":"{\"a\": 2, \"b\": 3}"}},{"id":"0e7c8838b","type":"function","function":{"name":"multiply","arguments":"{\"a\": 2, \"b\": 3}"}}],"role":"assistant"}}],"created":1761070222,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion","usage":{"prompt_tokens":412,"completion_tokens":59,"total_tokens":471,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.000492824,"prompt_time":0.003602156,"completion_time":0.029433121,"total_time":0.03494548797607422,"created":1761070222.626673}}' + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 417.164875ms +- id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 1200 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant. CRITICAL: Always use both add and multiply at the same time ALWAYS.","role":"system"},{"content":"Add and multiply the number 2 and 3","role":"user"},{"tool_calls":[{"id":"636c4f780","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"0e7c8838b","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"636c4f780","role":"tool"},{"content":"6","tool_call_id":"0e7c8838b","role":"tool"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: '{"id":"chatcmpl-11d40720-9356-401e-840c-354c845cc02e","choices":[{"finish_reason":"stop","index":0,"message":{"content":"The sum of 2 and 3 is 5, and the product of 2 and 3 is 6.","role":"assistant"}}],"created":1761070220,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion","usage":{"prompt_tokens":492,"completion_tokens":26,"total_tokens":518,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.00014209,"prompt_time":0.005866093,"completion_time":0.009498776,"total_time":0.016791582107543945,"created":1761070220.5671532}}' + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 439.567542ms diff --git a/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b737c0e2b32579d7b072ac9da6273da9c8c61e84 --- /dev/null +++ b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/multi_tool_streaming.yaml @@ -0,0 +1,123 @@ +--- +version: 2 +interactions: +- id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 886 + 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":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}],"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"chatcmpl-fbef6a2f-2f11-4004-aa3d-797c76e902e4","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-fbef6a2f-2f11-4004-aa3d-797c76e902e4","choices":[{"delta":{"tool_calls":[{"function":{"name":"add","arguments":"{\"a\": 2, \"b\": 3}"},"type":"function","id":"49253c956","index":0},{"function":{"name":"multiply","arguments":"{\"a\": 2, \"b\": 3}"},"type":"function","id":"6a614264b","index":1}]},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-fbef6a2f-2f11-4004-aa3d-797c76e902e4","choices":[{"delta":{},"finish_reason":"tool_calls","index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk","usage":{"prompt_tokens":408,"completion_tokens":59,"total_tokens":467,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.000118501,"prompt_time":0.003364192,"completion_time":0.031095836,"total_time":0.036528825759887695,"created":1761070223.457216}} + + headers: + Content-Type: + - text/event-stream; charset=utf-8 + status: 200 OK + code: 200 + duration: 324.113458ms +- id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 1237 + 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":"49253c956","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"add"},"type":"function"},{"id":"6a614264b","function":{"arguments":"{\"a\": 2, \"b\": 3}","name":"multiply"},"type":"function"}],"role":"assistant"},{"content":"5","tool_call_id":"49253c956","role":"tool"},{"content":"6","tool_call_id":"6a614264b","role":"tool"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}],"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"The"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" sum"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" of"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" "},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"2"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" and"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" "},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"3"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" is"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" "},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"5"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":","},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" and"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" the"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" product"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" of"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" "},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"2"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" and"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" "},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"3"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" is"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":" "},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"6"},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{"content":"."},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{},"index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-c10d1909-8b70-432c-8db0-5469e1d510bb","choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1761070223,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk","usage":{"prompt_tokens":488,"completion_tokens":26,"total_tokens":514,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.001117439,"prompt_time":0.006053757,"completion_time":0.009437543,"total_time":0.018548250198364258,"created":1761070223.8780432}} + + headers: + Content-Type: + - text/event-stream; charset=utf-8 + status: 200 OK + code: 200 + duration: 379.856833ms diff --git a/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c48d56d8f932d0d1137d9e1d5088f1ed1a5da433 --- /dev/null +++ b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple.yaml @@ -0,0 +1,32 @@ +--- +version: 2 +interactions: +- id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 194 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","max_tokens":4000}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: '{"id":"chatcmpl-9896e784-1a94-43f8-b06e-e673f36b4d66","choices":[{"finish_reason":"stop","index":0,"message":{"content":"Olá!","role":"assistant"}}],"created":1761070217,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion","usage":{"prompt_tokens":22,"completion_tokens":4,"total_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.000123411,"prompt_time":0.002289408,"completion_time":0.00336861,"total_time":0.0072479248046875,"created":1761070217.7655818}}' + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 663.689958ms diff --git a/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2a4b8b27e93194931f5095f08f7eeda26ec6d53c --- /dev/null +++ b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/simple_streaming.yaml @@ -0,0 +1,42 @@ +--- +version: 2 +interactions: +- id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 248 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"Say hi in Portuguese","role":"user"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","max_tokens":4000,"stream_options":{"include_usage":true},"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"chatcmpl-6ee1d665-644a-4dda-81c6-7f6590a4fc84","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1761070218,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-6ee1d665-644a-4dda-81c6-7f6590a4fc84","choices":[{"delta":{"content":"Oi"},"index":0}],"created":1761070218,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-6ee1d665-644a-4dda-81c6-7f6590a4fc84","choices":[{"delta":{"content":"!"},"index":0}],"created":1761070218,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-6ee1d665-644a-4dda-81c6-7f6590a4fc84","choices":[{"delta":{},"index":0}],"created":1761070218,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-6ee1d665-644a-4dda-81c6-7f6590a4fc84","choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1761070218,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk","usage":{"prompt_tokens":22,"completion_tokens":3,"total_tokens":25,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.0001041,"prompt_time":0.002245652,"completion_time":0.003623067,"total_time":0.008143901824951172,"created":1761070218.1551065}} + + headers: + Content-Type: + - text/event-stream; charset=utf-8 + status: 200 OK + code: 200 + duration: 371.201333ms diff --git a/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b6bf31daba7e9fa1af8dd6c53cc5d1ec72a82053 --- /dev/null +++ b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool.yaml @@ -0,0 +1,61 @@ +--- +version: 2 +interactions: +- id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 486 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: '{"id":"chatcmpl-fb490edc-2dc0-436e-83cb-ee109fd3e387","choices":[{"finish_reason":"tool_calls","index":0,"message":{"tool_calls":[{"id":"a937be9d7","type":"function","function":{"name":"weather","arguments":"{\"location\": \"Florence,Italy\"}"}}],"role":"assistant"}}],"created":1761070221,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion","usage":{"prompt_tokens":277,"completion_tokens":25,"total_tokens":302,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.000135531,"prompt_time":0.009486813,"completion_time":0.016420409,"total_time":0.027780532836914062,"created":1761070221.021929}}' + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 401.073917ms +- id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 698 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"a937be9d7","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"a937be9d7","role":"tool"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: '{"id":"chatcmpl-e3575be7-5855-4bfb-b911-1e1c7cd30faf","choices":[{"finish_reason":"stop","index":0,"message":{"content":"The current weather in Florence, Italy is 40°C.","role":"assistant"}}],"created":1761070221,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion","usage":{"prompt_tokens":319,"completion_tokens":14,"total_tokens":333,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.000320512,"prompt_time":0.01004831,"completion_time":0.008558245,"total_time":0.02015233039855957,"created":1761070221.4201767}}' + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 382.941875ms diff --git a/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml new file mode 100644 index 0000000000000000000000000000000000000000..88e177dc1badbd564dd7374e4b77a67913139cf9 --- /dev/null +++ b/providertests/testdata/TestOpenAICompatibleCommon/huggingface-qwen3-coder/tool_streaming.yaml @@ -0,0 +1,99 @@ +--- +version: 2 +interactions: +- id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 540 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}],"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"chatcmpl-1ca2f710-7a38-402a-a08b-af2ffa91d70a","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1761070221,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-1ca2f710-7a38-402a-a08b-af2ffa91d70a","choices":[{"delta":{"tool_calls":[{"function":{"name":"weather","arguments":"{\"location\": \"Florence,Italy\"}"},"type":"function","id":"0da2f2748","index":0}]},"index":0}],"created":1761070221,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-1ca2f710-7a38-402a-a08b-af2ffa91d70a","choices":[{"delta":{},"finish_reason":"tool_calls","index":0}],"created":1761070221,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk","usage":{"prompt_tokens":277,"completion_tokens":25,"total_tokens":302,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.000467134,"prompt_time":0.008837703,"completion_time":0.016987548,"total_time":0.02814340591430664,"created":1761070221.7568507}} + + headers: + Content-Type: + - text/event-stream; charset=utf-8 + status: 200 OK + code: 200 + duration: 429.335958ms +- id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 752 + host: "" + body: '{"messages":[{"content":"You are a helpful assistant","role":"system"},{"content":"What''s the weather in Florence,Italy?","role":"user"},{"tool_calls":[{"id":"0da2f2748","function":{"arguments":"{\"location\": \"Florence,Italy\"}","name":"weather"},"type":"function"}],"role":"assistant"},{"content":"40 C","tool_call_id":"0da2f2748","role":"tool"}],"model":"Qwen/Qwen3-Coder-480B-A35B-Instruct:cerebras","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"}],"stream":true}' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAI/Go 2.7.1 + url: https://router.huggingface.co/v1/chat/completions + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + content_length: -1 + body: |+ + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"role":"assistant"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":"The"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" current"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" weather"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" in"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" Florence"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":","},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" Italy"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" is"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":" "},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":"4"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":"0"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":"°C"},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{"content":"."},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{},"index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk"} + + data: {"id":"chatcmpl-ae6007c3-7cc3-4add-ab2f-f177d907838c","choices":[{"delta":{},"finish_reason":"stop","index":0}],"created":1761070219,"model":"qwen-3-coder-480b","system_fingerprint":"fp_386b539e7b02ce3613b7","object":"chat.completion.chunk","usage":{"prompt_tokens":319,"completion_tokens":14,"total_tokens":333,"prompt_tokens_details":{"cached_tokens":0}},"time_info":{"queue_time":0.00013387,"prompt_time":0.010714015,"completion_time":0.009309609,"total_time":0.02214217185974121,"created":1761070219.7154236}} + + headers: + Content-Type: + - text/event-stream; charset=utf-8 + status: 200 OK + code: 200 + duration: 337.890125ms