Skip to content

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

Closed
devin-ai-integration[bot] wants to merge 4 commits into
litellm_internal_stagingfrom
litellm_cognition_provider
Closed

feat(cognition): add a distinct provider identity for Cognition#36239
devin-ai-integration[bot] wants to merge 4 commits into
litellm_internal_stagingfrom
litellm_cognition_provider

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • Cognition traffic ran as custom_llm_provider: openai
  • OpenAI discounts and provider reports swallowed its spend
  • No way to pick Cognition when adding a model

How it solves it:

  • Registers cognition in the JSON provider registry
  • Ships SWE cost map entries, so spend prices correctly
  • Adds Cognition to the Admin UI provider dropdown

User Flow

Before: an admin onboarding Cognition has to disguise it as OpenAI, and every report then reads Cognition spend as OpenAI spend.

  1. They open https://litellm-domain/ui/?page=llm-providers, click "Add Model", and find no Cognition option in the provider list, so they pick "OpenAI-Compatible Chat Completions"
  2. They fill in the Cognition base URL and key, and save a deployment whose provider is openai
  3. They send POST https://litellm-domain/v1/chat/completions with "model": "swe-1.7" and get a normal completion back
  4. They open https://litellm-domain/ui/?page=logs and the request shows up under provider openai, priced off whatever swe-1.7 resolves to on the OpenAI side, and any OpenAI-specific discount they configured applies to it
  5. Provider-level usage on https://litellm-domain/ui/?page=usage pools this spend into the OpenAI row, so there is no way to see Cognition spend on its own

After: Cognition is a first-class provider, so the same deployment reports and prices as Cognition.

  1. They open https://litellm-domain/ui/?page=llm-providers, click "Add Model", and pick "Cognition" from the provider list
  2. The model dropdown offers cognition/swe-1.5, cognition/swe-1.6 and cognition/swe-1.7; they pick one, paste the key, and save
  3. They send POST https://litellm-domain/v1/chat/completions with "model": "swe-1.7" and get the same completion back
  4. https://litellm-domain/ui/?page=logs now shows the request under provider cognition, priced from the Cognition rates ($2.50 / $12.50 per million tokens for swe-1.7), with no OpenAI discount applied
  5. https://litellm-domain/ui/?page=usage breaks Cognition out as its own provider row

Relevant issues

Docs live in a separate repo, so the provider page and the COGNITION_API_KEY / COGNITION_API_BASE reference rows are in BerriAI/litellm-docs#822. The documentation and code-quality checks here check out litellm-docs main and fail any env var read under litellm/ that is documented nowhere, so they stay red until that PR merges.

Linear ticket

Resolves LIT-5348

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

Proof captured against a live proxy is in the session thread, including the Admin UI add-model flow and a real (non-mocked, paid) chat completion routed through the new provider identity. Cognition itself does not publish a public inference API, so the live call used a Cognition deployment whose api_base points at a real OpenAI-compatible upstream, which is exactly how the customer's endpoint is wired.

Type

🆕 New Feature

Changes

litellm/llms/openai_like/providers.json gains

"cognition": {
  "base_url": "https://api.cognition.ai/v1",
  "api_key_env": "COGNITION_API_KEY",
  "api_base_env": "COGNITION_API_BASE"
}

and cognition is registered in LlmProviders plus openai_compatible_providers, so model: cognition/swe-1.7 resolves to provider cognition with the Cognition base URL and key.

api_base autodetection in get_llm_provider gets no Cognition specific branch. Instead the chain ends with a registry lookup, so any provider whose default endpoint is in providers.json resolves from there rather than from a hardcoded slug and key env repeated in the core util:

elif (json_provider := JSONProviderRegistry.get_by_base_url(endpoint)) is not None:
    custom_llm_provider = json_provider.slug
    dynamic_api_key = api_key if api_key is not None else get_secret_str(json_provider.api_key_env)

The env key is a fallback rather than an override, so an explicit per call key survives autodetection instead of being replaced by whatever the environment holds, which is what the hardcoded branches above do today.

It sits last, so every existing hardcoded branch still wins, and JSON providers that were listed as compatible endpoints without a branch (tensormesh and libertai among them) now resolve instead of falling through with no provider.

The Add Model dropdown reads /public/providers/fields, which just serves litellm/proxy/public_endpoints/provider_create_fields.json, so Cognition also gets an entry there (required api_key, optional api_base) alongside the Providers enum and provider_map additions; without it the provider is registered but unselectable in the UI.

Cost map (both the root map and the bundled backup) gets cognition/swe-1.5, cognition/swe-1.6 and cognition/swe-1.7, priced from Cognition's published per-token rates, so spend is computed from the Cognition entry instead of an OpenAI one. provider_endpoints_support.json (plus backup) and the README provider table list the new provider as chat completions and messages only, since Cognition documents no Responses API, and the Admin UI provider dropdown gets a Cognition option that maps to the cognition slug.

ui/litellm-dashboard/src/lib/http/schema.d.ts is regenerated in one commit: it had drifted on the base branch (a missing tier_turns field on an auto-router response model), and the sync check fails on any PR until someone regenerates it. Nothing in this PR touches that model.

