Skip to main content

OpenAI shuts down gpt-4o and gpt-4.1 on 71 days left Sources

Your code didn’t change. The API did.

Arbor finds the Python calls to OpenAI, Anthropic and Google models that have a shutdown date, and says what has to change in each.

npx @anandb71/arbor-cli@3.1.1 retirements .

Runs locally: no code leaves this machine, and Arbor sends no telemetry. Free and open source; npx downloads the CLI from npm and its binary from Arbor's GitHub releases. Or add the GitHub Action, or request a readiness review.

Pick a date to see what Arbor prints for app/chat.py, a small example we wrote with five model calls.

Arbor's clock, CI=1 arbor retirements . --today 2026-10-23

Now ·

Failing (exit 1): 2 calls use a model that is already retired.

1 call uses a model Anthropic shut down on 28 Oct 2025
  app/chat.py:24  claude-3-5-sonnet-20241022 (line 25) → claude-sonnet-5-5

The call starts on line 24; its model is on line 25.

1 call uses a model OpenAI shuts down today (23 Oct 2026)
  app/chat.py:10  o4-mini (line 11) → gpt-5.6-terra

The call starts on line 10; its model is on line 11.

1 call uses a model Anthropic shuts down today (30 Nov 2026)
  app/chat.py:14  claude-sonnet-4-5-20250929 (line 15) → claude-sonnet-5-5

The call starts on line 14; its model is on line 15.

1 call uses a model OpenAI shuts down today (14 Jan 2027)
  app/chat.py:19  gpt-4o (line 20) → gpt-6-luna

The call starts on line 19; its model is on line 20.

app/chat.py · 31 lines
  1. import os

  2. from anthropic import Anthropic
  3. from openai import OpenAI

  4. gpt = OpenAI()
  5. claude = Anthropic()

  6. def draft(msgs):
  7. return gpt.chat.completions.create(
  8. model="o4-mini", messages=msgs)

  9. def review(msgs):
  10. return claude.messages.create(
  11. model="claude-sonnet-4-5-20250929",
  12. max_tokens=1024, messages=msgs)

  13. def answer(msgs):
  14. return gpt.chat.completions.create(
  15. model="gpt-4o", messages=msgs,
  16. max_tokens=300, temperature=0.2)

  17. def legacy(msgs):
  18. return claude.messages.create(
  19. model="claude-3-5-sonnet-20241022",
  20. max_tokens=512, messages=msgs)

  21. def route(msgs):
  22. return gpt.chat.completions.create(
  23. model=os.environ["CHAT_MODEL"],
  24. messages=msgs)
Full output from Arbor 3.1.1 (44 lines)

Claude Sonnet 3.5 shut down on . One call fails.

Anthropic gave 76 days' notice; its page says “Requests to retired models fail.”

o4-mini shut down on 23 Oct. Two calls have failed since.

OpenAI gave 184 days' notice for o4-mini, along with gpt-4, o1 and other older models.

Claude Sonnet 4.5 shuts down. Three calls fail.

Anthropic gave 61 days' notice; its policy promises at least 60.

gpt-4o shuts down. All four calls with a known model fail.

OpenAI gave 92 days' notice.

Struck: past its shutdown date on the date shown. Outlined: has a shutdown date, not yet reached. Dashed: Arbor can't read the model, so it doesn't guess, and the call isn't counted as failing.

Marks as of .

What Arbor prints for app/chat.py on four dates

Claude Sonnet 3.5 shut down on . One call fails.

Anthropic gave 76 days' notice; its page says “Requests to retired models fail.” The call on line 25 asks for claude-3-5-sonnet-20241022. Three more calls have dates: o4-mini, claude-sonnet-4-5 and gpt-4o. The check already exits 1.

CI=1 arbor retirements . --today 2026-10-20

Model retirements in . (1 Python file checked)

1 call uses a model Anthropic shut down on 28 Oct 2025
  app/chat.py:24  claude-3-5-sonnet-20241022 (line 25) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
35 lines not shownSummary: 4 calls in 1 file use retired or retiring models: 1 already retired, 3 retiring (next: 23 Oct 2026, 3 days).
1 line not shownFailing (exit 1): 1 call uses a model that is already retired.
1 line not shown
Full output from Arbor 3.1.1 (44 lines)

(not verified) marks an effect that no provider page states and no real API call has confirmed.

Model retirements in . (1 Python file checked)

1 call uses a model Anthropic shut down on 28 Oct 2025
  app/chat.py:24  claude-3-5-sonnet-20241022 (line 25) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shuts down on 23 Oct 2026 (3 days)
  app/chat.py:10  o4-mini (line 11) → gpt-5.6-terra
  note: gpt-5.6-terra has real-time safeguards that can refuse or pause some cyber and biology output.

1 call uses a model Anthropic shuts down on 30 Nov 2026 (41 days)
  app/chat.py:14  claude-sonnet-4-5-20250929 (line 15) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shuts down on 14 Jan 2027 (86 days)
  app/chat.py:19  gpt-4o (line 20) → gpt-6-luna
                  also change: max_tokens → max_completion_tokens
                  decide: keep reasoning off (add reasoning_effort="none"; keep temperature) or let the model reason (remove temperature)
  decide once for this repo (Arbor does not choose): gpt-6-luna runs at medium reasoning effort by default, so it can reason; the model it replaces answered without a reasoning step.
    keep reasoning off: Closest to the old non-reasoning model: the call keeps answering without a reasoning step. (not verified)
                        Sampling stays as the code sets it and there is no reasoning step: closest to the old model.
    let the model reason: The model can reason (default effort medium). When it does, the call is slower, reasoning tokens are billed as output tokens, max_completion_tokens also has to cover them, and answers may change. How much it reasons on real prompts is not measured yet.
                          The model can reason (default effort medium) and samples on its own: slower and costlier when it reasons, and output style and determinism change.
  note: If gpt-6-luna reasons, max_completion_tokens also bounds its reasoning tokens, so a small limit can be used up before any visible text.
  note: gpt-4o is an alias: OpenAI's deprecations page gives it no shutdown date (its 14 Jan 2027 rows name only dated snapshots), but OpenAI's API reference lists it as deprecated with shutdown date 14 Jan 2027, and its models API gave that date on 18 Oct 2026.
  note: OpenAI describes gpt-6-luna as its "most efficient model for focused, high-volume tasks", so answer quality may change compared with the model it replaces.

Not checked: 1 call takes the model from somewhere Arbor cannot read (an environment variable, a function argument, another module); arbor usages lists it.
Summary: 4 calls in 1 file use retired or retiring models: 1 already retired, 3 retiring (next: 23 Oct 2026, 3 days).
1 can move to the listed replacement with the changes shown; 3 can move once this repo makes the choice shown under decide.
Failing (exit 1): 1 call uses a model that is already retired.
Retirement data from the providers' deprecation pages: OpenAI, Anthropic, Google and Google Cloud as of 28 Oct 2026. Days are counted in UTC. Python and direct SDK calls only for now. Runs locally: no code leaves this machine.

exit 11 failing

o4-mini shut down on 23 Oct. Two calls have failed since.

OpenAI gave 184 days' notice for o4-mini, along with gpt-4, o1 and other older models. From this date, the call on line 11 fails.

CI=1 arbor retirements . --today 2026-10-23

Model retirements in . (1 Python file checked)
11 lines not shown1 call uses a model OpenAI shuts down today (23 Oct 2026)
  app/chat.py:10  o4-mini (line 11) → gpt-5.6-terra
26 lines not shownSummary: 4 calls in 1 file use retired or retiring models: 2 already retired, 2 retiring (next: 30 Nov 2026, 38 days).
1 line not shownFailing (exit 1): 2 calls use a model that is already retired.
1 line not shown
Full output from Arbor 3.1.1 (44 lines)

(not verified) marks an effect that no provider page states and no real API call has confirmed.

Model retirements in . (1 Python file checked)

1 call uses a model Anthropic shut down on 28 Oct 2025
  app/chat.py:24  claude-3-5-sonnet-20241022 (line 25) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shuts down today (23 Oct 2026)
  app/chat.py:10  o4-mini (line 11) → gpt-5.6-terra
  note: gpt-5.6-terra has real-time safeguards that can refuse or pause some cyber and biology output.

1 call uses a model Anthropic shuts down on 30 Nov 2026 (38 days)
  app/chat.py:14  claude-sonnet-4-5-20250929 (line 15) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shuts down on 14 Jan 2027 (83 days)
  app/chat.py:19  gpt-4o (line 20) → gpt-6-luna
                  also change: max_tokens → max_completion_tokens
                  decide: keep reasoning off (add reasoning_effort="none"; keep temperature) or let the model reason (remove temperature)
  decide once for this repo (Arbor does not choose): gpt-6-luna runs at medium reasoning effort by default, so it can reason; the model it replaces answered without a reasoning step.
    keep reasoning off: Closest to the old non-reasoning model: the call keeps answering without a reasoning step. (not verified)
                        Sampling stays as the code sets it and there is no reasoning step: closest to the old model.
    let the model reason: The model can reason (default effort medium). When it does, the call is slower, reasoning tokens are billed as output tokens, max_completion_tokens also has to cover them, and answers may change. How much it reasons on real prompts is not measured yet.
                          The model can reason (default effort medium) and samples on its own: slower and costlier when it reasons, and output style and determinism change.
  note: If gpt-6-luna reasons, max_completion_tokens also bounds its reasoning tokens, so a small limit can be used up before any visible text.
  note: gpt-4o is an alias: OpenAI's deprecations page gives it no shutdown date (its 14 Jan 2027 rows name only dated snapshots), but OpenAI's API reference lists it as deprecated with shutdown date 14 Jan 2027, and its models API gave that date on 18 Oct 2026.
  note: OpenAI describes gpt-6-luna as its "most efficient model for focused, high-volume tasks", so answer quality may change compared with the model it replaces.

Not checked: 1 call takes the model from somewhere Arbor cannot read (an environment variable, a function argument, another module); arbor usages lists it.
Summary: 4 calls in 1 file use retired or retiring models: 2 already retired, 2 retiring (next: 30 Nov 2026, 38 days).
1 can move to the listed replacement with the changes shown; 3 can move once this repo makes the choice shown under decide.
Failing (exit 1): 2 calls use a model that is already retired.
Retirement data from the providers' deprecation pages: OpenAI, Anthropic, Google and Google Cloud as of 28 Oct 2026. Days are counted in UTC. Python and direct SDK calls only for now. Runs locally: no code leaves this machine.

exit 12 failing

Claude Sonnet 4.5 shuts down. Three calls fail.

Anthropic gave 61 days' notice; its policy promises at least 60. From this date, the call on line 15 fails.

For line 15, Arbor also prints:

let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.

CI=1 arbor retirements . --today 2026-11-30

Model retirements in . (1 Python file checked)
15 lines not shown1 call uses a model Anthropic shuts down today (30 Nov 2026)
  app/chat.py:14  claude-sonnet-4-5-20250929 (line 15) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
21 lines not shownSummary: 4 calls in 1 file use retired or retiring models: 3 already retired, 1 retiring (next: 14 Jan 2027, 45 days).
1 line not shownFailing (exit 1): 3 calls use a model that is already retired.
1 line not shown
Full output from Arbor 3.1.1 (44 lines)

(not verified) marks an effect that no provider page states and no real API call has confirmed.

Model retirements in . (1 Python file checked)

