feat(cognition): add a distinct provider identity for Cognition

Register cognition as a JSON-configured OpenAI-compatible provider so its traffic no longer rides on custom_llm_provider=openai, keeping OpenAI cost discounts and provider-level reporting out of it. Adds the SWE cost map entries, the supported-endpoints matrix row, and the Admin UI provider option.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
shivam 2026-08-08 01:47:25 +00:00
parent 1bafdb3c93
commit bcb9d16eaa
11 changed files with 271 additions and 0 deletions

View file

@ -292,6 +292,7 @@ curl -X POST 'http://0.0.0.0:4000/v1/chat/completions' \
| [Clarifai (`clarifai`)](https://docs.litellm.ai/docs/providers/clarifai) | ✅ | ✅ | ✅ | | | | | | | |
| [Cloudflare AI Workers (`cloudflare`)](https://docs.litellm.ai/docs/providers/cloudflare_workers) | ✅ | ✅ | ✅ | | | | | | | |
| [Codestral (`codestral`)](https://docs.litellm.ai/docs/providers/codestral) | ✅ | ✅ | ✅ | | | | | | | |
| [Cognition (`cognition`)](https://docs.litellm.ai/docs/providers/cognition) | ✅ | ✅ | ✅ | | | | | | | |
| [Cohere (`cohere`)](https://docs.litellm.ai/docs/providers/cohere) | ✅ | ✅ | ✅ | ✅ | | | | | | ✅ |
| [Cohere Chat (`cohere_chat`)](https://docs.litellm.ai/docs/providers/cohere) | ✅ | ✅ | ✅ | | | | | | | |
| [CometAPI (`cometapi`)](https://docs.litellm.ai/docs/providers/cometapi) | ✅ | ✅ | ✅ | ✅ | | | | | | |

View file

@ -751,6 +751,7 @@ openai_compatible_endpoints: Final[list] = [
"https://api.libertai.io/v1",
"https://pinstripes.io/v1",
"https://api.meta.ai/v1",
"https://api.cognition.ai/v1",
]
@ -818,6 +819,7 @@ openai_compatible_providers: Final[list] = [
"pinstripes", # Pinstripes - JSON-configured provider
"darkbloom",
"meta", # Meta Model API (Muse Spark) - JSON-configured provider
"cognition", # Cognition - JSON-configured provider
]
openai_text_completion_compatible_providers: Final[list] = [ # providers that support `/v1/completions`
"together_ai",

View file

@ -349,6 +349,9 @@ def get_llm_provider(
elif endpoint == "https://api.meta.ai/v1":
custom_llm_provider = "meta"
dynamic_api_key = get_secret_str("META_API_KEY")
elif endpoint == "https://api.cognition.ai/v1":
custom_llm_provider = "cognition"
dynamic_api_key = get_secret_str("COGNITION_API_KEY")
if api_base is not None and not isinstance(api_base, str):
raise Exception(f"api base needs to be a string. api_base={api_base}")

View file

@ -175,6 +175,11 @@
"base_class": "openai_gpt",
"supported_endpoints": ["/v1/chat/completions", "/v1/responses", "/v1/messages"]
},
"cognition": {
"base_url": "https://api.cognition.ai/v1",
"api_key_env": "COGNITION_API_KEY",
"api_base_env": "COGNITION_API_BASE"
},
"pinstripes": {
"base_url": "https://pinstripes.io/v1",
"api_key_env": "PINSTRIPES_API_KEY",

View file

@ -46247,6 +46247,37 @@
"supports_reasoning": true,
"supports_vision": false
},
"cognition/swe-1.5": {
"input_cost_per_token": 3e-07,
"output_cost_per_token": 1.5e-06,
"cache_creation_input_token_cost": 3.75e-07,
"cache_read_input_token_cost": 3e-08,
"litellm_provider": "cognition",
"mode": "chat",
"supports_function_calling": true,
"supports_prompt_caching": true,
"source": "https://docs.devin.ai/windsurf/plugins/cascade/models"
},
"cognition/swe-1.6": {
"input_cost_per_token": 3e-07,
"output_cost_per_token": 1.5e-06,
"cache_read_input_token_cost": 3e-08,
"litellm_provider": "cognition",
"mode": "chat",
"supports_function_calling": true,
"supports_prompt_caching": true,
"source": "https://docs.devin.ai/windsurf/plugins/cascade/models"
},
"cognition/swe-1.7": {
"input_cost_per_token": 2.5e-06,
"output_cost_per_token": 1.25e-05,
"cache_read_input_token_cost": 1e-06,
"litellm_provider": "cognition",
"mode": "chat",
"supports_function_calling": true,
"supports_prompt_caching": true,
"source": "https://docs.devin.ai/windsurf/plugins/cascade/models"
},
"pinstripes/ps/glm-4.5-air": {
"max_tokens": 128000,
"max_input_tokens": 128000,

View file

@ -528,6 +528,23 @@
"interactions": true
}
},
"cognition": {
"display_name": "Cognition (`cognition`)",
"url": "https://docs.litellm.ai/docs/providers/cognition",
"endpoints": {
"chat_completions": true,
"messages": true,
"responses": false,
"embeddings": false,
"image_generations": false,
"audio_transcriptions": false,
"audio_speech": false,
"moderations": false,
"batches": false,
"rerank": false,
"a2a": false
}
},
"cohere": {
"display_name": "Cohere (`cohere`)",
"url": "https://docs.litellm.ai/docs/providers/cohere",

View file

@ -3695,6 +3695,7 @@ class LlmProviders(str, Enum):
TENSORMESH = "tensormesh"
LIBERTAI = "libertai"
PINSTRIPES = "pinstripes"
COGNITION = "cognition"
DARKBLOOM = "darkbloom"
META = "meta"
LITELLM_AGENT = "litellm_agent"

View file

@ -46335,6 +46335,37 @@
"supports_reasoning": true,
"supports_vision": false
},
"cognition/swe-1.5": {
"input_cost_per_token": 3e-07,
"output_cost_per_token": 1.5e-06,
"cache_creation_input_token_cost": 3.75e-07,
"cache_read_input_token_cost": 3e-08,
"litellm_provider": "cognition",
"mode": "chat",
"supports_function_calling": true,
"supports_prompt_caching": true,
"source": "https://docs.devin.ai/windsurf/plugins/cascade/models"
},
"cognition/swe-1.6": {
"input_cost_per_token": 3e-07,
"output_cost_per_token": 1.5e-06,
"cache_read_input_token_cost": 3e-08,
"litellm_provider": "cognition",
"mode": "chat",
"supports_function_calling": true,
"supports_prompt_caching": true,
"source": "https://docs.devin.ai/windsurf/plugins/cascade/models"
},
"cognition/swe-1.7": {
"input_cost_per_token": 2.5e-06,
"output_cost_per_token": 1.25e-05,
"cache_read_input_token_cost": 1e-06,
"litellm_provider": "cognition",
"mode": "chat",
"supports_function_calling": true,
"supports_prompt_caching": true,
"source": "https://docs.devin.ai/windsurf/plugins/cascade/models"
},
"pinstripes/ps/glm-4.5-air": {
"max_tokens": 128000,
"max_input_tokens": 128000,

View file

@ -563,6 +563,23 @@
"interactions": true
}
},
"cognition": {
"display_name": "Cognition (`cognition`)",
"url": "https://docs.litellm.ai/docs/providers/cognition",
"endpoints": {
"chat_completions": true,
"messages": true,
"responses": false,
"embeddings": false,
"image_generations": false,
"audio_transcriptions": false,
"audio_speech": false,
"moderations": false,
"batches": false,
"rerank": false,
"a2a": false
}
},
"cohere": {
"display_name": "Cohere (`cohere`)",
"url": "https://docs.litellm.ai/docs/providers/cohere",

View file

@ -0,0 +1,159 @@
"""
Tests for the Cognition provider identity.
Cognition serves an OpenAI-compatible /v1/chat/completions surface, but it must resolve to its
own `cognition` provider so OpenAI-specific pricing and provider-level reporting never apply to
its traffic.
"""
import json
from pathlib import Path
import pytest
import litellm
class TestCognitionProviderIdentity:
def test_cognition_is_a_registered_provider(self):
from litellm import LlmProviders
assert LlmProviders.COGNITION.value == "cognition"
assert "cognition" in litellm.provider_list
def test_cognition_json_config(self):
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
cognition = JSONProviderRegistry.get("cognition")
assert cognition is not None
assert cognition.base_url == "https://api.cognition.ai/v1"
assert cognition.api_key_env == "COGNITION_API_KEY"
assert cognition.api_base_env == "COGNITION_API_BASE"
def test_cognition_in_openai_compatible_providers(self):
from litellm.constants import openai_compatible_providers
assert "cognition" in openai_compatible_providers
def test_prefixed_model_resolves_to_cognition_not_openai(self):
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
model, provider, _, api_base = get_llm_provider(
model="cognition/swe-1.7",
custom_llm_provider=None,
api_base=None,
api_key=None,
)
assert model == "swe-1.7"
assert provider == "cognition"
assert api_base == "https://api.cognition.ai/v1"
def test_explicit_api_base_and_key_win(self):
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
_, provider, api_key, api_base = get_llm_provider(
model="cognition/swe-1.7",
custom_llm_provider=None,
api_base="https://cognition.internal.example/v1",
api_key="sk-test",
)
assert provider == "cognition"
assert api_base == "https://cognition.internal.example/v1"
assert api_key == "sk-test"
def test_api_base_autodetects_cognition(self, monkeypatch: pytest.MonkeyPatch):
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
monkeypatch.setenv("COGNITION_API_KEY", "sk-cognition-env")
_, provider, api_key, api_base = get_llm_provider(
model="swe-1.7",
custom_llm_provider=None,
api_base="https://api.cognition.ai/v1",
api_key=None,
)
assert provider == "cognition"
assert api_base == "https://api.cognition.ai/v1"
assert api_key == "sk-cognition-env"
def test_env_api_key_is_read_from_cognition_variable(self, monkeypatch: pytest.MonkeyPatch):
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
monkeypatch.setenv("COGNITION_API_KEY", "sk-cognition-env")
provider = JSONProviderRegistry.get("cognition")
assert provider is not None
api_base, api_key = create_config_class(provider)()._get_openai_compatible_provider_info(None, None)
assert api_base == "https://api.cognition.ai/v1"
assert api_key == "sk-cognition-env"
class TestCognitionCostTracking:
@pytest.mark.parametrize(
"model, input_cost, output_cost",
[
("cognition/swe-1.5", 3e-07, 1.5e-06),
("cognition/swe-1.6", 3e-07, 1.5e-06),
("cognition/swe-1.7", 2.5e-06, 1.25e-05),
],
)
def test_cost_map_entries(self, model: str, input_cost: float, output_cost: float):
info = litellm.get_model_info(model=model)
assert info["litellm_provider"] == "cognition"
assert info["mode"] == "chat"
assert info["input_cost_per_token"] == input_cost
assert info["output_cost_per_token"] == output_cost
def test_cost_differs_from_openai_pricing(self):
"""A cognition-prefixed model must never be priced off an OpenAI cost entry."""
from litellm.cost_calculator import cost_per_token
prompt_cost, completion_cost = cost_per_token(
model="cognition/swe-1.7",
prompt_tokens=1_000_000,
completion_tokens=1_000_000,
custom_llm_provider="cognition",
)
assert prompt_cost == pytest.approx(2.5)
assert completion_cost == pytest.approx(12.5)
def test_supported_endpoints_matrix(self):
matrix = json.loads((Path(litellm.__file__).parent / "provider_endpoints_support_backup.json").read_text())
endpoints = matrix["providers"]["cognition"]["endpoints"]
assert endpoints["chat_completions"] is True
assert endpoints["embeddings"] is False
class TestCognitionRouting:
@pytest.mark.asyncio
async def test_router_spend_is_attributed_to_cognition_pricing(self):
"""Routed traffic is costed off the cognition entry, not an OpenAI one."""
from litellm import Router
router = Router(
model_list=[
{
"model_name": "swe",
"litellm_params": {"model": "cognition/swe-1.7", "api_key": "sk-test"},
}
]
)
response = await router.acompletion(
model="swe",
messages=[{"role": "user", "content": "hi"}],
mock_response="hello from swe",
)
usage = response.usage
expected = usage.prompt_tokens * 2.5e-06 + usage.completion_tokens * 1.25e-05
assert response._hidden_params["response_cost"] == pytest.approx(expected)

View file

@ -85,6 +85,7 @@ export enum Providers {
CLARIFAI = "Clarifai",
CLOUDFLARE = "Cloudflare",
CODESTRAL = "Codestral",
Cognition = "Cognition",
Cohere = "Cohere",
COHERE_CHAT = "Cohere Chat",
COMETAPI = "Cometapi",
@ -193,6 +194,7 @@ export const provider_map: Record<string, string> = {
CLARIFAI: "clarifai",
CLOUDFLARE: "cloudflare",
CODESTRAL: "codestral",
Cognition: "cognition",
Cohere: "cohere",
COHERE_CHAT: "cohere_chat",
COMETAPI: "cometapi",
@ -439,6 +441,8 @@ export const getPlaceholder = (selectedProvider: string): string => {
return "cursor/claude-4-sonnet";
} else if (selectedProvider === Providers.ZAI) {
return "zai/glm-4.5";
} else if (selectedProvider === Providers.Cognition) {
return "cognition/swe-1.7";
} else {
return "gpt-3.5-turbo";
}