Skip to content

feat(vantage): include organization metadata in FOCUS Tags export#28184

Open
milan-berri wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_vantage_focus_organization_tags
Open

feat(vantage): include organization metadata in FOCUS Tags export#28184
milan-berri wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_vantage_focus_organization_tags

Conversation

@milan-berri
Copy link
Copy Markdown
Collaborator

@milan-berri milan-berri commented May 18, 2026

Linear ticket

Resolves LIT-2895

Docs

Companion docs PR: BerriAI/litellm-docs#162

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Screenshots / Proof of Fix

Local verification against db_berriai after seeding org-linked team, key, and daily spend:

POST /vantage/dry-runusage_data includes organization fields:

{
  "api_key": "vantage_org_seed_api_key_hash_001",
  "organization_id": "840fa8b4-9ada-48b7-be52-6957dcce30a5",
  "organization_alias": "repro_org_1778259917",
  "team_id": "team_m2a_1777028518",
  "team_alias": "M2 A"
}

normalized_data Tags (FOCUS export payload):

{
  "team_id": "team_m2a_1777028518",
  "team_alias": "M2 A",
  "organization_id": "840fa8b4-9ada-48b7-be52-6957dcce30a5",
  "organization_alias": "repro_org_1778259917",
  "user_id": "default_user_id",
  "api_key_alias": "vantage-org-seed-key",
  "model": "gpt-4o",
  "model_group": "gpt-4o",
  "custom_llm_provider": "openai"
}

Unit tests:

poetry run pytest tests/test_litellm/integrations/focus/test_focus_database.py \
  tests/test_litellm/integrations/focus/test_transformer.py -v
# 7 passed

Type

🆕 New Feature

Changes

Problem

Vantage/FOCUS export reads from LiteLLM_DailyUserSpend and maps team → SubAccountId/SubAccountName, but organization is not included anywhere in the export. Customers using LiteLLM organizations cannot filter or allocate LLM spend by org in Vantage today.

Solution

Include organization metadata in the existing user-level export (non-breaking):

  1. FocusLiteLLMDatabase — JOIN LiteLLM_OrganizationTable via COALESCE(vt.organization_id, tt.organization_id) and select organization_id, organization_alias.
  2. FocusTransformer — Add those fields to _TAG_KEYS so they appear in FOCUS Tags JSON (Vantage-supported column for custom metadata).

Org resolution order: API key organization_id first, then team organization_id.

Files changed

File Change
litellm/integrations/focus/database.py Org table join + SELECT
litellm/integrations/focus/transformer.py organization_id, organization_alias in Tags
tests/test_litellm/integrations/focus/test_focus_database.py Assert org join in SQL
tests/test_litellm/integrations/focus/test_transformer.py Assert org in Tags JSON

Test plan

Join LiteLLM_OrganizationTable when building Vantage/FOCUS export rows so
organization_id and organization_alias appear in Tags for org-level filtering.

Co-authored-by: Cursor <cursoragent@cursor.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 18, 2026

Greptile Summary

This PR extends the Vantage/FOCUS export pipeline to include organization metadata (organization_id, organization_alias) alongside the existing team fields, enabling customers to filter and allocate LLM spend by organization in Vantage.

  • database.py: Adds a LEFT JOIN to LiteLLM_OrganizationTable using COALESCE(vt.organization_id, tt.organization_id) as the join key, with API-key-level org taking precedence over team-level org; existing rows without an org remain unaffected.
  • transformer.py: Adds organization_id and organization_alias to _TAG_KEYS; the existing if k in frame.columns guard means these fields are silently omitted from the Tags JSON when absent.
  • New mock-based tests cover both the SQL shape and the Tags serialization for the presence/absence cases.

Confidence Score: 5/5

Small, focused change confined to the FOCUS export pipeline; the LEFT JOIN is additive and cannot drop existing rows, and the transformer's column-presence guard prevents any breakage when the new fields are absent.

The SQL change is a straightforward additive LEFT JOIN — NULL-safe throughout the join chain — and the transformer correctly omits the new keys when they are not present in the frame. Tests are mock-based, cover both the happy path and the missing-column case, and make no real network calls. No existing tests were weakened or removed.

No files require special attention.

Important Files Changed

Filename Overview
litellm/integrations/focus/database.py Adds LEFT JOIN to LiteLLM_OrganizationTable via COALESCE(vt.organization_id, tt.organization_id) and selects organization_id/organization_alias; non-breaking, correct NULL handling through the LEFT JOIN chain.
litellm/integrations/focus/transformer.py Adds organization_id and organization_alias to _TAG_KEYS; the existing available_keys filter (if k in frame.columns) correctly handles rows where these columns are absent.
tests/test_litellm/integrations/focus/test_focus_database.py Adds mock-based test asserting the generated SQL contains the org JOIN and COALESCE select; no real network calls.
tests/test_litellm/integrations/focus/test_transformer.py New test file covering both presence and absence of org fields in Tags JSON output; no real network calls, covers the happy path and the null/missing column case.

Reviews (1): Last reviewed commit: "feat(vantage): include organization meta..." | Re-trigger Greptile

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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