1 call uses a model Anthropic shut down on 28 Oct 2025
  app/chat.py:24  claude-3-5-sonnet-20241022 (line 25) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shut down on 23 Oct 2026
  app/chat.py:10  o4-mini (line 11) → gpt-5.6-terra
  note: gpt-5.6-terra has real-time safeguards that can refuse or pause some cyber and biology output.

1 call uses a model Anthropic shuts down today (30 Nov 2026)
  app/chat.py:14  claude-sonnet-4-5-20250929 (line 15) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shuts down on 14 Jan 2027 (45 days)
  app/chat.py:19  gpt-4o (line 20) → gpt-6-luna
                  also change: max_tokens → max_completion_tokens
                  decide: keep reasoning off (add reasoning_effort="none"; keep temperature) or let the model reason (remove temperature)
  decide once for this repo (Arbor does not choose): gpt-6-luna runs at medium reasoning effort by default, so it can reason; the model it replaces answered without a reasoning step.
    keep reasoning off: Closest to the old non-reasoning model: the call keeps answering without a reasoning step. (not verified)
                        Sampling stays as the code sets it and there is no reasoning step: closest to the old model.
    let the model reason: The model can reason (default effort medium). When it does, the call is slower, reasoning tokens are billed as output tokens, max_completion_tokens also has to cover them, and answers may change. How much it reasons on real prompts is not measured yet.
                          The model can reason (default effort medium) and samples on its own: slower and costlier when it reasons, and output style and determinism change.
  note: If gpt-6-luna reasons, max_completion_tokens also bounds its reasoning tokens, so a small limit can be used up before any visible text.
  note: gpt-4o is an alias: OpenAI's deprecations page gives it no shutdown date (its 14 Jan 2027 rows name only dated snapshots), but OpenAI's API reference lists it as deprecated with shutdown date 14 Jan 2027, and its models API gave that date on 18 Oct 2026.
  note: OpenAI describes gpt-6-luna as its "most efficient model for focused, high-volume tasks", so answer quality may change compared with the model it replaces.

Not checked: 1 call takes the model from somewhere Arbor cannot read (an environment variable, a function argument, another module); arbor usages lists it.
Summary: 4 calls in 1 file use retired or retiring models: 3 already retired, 1 retiring (next: 14 Jan 2027, 45 days).
1 can move to the listed replacement with the changes shown; 3 can move once this repo makes the choice shown under decide.
Failing (exit 1): 3 calls use a model that is already retired.
Retirement data from the providers' deprecation pages: OpenAI, Anthropic, Google and Google Cloud as of 28 Oct 2026. Days are counted in UTC. Python and direct SDK calls only for now. Runs locally: no code leaves this machine.

exit 13 failing

gpt-4o shuts down. All four calls with a known model fail.

OpenAI gave 92 days' notice. Its deprecations page lists gpt-4o's dated snapshots for that day, and its models API gives gpt-4o the same date (checked ).

CI=1 arbor retirements . --today 2027-01-14

Model retirements in . (1 Python file checked)
25 lines not shown1 call uses a model OpenAI shuts down today (14 Jan 2027)
  app/chat.py:19  gpt-4o (line 20) → gpt-6-luna
                  also change: max_tokens → max_completion_tokens
                  decide: keep reasoning off (add reasoning_effort="none"; keep temperature) or let the model reason (remove temperature)
10 lines not shownSummary: 4 calls in 1 file use retired or retiring models: 4 already retired.
1 line not shownFailing (exit 1): 4 calls use a model that is already retired.
1 line not shown
Full output from Arbor 3.1.1 (44 lines)

(not verified) marks an effect that no provider page states and no real API call has confirmed.

Model retirements in . (1 Python file checked)

1 call uses a model Anthropic shut down on 28 Oct 2025
  app/chat.py:24  claude-3-5-sonnet-20241022 (line 25) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shut down on 23 Oct 2026
  app/chat.py:10  o4-mini (line 11) → gpt-5.6-terra
  note: gpt-5.6-terra has real-time safeguards that can refuse or pause some cyber and biology output.

1 call uses a model Anthropic shut down on 30 Nov 2026
  app/chat.py:14  claude-sonnet-4-5-20250929 (line 15) → claude-sonnet-5-5
                  decide: think only between tools (add thinking={"type": "between_tools"}) or let the model think (no change)
  decide once for this repo (Arbor does not choose): claude-sonnet-5-5 thinks by default (adaptive thinking) when the call sends no thinking; the model it replaces answered without thinking.
    think only between tools: Closest to the old model: no thinking before the answer. Without tools the response contains only text; with tools, the short updates written between tool calls come back as thinking blocks. Accepted at low, medium and high effort; at xhigh or max effort the call returns 400.
    let the model think: The model thinks adaptively at its default effort (high). A response can begin with thinking blocks, so code that reads content[0].text breaks; max_tokens covers thinking plus text, and thinking tokens are billed as output tokens, so calls are slower and costlier when it thinks. How much it thinks on real prompts is not measured yet.
  note: A request that ends with an assistant turn (prefill) returns 400 on claude-sonnet-5-5.
  note: claude-sonnet-5-5 uses more tokens for the same text; check max_tokens headroom.
  note: Handle stop_reason "refusal" and "model_context_window_exceeded".

1 call uses a model OpenAI shuts down today (14 Jan 2027)
  app/chat.py:19  gpt-4o (line 20) → gpt-6-luna
                  also change: max_tokens → max_completion_tokens
                  decide: keep reasoning off (add reasoning_effort="none"; keep temperature) or let the model reason (remove temperature)
  decide once for this repo (Arbor does not choose): gpt-6-luna runs at medium reasoning effort by default, so it can reason; the model it replaces answered without a reasoning step.
    keep reasoning off: Closest to the old non-reasoning model: the call keeps answering without a reasoning step. (not verified)
                        Sampling stays as the code sets it and there is no reasoning step: closest to the old model.
    let the model reason: The model can reason (default effort medium). When it does, the call is slower, reasoning tokens are billed as output tokens, max_completion_tokens also has to cover them, and answers may change. How much it reasons on real prompts is not measured yet.
                          The model can reason (default effort medium) and samples on its own: slower and costlier when it reasons, and output style and determinism change.
  note: If gpt-6-luna reasons, max_completion_tokens also bounds its reasoning tokens, so a small limit can be used up before any visible text.
  note: gpt-4o is an alias: OpenAI's deprecations page gives it no shutdown date (its 14 Jan 2027 rows name only dated snapshots), but OpenAI's API reference lists it as deprecated with shutdown date 14 Jan 2027, and its models API gave that date on 18 Oct 2026.
  note: OpenAI describes gpt-6-luna as its "most efficient model for focused, high-volume tasks", so answer quality may change compared with the model it replaces.

Not checked: 1 call takes the model from somewhere Arbor cannot read (an environment variable, a function argument, another module); arbor usages lists it.
Summary: 4 calls in 1 file use retired or retiring models: 4 already retired.
1 can move to the listed replacement with the changes shown; 3 can move once this repo makes the choice shown under decide.
Failing (exit 1): 4 calls use a model that is already retired.
Retirement data from the providers' deprecation pages: OpenAI, Anthropic, Google and Google Cloud as of 28 Oct 2026. Days are counted in UTC. Python and direct SDK calls only for now. Runs locally: no code leaves this machine.

exit 14 failing

OpenAI’s own examples call models OpenAI is retiring.

We ran Arbor on the examples folder of openai/openai-python on : 22 calls in 20 files use retired or retiring models.

On the day, a rename isn’t enough.

Take the gpt-4o call on line 20. The obvious fix is the replacement OpenAI lists, gpt-6-luna.

Arbor prints three lines for this call. Lines 2 and 3 answer the two 400s below.

app/chat.py:19  gpt-4o (line 20) → gpt-6-luna