Two notes for reviewers, both flagged on the ticket: the default base_url is Cognition's documented API host and can be overridden per deployment or with COGNITION_API_BASE, and the SWE entries carry no context-window numbers because Cognition has not published them.

Link to Devin session: https://app.devin.ai/sessions/c27f086d609843cdb6380708ecd31b2f
Requested by: @shivamrawat1

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>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR registers Cognition as a distinct OpenAI-compatible provider across provider resolution, pricing, endpoint metadata, and the Admin UI.

  • Adds Cognition provider identity, credentials, models, and pricing metadata.
  • Adds registry-based api_base autodetection while retaining explicit caller credentials.
  • Exposes Cognition in provider creation and dashboard mappings.

Confidence Score: 3/5

This PR is not safe to merge until Cognition requests can no longer inherit and disclose an unrelated OpenAI credential when Cognition credentials are absent.

The new autodetection path can return no Cognition key, after which the shared OpenAI-compatible dispatcher substitutes a globally configured OpenAI key and sends it to the Cognition endpoint.

Files Needing Attention: litellm/litellm_core_utils/get_llm_provider_logic.py and litellm/main.py

Security Review

Cognition autodetection can forward a globally configured OpenAI credential to Cognition when no Cognition credential is available. How this was verified: The changed resolver returns no key in that state, and the reached OpenAI-compatible dispatch explicitly substitutes the global OpenAI credential chain.

Important Files Changed

Filename Overview
litellm/litellm_core_utils/get_llm_provider_logic.py Adds registry-based provider autodetection and explicit-key precedence, but missing Cognition credentials can still fall through to an unrelated OpenAI key.
litellm/llms/openai_like/json_loader.py Adds an exact default-base-URL registry lookup used by provider autodetection.
litellm/llms/openai_like/providers.json Registers Cognition's default endpoint and credential environment variables.
litellm/constants.py Registers Cognition as OpenAI-compatible and adds its endpoint to the autodetection gate.
model_prices_and_context_window.json Adds Cognition SWE model pricing and capability metadata.
litellm/proxy/public_endpoints/provider_create_fields.json Exposes Cognition's credential and endpoint fields to provider-creation clients.
ui/litellm-dashboard/src/components/provider_info_helpers.tsx Adds Cognition to the Admin UI provider mapping.
tests/test_litellm/llms/openai_like/test_cognition_provider.py Covers provider identity, default autodetection, explicit endpoint and key precedence, pricing, and routing.

Reviews (3): Last reviewed commit: "fix(cognition): keep the caller api key ..." | Re-trigger Greptile

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread litellm/litellm_core_utils/get_llm_provider_logic.py Outdated
@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

The dropdown is driven by /public/providers/fields, so the provider needed an entry in provider_create_fields.json. Also document COGNITION_API_KEY/COGNITION_API_BASE (docs repo PR) and regenerate the dashboard API types, which had drifted on the base branch.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@codspeed-hq

codspeed-hq Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_cognition_provider (702120b) with litellm_internal_staging (b0fd3e1)1

Open in CodSpeed

Footnotes

  1. No successful run was found on litellm_internal_staging (8b16ee1) during the generation of this report, so 4c1fb9b was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@shivamrawat1

Copy link
Copy Markdown
Contributor

@greptile review again

Comment thread litellm/litellm_core_utils/get_llm_provider_logic.py Outdated
…vider

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@shivamrawat1

Copy link
Copy Markdown
Contributor

@greptile review again

dynamic_api_key = get_secret_str("META_API_KEY")
elif (json_provider := JSONProviderRegistry.get_by_base_url(endpoint)) is not None:
custom_llm_provider = json_provider.slug
dynamic_api_key = api_key if api_key is not None else get_secret_str(json_provider.api_key_env)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security OpenAI credential leaks to Cognition

If Cognition is autodetected while neither an explicit api_key nor COGNITION_API_KEY is configured, this returns no key and the shared OpenAI-compatible dispatch substitutes litellm.api_key, litellm.openai_key, or OPENAI_API_KEY, sending an unrelated credential to Cognition and failing authentication.

How this was verified: The changed resolver returns None in this state, and the reached dispatch explicitly falls back through the global OpenAI credential chain.

Knowledge Base Used: LLM Provider Adapters

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That OpenAI key fallback in main.py:6163 predates this PR and hits every provider here (mistral, meta) with an unset env var, so fixing it belongs in its own change, not this one

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point. Looking at the existing branches in the same block, they all do the same thing — dynamic_api_key = get_secret_str("SOME_API_KEY") without preserving an explicit api_key. The new JSON registry branch is actually strictly better than the precedent: it checks api_key if api_key is not None else get_secret_str(...), so it preserves an explicitly-passed key rather than overwriting it. The downstream OpenAI credential fallback when dynamic_api_key is None is pre-existing behavior shared across all providers here (mistral, meta, perplexity, etc.), not something this PR introduces or worsens. The concern doesn't apply to this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant