mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-29 01:42:19 +00:00
feat(providers): add Standard Compute chat completions
This commit is contained in:
parent
c52b53706e
commit
9e46e25825
2 changed files with 165 additions and 0 deletions
|
|
@ -200,5 +200,12 @@
|
|||
"temperature_max": 1.99
|
||||
},
|
||||
"supported_endpoints": ["/v1/chat/completions"]
|
||||
},
|
||||
"standardcompute": {
|
||||
"base_url": "https://api.stdcmpt.com/v1",
|
||||
"api_key_env": "STANDARDCOMPUTE_API_KEY",
|
||||
"param_mappings": {
|
||||
"max_completion_tokens": "max_tokens"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
import json
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
|
||||
import litellm
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def httpx_transport(monkeypatch):
|
||||
monkeypatch.setenv("DISABLE_AIOHTTP_TRANSPORT", "True")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_standardcompute_completion_preserves_tools_and_maps_token_limit():
|
||||
tools = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "read_file",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {"path": {"type": "string"}},
|
||||
"required": ["path"],
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
response = {
|
||||
"id": "chatcmpl-test",
|
||||
"object": "chat.completion",
|
||||
"created": 1,
|
||||
"model": "standardcompute",
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"finish_reason": "tool_calls",
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call-read",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "read_file",
|
||||
"arguments": '{"path":"README.md"}',
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
with respx.mock as transport:
|
||||
request = transport.post("https://api.stdcmpt.com/v1/chat/completions").mock(
|
||||
return_value=httpx.Response(200, json=response)
|
||||
)
|
||||
result = await litellm.acompletion(
|
||||
model="standardcompute/standardcompute",
|
||||
api_key="test-key",
|
||||
messages=[{"role": "user", "content": "Read README.md"}],
|
||||
tools=tools,
|
||||
max_completion_tokens=64,
|
||||
)
|
||||
sent = json.loads(request.calls.last.request.content)
|
||||
assert sent["model"] == "standardcompute"
|
||||
assert sent["tools"] == tools
|
||||
assert sent["max_tokens"] == 64
|
||||
assert "max_completion_tokens" not in sent
|
||||
assert request.calls.last.request.headers["authorization"] == "Bearer test-key"
|
||||
assert result.choices[0].message.tool_calls[0].function.name == "read_file"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_standardcompute_environment_key_and_api_base_override(monkeypatch):
|
||||
monkeypatch.setenv("STANDARDCOMPUTE_API_KEY", "environment-test-key")
|
||||
response = {
|
||||
"id": "chatcmpl-test",
|
||||
"object": "chat.completion",
|
||||
"created": 1,
|
||||
"model": "standardcompute",
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"finish_reason": "stop",
|
||||
"message": {"role": "assistant", "content": "Connected"},
|
||||
}
|
||||
],
|
||||
}
|
||||
with respx.mock as transport:
|
||||
request = transport.post("https://example.test/v1/chat/completions").mock(
|
||||
return_value=httpx.Response(200, json=response)
|
||||
)
|
||||
result = await litellm.acompletion(
|
||||
model="standardcompute/standardcompute",
|
||||
api_base="https://example.test/v1",
|
||||
messages=[{"role": "user", "content": "Connection check"}],
|
||||
)
|
||||
assert (
|
||||
request.calls.last.request.headers["authorization"]
|
||||
== "Bearer environment-test-key"
|
||||
)
|
||||
assert result.choices[0].message.content == "Connected"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_standardcompute_stream_consumes_chat_completion_events():
|
||||
chunks = [
|
||||
{
|
||||
"id": "chatcmpl-test",
|
||||
"object": "chat.completion.chunk",
|
||||
"created": 1,
|
||||
"model": "standardcompute",
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"delta": {"role": "assistant", "content": "Connected"},
|
||||
"finish_reason": None,
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "chatcmpl-test",
|
||||
"object": "chat.completion.chunk",
|
||||
"created": 1,
|
||||
"model": "standardcompute",
|
||||
"choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}],
|
||||
},
|
||||
]
|
||||
events = (
|
||||
"".join("data: " + json.dumps(chunk) + "\n\n" for chunk in chunks)
|
||||
+ "data: [DONE]\n\n"
|
||||
)
|
||||
with respx.mock as transport:
|
||||
request = transport.post("https://api.stdcmpt.com/v1/chat/completions").mock(
|
||||
return_value=httpx.Response(
|
||||
200, text=events, headers={"content-type": "text/event-stream"}
|
||||
)
|
||||
)
|
||||
stream = await litellm.acompletion(
|
||||
model="standardcompute/standardcompute",
|
||||
api_key="test-key",
|
||||
messages=[{"role": "user", "content": "Connection check"}],
|
||||
stream=True,
|
||||
)
|
||||
received = [chunk async for chunk in stream]
|
||||
assert json.loads(request.calls.last.request.content)["stream"] is True
|
||||
assert (
|
||||
"".join(
|
||||
chunk.choices[0].delta.content or "" for chunk in received if chunk.choices
|
||||
)
|
||||
== "Connected"
|
||||
)
|
||||
assert any(
|
||||
chunk.choices and chunk.choices[0].finish_reason == "stop" for chunk in received
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue