Skip to content

Commit ece0250

Browse files
authored
fix: correct Ollama context metadata for GPT-5.5 and GPT-5.4 models (#420)
1 parent cca154b commit ece0250

2 files changed

Lines changed: 39 additions & 31 deletions

File tree

src/ollama/bridge.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ class OllamaBridgeError extends Error {
5353
}
5454

5555
const CONTEXT_WINDOW_OVERRIDES = new Map<string, number>([
56-
["gpt-5.4", 272000],
57-
["gpt-5.4-mini", 272000],
56+
["gpt-5.5", 400000],
57+
["gpt-5.4", 400000],
58+
["gpt-5.4-pro", 400000],
59+
["gpt-5.4-mini", 400000],
60+
["gpt-5.4-nano", 400000],
5861
["gpt-5.3-codex", 272000],
5962
["gpt-5.3-codex-spark", 272000],
6063
["gpt-5.2", 272000],
@@ -107,6 +110,7 @@ function responseHeaders(init: HeadersInit, request?: Request): Headers {
107110

108111
function inferFamily(modelId: string): string {
109112
const normalized = modelId.toLowerCase();
113+
if (normalized.startsWith("gpt-5.5")) return "gpt-5.5";
110114
if (normalized.startsWith("gpt-5.4")) return "gpt-5.4";
111115
if (normalized.startsWith("gpt-5.3")) return "gpt-5.3";
112116
if (normalized.startsWith("gpt-5.2")) return "gpt-5.2";

tests/unit/ollama/bridge.test.ts

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -105,36 +105,40 @@ describe("Ollama bridge routes", () => {
105105
expect(body.models[0].digest).toMatch(/^[a-f0-9]{64}$/);
106106
});
107107

108-
it("returns model show metadata and can suppress vision capability", async () => {
109-
fetchMock.mockResolvedValueOnce(json({
110-
id: "gpt-5.4-mini",
111-
displayName: "GPT 5.4 mini",
112-
inputModalities: ["text", "image"],
113-
supportedReasoningEfforts: [{ reasoningEffort: "medium" }],
114-
defaultReasoningEffort: "medium",
115-
}));
116-
const app = createApp(true);
117-
118-
const res = await app.request("/api/show", {
119-
method: "POST",
120-
headers: { "Content-Type": "application/json" },
121-
body: JSON.stringify({ model: "gpt-5.4-mini" }),
122-
});
123-
124-
expect(res.status).toBe(200);
125-
expect(fetchMock).toHaveBeenCalledWith(
126-
"http://upstream.test/v1/models/gpt-5.4-mini/info",
127-
expect.any(Object),
128-
);
129-
const body = await res.json() as Record<string, unknown>;
130-
expect(body.capabilities).toEqual(["completion", "tools", "thinking"]);
131-
expect(body.parameters).toBe("num_ctx 272000\nreasoning medium");
132-
expect(body.model_info).toMatchObject({
133-
"gpt-5.4.context_length": 272000,
134-
upstream_id: "gpt-5.4-mini",
135-
input_modalities: ["text", "image"],
108+
it.each(["gpt-5.5", "gpt-5.4-mini"])(
109+
"returns 400k context metadata for %s and can suppress vision capability",
110+
async (model) => {
111+
fetchMock.mockResolvedValueOnce(json({
112+
id: model,
113+
displayName: model,
114+
inputModalities: ["text", "image"],
115+
supportedReasoningEfforts: [{ reasoningEffort: "medium" }],
116+
defaultReasoningEffort: "medium",
117+
}));
118+
const app = createApp(true);
119+
120+
const res = await app.request("/api/show", {
121+
method: "POST",
122+
headers: { "Content-Type": "application/json" },
123+
body: JSON.stringify({ model }),
124+
});
125+
126+
expect(res.status).toBe(200);
127+
expect(fetchMock).toHaveBeenCalledWith(
128+
`http://upstream.test/v1/models/${model}/info`,
129+
expect.any(Object),
130+
);
131+
const body = await res.json() as Record<string, unknown>;
132+
expect(body.capabilities).toEqual(["completion", "tools", "thinking"]);
133+
expect(body.parameters).toBe("num_ctx 400000\nreasoning medium");
134+
const architecture = model.startsWith("gpt-5.4") ? "gpt-5.4" : model;
135+
expect(body.model_info).toMatchObject({
136+
[`${architecture}.context_length`]: 400000,
137+
context_length: 400000,
138+
upstream_id: model,
139+
input_modalities: ["text", "image"],
140+
});
136141
});
137-
});
138142

139143
it("converts non-streaming Ollama chat requests and responses", async () => {
140144
fetchMock.mockResolvedValueOnce(json({

0 commit comments

Comments
 (0)