Skip to content

fix(openai): match longest model prefix for context window size#6603

Open
Kropiunig wants to merge 1 commit into
crewAIInc:mainfrom
Kropiunig:fix/openai-context-window-longest-prefix
Open

fix(openai): match longest model prefix for context window size#6603
Kropiunig wants to merge 1 commit into
crewAIInc:mainfrom
Kropiunig:fix/openai-context-window-longest-prefix

Conversation

@Kropiunig

Copy link
Copy Markdown

Summary

OpenAICompletion.get_context_window_size() iterates the model-prefix table in insertion order and returns on the first startswith match:

context_windows = {
    "gpt-4": 8192,
    "gpt-4o": 128000,
    "gpt-4o-mini": 200000,
    "gpt-4-turbo": 128000,
    "gpt-4.1": 1047576,
    ...
}
for model_prefix, size in context_windows.items():
    if self.model.startswith(model_prefix):
        return int(size * CONTEXT_WINDOW_USAGE_RATIO)

Because "gpt-4" comes first and "gpt-4o".startswith("gpt-4") is True, every gpt-4* model collapses to gpt-4's 8192-token window before its own, more-specific entry is ever reached. The more specific keys (gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-4.1, ...) are effectively dead code.

This hits the default model gpt-4o (model: str = "gpt-4o"), so out of the box get_context_window_size() returns int(8192 * 0.85) = 6963 instead of int(128000 * 0.85) = 108800 — making summarization/truncation far too aggressive and causing spurious context-window-exceeded handling.

model before after
gpt-4 6963 6963
gpt-4o 6963 108800
gpt-4o-mini 6963 170000
gpt-4-turbo 6963 108800
gpt-4.1 6963 890439

Fix

Sort the prefixes by length (longest first) before matching, so the most specific prefix wins. This mirrors AzureCompletion.get_context_window_size(), which already does exactly this:

for model_prefix, size in sorted(
    context_windows.items(), key=lambda x: len(x[0]), reverse=True
):

Test

Adds test_openai_context_window_uses_longest_prefix_match, asserting gpt-4o -> 128k and gpt-4o-mini -> 200k windows while gpt-4 stays at 8k. It fails on main (6963 == 108800 AssertionError) and passes with this change. Existing behavior for models without a shorter conflicting prefix (e.g. o3-mini -> 200k) is unchanged.

OpenAICompletion.get_context_window_size iterated the prefix table in
insertion order and returned on the first match. Because "gpt-4" precedes
the more specific "gpt-4o", "gpt-4o-mini", "gpt-4-turbo" and "gpt-4.1"
entries, every "gpt-4*" model (including the default "gpt-4o") resolved to
gpt-4's 8192-token window instead of its own, making context management far
too aggressive.

Sort the prefixes by length (longest first) before matching, mirroring the
AzureCompletion provider which already does this. Add a regression test
covering gpt-4, gpt-4o and gpt-4o-mini.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 315f0edd-6524-4e11-b2aa-468f1d9c6c88

📥 Commits

Reviewing files that changed from the base of the PR and between 4c7e483 and f32b5fa.

📒 Files selected for processing (2)
  • lib/crewai/src/crewai/llms/providers/openai/completion.py
  • lib/crewai/tests/llms/openai/test_openai.py

📝 Walkthrough

Walkthrough

OpenAI context-window lookup now prioritizes the longest matching model prefix. A regression test covers gpt-4, gpt-4o, and gpt-4o-mini resolution and expected context-window sizes.

Changes

OpenAI context window matching

Layer / File(s) Summary
Longest-prefix matching and regression coverage
lib/crewai/src/crewai/llms/providers/openai/completion.py, lib/crewai/tests/llms/openai/test_openai.py
get_context_window_size() checks longer prefixes first, while regression tests verify correct sizing for overlapping OpenAI model prefixes.

Suggested reviewers: vinibrsl

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: using the longest matching OpenAI model prefix for context window sizing.
Description check ✅ Passed The description is directly related to the change and accurately explains the bug, fix, and regression test.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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