The call (line 19), its model (line 20) and the replacement the provider lists.

Change only the name and send the same call. The API answers:

400

Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.

also change: max_tokens → max_completion_tokens

An argument that has to change with the model.

400

Unsupported value: 'temperature' does not support 0.2 with this model. Only the default (1) value is supported.

decide: keep reasoning off (add reasoning_effort="none"; keep temperature) or let the model reason (remove temperature)

A choice that changes speed, cost and answers, so it's yours to make.

Recorded from OpenAI's Chat Completions API on . The retirements guide lists each argument we tested on gpt-6-luna.

In 2026 all three providers changed sampling: OpenAI's new models reject a non-default temperature unless reasoning is off, Claude 4.7 and later return 400 for a non-default temperature, top_p or top_k, and the Gemini API deprecated all three on .

Keep reasoning off

app/chat.py · line 20

− max_tokens=300
+ max_completion_tokens=300
+ reasoning_effort="none"
temperature=0.2 (kept)
Sampling stays as the code sets it and there is no reasoning step: closest to the old model.

At reasoning_effort="none", gpt-6-luna accepts a non-default temperature: a live check on got a 200 (Chat Completions).

Let the model reason

app/chat.py · line 20

− max_tokens=300
+ max_completion_tokens=300
− temperature=0.2
The model can reason (default effort medium) and samples on its own: slower and costlier when it reasons, and output style and determinism change.

OpenAI describes gpt-6-luna as its “most efficient model for focused, high-volume tasks”. Check answer quality before you ship the swap.

note: OpenAI describes gpt-6-luna as its "most efficient model for focused, high-volume tasks", so answer quality may change compared with the model it replaces.

Get ready before the date.

A readiness review is a paid, fixed-price sprint: a founder goes through your repos with you, we write the fix pull requests with your team before the date, and we list every call we find but can’t check.

Fixed price: $1,500 for up to 3 repos and $500 for each repo after that, agreed in writing and paid before work starts.

Request a readiness review

Set your deadline before theirs.

OpenAI's deprecations page states at least six months' notice for generally available models, unless safety or compliance requires faster. gpt-4o got 92 days: about half the six months.

In a pull request, the GitHub Action marks up to 10 affected lines and lists every call in its summary. Give retirements-fail-on a number of days, and the build fails once a shutdown is that close.

GitHub Actions workflow
name: Model retirements
on: [pull_request]

jobs:
  retirements:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: Anandb71/arbor@v3.1.1
        with:
          mode: retirements
          retirements-fail-on: 90

With retirements-fail-on: 90, a gpt-4o call has failed this check since : two days after OpenAI's announcement, 90 days before the shutdown.

What Arbor checks

Languages
Python today. TypeScript and JavaScript aren't supported yet.
Calls
Direct openai, anthropic, google-genai and google-generativeai SDK calls. Wrappers such as LangChain, LlamaIndex and LiteLLM aren't checked yet.
Routing
Calls through Azure, Bedrock, Vertex for Claude or another host in base_url are only counted by default, because the provider's dates may not apply there; --include-routed lists them and lets them fail the check.
Not read
Model IDs in .env, YAML, JSON or notebooks. A call whose model comes from an environment variable, a function argument or another module is listed as not checked and is not counted as failing (arbor usages lists it).
Data
308 retirement entries, each naming the provider page it came from. Update Arbor for newer dates.
Measured
In 18 example files copied unchanged from the OpenAI, Anthropic and legacy Gemini Python SDK repositories, Arbor found all 70 places that call an SDK or create its client.
Arguments
Arbor marks what must change (also change) and what you have to choose (decide).

Later: Arbor opens the fix as a pull request. Get one email when it ships.

Find the gpt-4o and gpt-4.1 calls in your Python code before .

npx @anandb71/arbor-cli@3.1.1 retirements .

Or request a readiness review

Arbor · Find AI model calls before they stop working