getreadystack commited on
Commit
16716f9
·
verified ·
1 Parent(s): 0186b41

Upload index.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +6 -7
index.html CHANGED
@@ -2,7 +2,6 @@
2
  <meta name="viewport" content="width=device-width,initial-scale=1">
3
  <title>Model Sunset Lint - retired AI model IDs, dated</title>
4
  <meta name="description" content="Finds every model ID and API parameter in your code that a vendor has already switched off or has published a date for - 109 rules across OpenAI, Anthropic, Google and Azure, each carrying the real shutdown date and the exact replacement string.">
5
- <script defer data-auto-init src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@latest/dist/embed.global.js"></script>
6
  <style>
7
  :root{color-scheme:light dark}
8
  body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;
@@ -67,7 +66,7 @@ genai.GenerativeModel("gemini-2.0-flash").generate_content("hello")
67
  </textarea>
68
  <button id="go">Check</button>
69
  <div id="out"></div>
70
- <div class="next"><h2>In the full version</h2><ul><li>Every file in the repository</li><li>Rewrite the retired IDs</li><li>Dated inventory as CSV, JSON or HTML</li><li>CI JSON so the build fails first</li><li><a href="https://getreadystack.com" data-polar-checkout data-polar-checkout-theme="light">Get the full version - $29</a></li></ul></div>
71
  </div>
72
  <script>
73
  var RULES=[{"pattern": "([\"'`])gpt\\-4\\.5\\-preview\\1", "flags": "", "message": "gpt-4.5-preview: OpenAI stopped answering on 14 July 2025 (2025-07-14). Move to gpt-4.1.", "fix": "Replace with gpt-4.1", "replace": "$1gpt-4.1$1", "sev": "error"}, {"pattern": "([\"'`])o1\\-preview\\1", "flags": "", "message": "o1-preview: OpenAI stopped answering on 28 July 2025 (2025-07-28). Move to o3.", "fix": "Replace with o3", "replace": "$1o3$1", "sev": "error"}, {"pattern": "([\"'`])o1\\-mini\\1", "flags": "", "message": "o1-mini: OpenAI stopped answering on 27 October 2025 (2025-10-27). Move to gpt-5.6-terra. (The replacement OpenAI first listed is itself shut down.)", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "error"}, {"pattern": "([\"'`])text\\-moderation\\-latest\\1", "flags": "", "message": "text-moderation-latest: OpenAI stopped answering on 27 October 2025 (2025-10-27). Move to omni-moderation.", "fix": "Replace with omni-moderation", "replace": "$1omni-moderation$1", "sev": "error"}, {"pattern": "([\"'`])text\\-moderation\\-stable\\1", "flags": "", "message": "text-moderation-stable: OpenAI stopped answering on 27 October 2025 (2025-10-27). Move to omni-moderation.", "fix": "Replace with omni-moderation", "replace": "$1omni-moderation$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-audio\\-preview\\-2024\\-10\\-01\\1", "flags": "", "message": "gpt-4o-audio-preview-2024-10-01: OpenAI stopped answering on 10 October 2025 (2025-10-10). Move to gpt-audio-1.5.", "fix": "Replace with gpt-audio-1.5", "replace": "$1gpt-audio-1.5$1", "sev": "error"}, {"pattern": "([\"'`])codex\\-mini\\-latest\\1", "flags": "", "message": "codex-mini-latest: OpenAI stopped answering on 12 February 2026 (2026-02-12). Move to gpt-5-codex-mini.", "fix": "Replace with gpt-5-codex-mini", "replace": "$1gpt-5-codex-mini$1", "sev": "error"}, {"pattern": "([\"'`])chatgpt\\-4o\\-latest\\1", "flags": "", "message": "chatgpt-4o-latest: OpenAI stopped answering on 17 February 2026 (2026-02-17). Move to gpt-5.6-sol. (The replacement OpenAI first listed is itself shut down.)", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])whisper\\-1\\1", "flags": "", "message": "whisper-1: OpenAI stopped answering on 26 February 2026 (2026-02-26). Move to gpt-transcribe.", "fix": "Replace with gpt-transcribe", "replace": "$1gpt-transcribe$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-transcribe\\1", "flags": "", "message": "gpt-4o-transcribe: OpenAI stopped answering on 26 February 2026 (2026-02-26). Move to gpt-transcribe.", "fix": "Replace with gpt-transcribe", "replace": "$1gpt-transcribe$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-mini\\-transcribe\\1", "flags": "", "message": "gpt-4o-mini-transcribe: OpenAI stopped answering on 26 February 2026 (2026-02-26). Move to gpt-transcribe.", "fix": "Replace with gpt-transcribe", "replace": "$1gpt-transcribe$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4\\-0314\\1", "flags": "", "message": "gpt-4-0314: OpenAI stopped answering on 26 March 2026 (2026-03-26). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4\\-0125\\-preview\\1", "flags": "", "message": "gpt-4-0125-preview: OpenAI stopped answering on 26 March 2026 (2026-03-26). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4\\-turbo\\-preview\\1", "flags": "", "message": "gpt-4-turbo-preview: OpenAI stopped answering on 26 March 2026 (2026-03-26). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-realtime\\-preview\\1", "flags": "", "message": "gpt-4o-realtime-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-realtime-1.5.", "fix": "Replace with gpt-realtime-1.5", "replace": "$1gpt-realtime-1.5$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-audio\\-preview\\1", "flags": "", "message": "gpt-4o-audio-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-audio-1.5.", "fix": "Replace with gpt-audio-1.5", "replace": "$1gpt-audio-1.5$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-mini\\-audio\\-preview\\1", "flags": "", "message": "gpt-4o-mini-audio-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-audio-mini.", "fix": "Replace with gpt-audio-mini", "replace": "$1gpt-audio-mini$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-mini\\-realtime\\-preview\\1", "flags": "", "message": "gpt-4o-mini-realtime-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-realtime-mini.", "fix": "Replace with gpt-realtime-mini", "replace": "$1gpt-realtime-mini$1", "sev": "error"}, {"pattern": "([\"'`])dall\\-e\\-2\\1", "flags": "", "message": "dall-e-2: OpenAI stopped answering on 12 May 2026 (2026-05-12). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "error"}, {"pattern": "([\"'`])dall\\-e\\-3\\1", "flags": "", "message": "dall-e-3: OpenAI stopped answering on 12 May 2026 (2026-05-12). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "error"}, {"pattern": "([\"'`])computer\\-use\\-preview\\1", "flags": "", "message": "computer-use-preview: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\-chat\\-latest\\1", "flags": "", "message": "gpt-5-chat-latest: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\-codex\\1", "flags": "", "message": "gpt-5-codex: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-chat\\-latest\\1", "flags": "", "message": "gpt-5.1-chat-latest: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-codex\\1", "flags": "", "message": "gpt-5.1-codex: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-codex\\-max\\1", "flags": "", "message": "gpt-5.1-codex-max: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-codex\\-mini\\1", "flags": "", "message": "gpt-5.1-codex-mini: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.2\\-codex\\1", "flags": "", "message": "gpt-5.2-codex: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])o3\\-deep\\-research\\1", "flags": "", "message": "o3-deep-research: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])o4\\-mini\\-deep\\-research\\1", "flags": "", "message": "o4-mini-deep-research: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.2\\-chat\\-latest\\1", "flags": "", "message": "gpt-5.2-chat-latest: OpenAI stopped answering on 10 August 2026 (2026-08-10). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.3\\-chat\\-latest\\1", "flags": "", "message": "gpt-5.3-chat-latest: OpenAI stopped answering on 10 August 2026 (2026-08-10). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])sora\\-2\\1", "flags": "", "message": "sora-2: OpenAI stops answering on 24 September 2026 (2026-09-24). Move to the Videos API replacement OpenAI names.", "fix": "Replace with the Videos API replacement OpenAI names", "replace": "$1the Videos API replacement OpenAI names$1", "sev": "warn"}, {"pattern": "([\"'`])sora\\-2\\-pro\\1", "flags": "", "message": "sora-2-pro: OpenAI stops answering on 24 September 2026 (2026-09-24). Move to the Videos API replacement OpenAI names.", "fix": "Replace with the Videos API replacement OpenAI names", "replace": "$1the Videos API replacement OpenAI names$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\-instruct\\1", "flags": "", "message": "gpt-3.5-turbo-instruct: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])babbage\\-002\\1", "flags": "", "message": "babbage-002: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])davinci\\-002\\1", "flags": "", "message": "davinci-002: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\-1106\\1", "flags": "", "message": "gpt-3.5-turbo-1106: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\1", "flags": "", "message": "gpt-3.5-turbo: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\-0125\\1", "flags": "", "message": "gpt-3.5-turbo-0125: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\1", "flags": "", "message": "gpt-4: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-0613\\1", "flags": "", "message": "gpt-4-0613: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-1106\\-preview\\1", "flags": "", "message": "gpt-4-1106-preview: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-turbo\\1", "flags": "", "message": "gpt-4-turbo: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-turbo\\-2024\\-04\\-09\\1", "flags": "", "message": "gpt-4-turbo-2024-04-09: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\.1\\-nano\\1", "flags": "", "message": "gpt-4.1-nano: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-luna.", "fix": "Replace with gpt-5.6-luna", "replace": "$1gpt-5.6-luna$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4o\\-2024\\-05\\-13\\1", "flags": "", "message": "gpt-4o-2024-05-13: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-image\\-1\\1", "flags": "", "message": "gpt-image-1: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])o1\\1", "flags": "", "message": "o1: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o1\\-pro\\1", "flags": "", "message": "o1-pro: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o3\\-mini\\1", "flags": "", "message": "o3-mini: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o4\\-mini\\1", "flags": "", "message": "o4-mini: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-image\\-1\\-mini\\1", "flags": "", "message": "gpt-image-1-mini: OpenAI stops answering on 1 December 2026 (2026-12-01). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-image\\-1\\.5\\1", "flags": "", "message": "gpt-image-1.5: OpenAI stops answering on 1 December 2026 (2026-12-01). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])chatgpt\\-image\\-latest\\1", "flags": "", "message": "chatgpt-image-latest: OpenAI stops answering on 1 December 2026 (2026-12-01). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-2025\\-08\\-07\\1", "flags": "", "message": "gpt-5-2025-08-07: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-mini\\-2025\\-08\\-07\\1", "flags": "", "message": "gpt-5-mini-2025-08-07: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-nano\\-2025\\-08\\-07\\1", "flags": "", "message": "gpt-5-nano-2025-08-07: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-luna.", "fix": "Replace with gpt-5.6-luna", "replace": "$1gpt-5.6-luna$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-pro\\-2025\\-10\\-06\\1", "flags": "", "message": "gpt-5-pro-2025-10-06: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o3\\-2025\\-04\\-16\\1", "flags": "", "message": "o3-2025-04-16: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o3\\-pro\\-2025\\-06\\-10\\1", "flags": "", "message": "o3-pro-2025-06-10: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "(beta\\.assistants|/v1/assistants)", "flags": "", "message": "Assistants API: OpenAI shut it down on 26 August 2026 (2026-08-26). Move to the Responses API and the Conversations API.", "sev": "error", "fix": "Rewrite against the Responses API / Conversations API"}, {"pattern": "/v1/prompts", "flags": "", "message": "The /v1/prompts API: OpenAI shuts it down on 30 November 2026 (2026-11-30). Move the prompt text into your application code.", "sev": "warn", "fix": "Inline the prompt in application code"}, {"pattern": "OpenAI-Beta[\"\\s:=]+realtime=v1", "flags": "", "message": "OpenAI-Beta: realtime=v1 was shut down on 12 May 2026 (2026-05-12). Use the current Realtime API without this header.", "sev": "error", "fix": "Drop the OpenAI-Beta realtime=v1 header"}, {"pattern": "([\"'`])claude\\-2\\.0\\1", "flags": "", "message": "claude-2.0: Anthropic stopped answering on 21 July 2025 (2025-07-21). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-2\\.1\\1", "flags": "", "message": "claude-2.1: Anthropic stopped answering on 21 July 2025 (2025-07-21). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-sonnet\\-20240229\\1", "flags": "", "message": "claude-3-sonnet-20240229: Anthropic stopped answering on 21 July 2025 (2025-07-21). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-5\\-sonnet\\-20240620\\1", "flags": "", "message": "claude-3-5-sonnet-20240620: Anthropic stopped answering on 28 October 2025 (2025-10-28). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-5\\-sonnet\\-20241022\\1", "flags": "", "message": "claude-3-5-sonnet-20241022: Anthropic stopped answering on 28 October 2025 (2025-10-28). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-opus\\-20240229\\1", "flags": "", "message": "claude-3-opus-20240229: Anthropic stopped answering on 5 January 2026 (2026-01-05). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-7\\-sonnet\\-20250219\\1", "flags": "", "message": "claude-3-7-sonnet-20250219: Anthropic stopped answering on 19 February 2026 (2026-02-19). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-5\\-haiku\\-20241022\\1", "flags": "", "message": "claude-3-5-haiku-20241022: Anthropic stopped answering on 19 February 2026 (2026-02-19). Move to claude-haiku-4-5.", "fix": "Replace with claude-haiku-4-5", "replace": "$1claude-haiku-4-5$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-haiku\\-20240307\\1", "flags": "", "message": "claude-3-haiku-20240307: Anthropic stopped answering on 20 April 2026 (2026-04-20). Move to claude-haiku-4-5.", "fix": "Replace with claude-haiku-4-5", "replace": "$1claude-haiku-4-5$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-sonnet\\-4\\-20250514\\1", "flags": "", "message": "claude-sonnet-4-20250514: Anthropic stopped answering on 15 June 2026 (2026-06-15). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-opus\\-4\\-20250514\\1", "flags": "", "message": "claude-opus-4-20250514: Anthropic stopped answering on 15 June 2026 (2026-06-15). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-opus\\-4\\-1\\-20250805\\1", "flags": "", "message": "claude-opus-4-1-20250805: Anthropic stopped answering on 5 August 2026 (2026-08-05). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-sonnet\\-4\\-5\\-20250929\\1", "flags": "", "message": "claude-sonnet-4-5-20250929: Anthropic lists a tentative retirement not sooner than 29 September 2026 (2026-09-29). Plan the move to claude-sonnet-5.", "sev": "warn", "fix": "Plan the move to claude-sonnet-5"}, {"pattern": "([\"'`])claude\\-haiku\\-4\\-5\\-20251001\\1", "flags": "", "message": "claude-haiku-4-5-20251001: Anthropic lists a tentative retirement not sooner than 15 October 2026 (2026-10-15). Plan the move to claude-haiku-4-5.", "sev": "warn", "fix": "Plan the move to claude-haiku-4-5"}, {"pattern": "([\"'`])claude\\-opus\\-4\\-5\\-20251101\\1", "flags": "", "message": "claude-opus-4-5-20251101: Anthropic lists a tentative retirement not sooner than 24 November 2026 (2026-11-24). Plan the move to claude-opus-5.", "sev": "warn", "fix": "Plan the move to claude-opus-5"}, {"pattern": "([\"'`])claude-mythos-preview\\1", "flags": "", "message": "claude-mythos-preview is deprecated. Move to claude-mythos-5.", "sev": "warn", "fix": "Replace with claude-mythos-5", "replace": "$1claude-mythos-5$1"}, {"pattern": "([\"\\'`])claude-(opus-5|sonnet-5|fable-5|opus-4-[678]|sonnet-4-6|haiku-4-5)-\\d{8}\\1", "flags": "", "message": "Current-generation Claude model IDs carry no date suffix - a dated variant of this ID does not exist and returns a 404. Use the bare ID (for example claude-opus-5).", "sev": "error", "fix": "Drop the -YYYYMMDD suffix"}, {"pattern": "\\b(budget_tokens|budgetTokens)\\b", "flags": "", "message": "budget_tokens is removed on Claude Opus 4.7 and later (Opus 5, Opus 4.8, Sonnet 5, Fable 5) and returns a 400. Use thinking: {type: \"adaptive\"} with output_config.effort.", "sev": "error", "fix": "thinking: {type: \"adaptive\"} + output_config.effort"}, {"pattern": "([\"\\'`])web_search_20250305\\1", "flags": "", "message": "web_search_20250305 is the pre-2026 server-tool variant. On Opus 5/4.8/4.7/4.6, Sonnet 5 and Sonnet 4.6 use web_search_20260209. (Vertex AI still carries only the older variant.)", "sev": "warn", "fix": "Replace with web_search_20260209", "replace": "$1web_search_20260209$1"}, {"pattern": "([\"\\'`])web_fetch_20250910\\1", "flags": "", "message": "web_fetch_20250910 is the pre-2026 server-tool variant. On Opus 5/4.8/4.7/4.6, Sonnet 5 and Sonnet 4.6 use web_fetch_20260209.", "sev": "warn", "fix": "Replace with web_fetch_20260209", "replace": "$1web_fetch_20260209$1"}, {"pattern": "([\"\\'`])(files-api-2025-04-14|skills-2025-10-02)\\1", "flags": "", "message": "This beta header is obsolete - the Files API and Skills are out of beta. Remove the header and call client.files / client.skills.", "sev": "error", "fix": "Remove the beta header"}, {"pattern": "\\bclient\\.beta\\.(files|skills)\\b", "flags": "", "message": "client.beta.files / client.beta.skills changed shape when Files and Skills left beta. Use client.files / client.skills with no beta header.", "sev": "warn", "fix": "Use client.files / client.skills"}, {"pattern": "([\"\\'`])code_execution_tool_result\\1", "flags": "", "message": "code_execution_20260521 returns bash_code_execution_tool_result, not the bare code_execution_tool_result block. Matching the old type silently drops every result.", "sev": "warn", "fix": "Match bash_code_execution_tool_result"}, {"pattern": "\\boutput_format\\s*[=:]", "flags": "", "message": "The output_format parameter on the Anthropic Messages API is deprecated. Use output_config: {format: {...}}.", "sev": "info", "fix": "Use output_config.format"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-live\\-001\\1", "flags": "", "message": "gemini-2.0-flash-live-001: Google stopped answering on 9 December 2025 (2025-12-09). Move to a current Gemini Live model.", "fix": "Replace with a current Gemini Live model", "replace": "$1a current Gemini Live model$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-live\\-2\\.5\\-flash\\-preview\\1", "flags": "", "message": "gemini-live-2.5-flash-preview: Google stopped answering on 9 December 2025 (2025-12-09). Move to a current Gemini Live model.", "fix": "Replace with a current Gemini Live model", "replace": "$1a current Gemini Live model$1", "sev": "error"}, {"pattern": "([\"'`])text\\-embedding\\-004\\1", "flags": "", "message": "text-embedding-004: Google stopped answering on 14 January 2026 (2026-01-14). Move to a current Gemini embedding model.", "fix": "Replace with a current Gemini embedding model", "replace": "$1a current Gemini embedding model$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.5\\-flash\\-image\\-preview\\1", "flags": "", "message": "gemini-2.5-flash-image-preview: Google stopped answering on 15 January 2026 (2026-01-15). Move to gemini-3.1-flash-image.", "fix": "Replace with gemini-3.1-flash-image", "replace": "$1gemini-3.1-flash-image$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-3\\.1\\-flash\\-lite\\-preview\\1", "flags": "", "message": "gemini-3.1-flash-lite-preview: Google stopped answering on 25 May 2026 (2026-05-25). Move to gemini-3.1-flash-lite.", "fix": "Replace with gemini-3.1-flash-lite", "replace": "$1gemini-3.1-flash-lite$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\1", "flags": "", "message": "gemini-2.0-flash: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.5-flash.", "fix": "Replace with gemini-3.5-flash", "replace": "$1gemini-3.5-flash$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-001\\1", "flags": "", "message": "gemini-2.0-flash-001: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.5-flash.", "fix": "Replace with gemini-3.5-flash", "replace": "$1gemini-3.5-flash$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-lite\\1", "flags": "", "message": "gemini-2.0-flash-lite: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.1-flash-lite.", "fix": "Replace with gemini-3.1-flash-lite", "replace": "$1gemini-3.1-flash-lite$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-lite\\-001\\1", "flags": "", "message": "gemini-2.0-flash-lite-001: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.1-flash-lite.", "fix": "Replace with gemini-3.1-flash-lite", "replace": "$1gemini-3.1-flash-lite$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-3\\.1\\-flash\\-image\\-preview\\1", "flags": "", "message": "gemini-3.1-flash-image-preview: Google stopped answering on 25 June 2026 (2026-06-25). Move to gemini-3.1-flash-image.", "fix": "Replace with gemini-3.1-flash-image", "replace": "$1gemini-3.1-flash-image$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-3\\-pro\\-image\\-preview\\1", "flags": "", "message": "gemini-3-pro-image-preview: Google stopped answering on 25 June 2026 (2026-06-25). Move to gemini-3-pro-image.", "fix": "Replace with gemini-3-pro-image", "replace": "$1gemini-3-pro-image$1", "sev": "error"}, {"pattern": "([\"'`])veo\\-2\\.0\\-generate\\-001\\1", "flags": "", "message": "veo-2.0-generate-001: Google stopped answering on 30 June 2026 (2026-06-30). Move to veo-3.1-generate-preview.", "fix": "Replace with veo-3.1-generate-preview", "replace": "$1veo-3.1-generate-preview$1", "sev": "error"}, {"pattern": "([\"'`])veo\\-3\\.0\\-generate\\-001\\1", "flags": "", "message": "veo-3.0-generate-001: Google stopped answering on 30 June 2026 (2026-06-30). Move to veo-3.1-generate-preview.", "fix": "Replace with veo-3.1-generate-preview", "replace": "$1veo-3.1-generate-preview$1", "sev": "error"}, {"pattern": "([\"'`])veo\\-3\\.0\\-fast\\-generate\\-001\\1", "flags": "", "message": "veo-3.0-fast-generate-001: Google stopped answering on 30 June 2026 (2026-06-30). Move to veo-3.1-fast-generate-preview.", "fix": "Replace with veo-3.1-fast-generate-preview", "replace": "$1veo-3.1-fast-generate-preview$1", "sev": "error"}, {"pattern": "([\"'`])imagen\\-4\\.0\\-generate\\-001\\1", "flags": "", "message": "imagen-4.0-generate-001: Google stopped answering on 17 August 2026 (2026-08-17). Move to a current Imagen model.", "fix": "Replace with a current Imagen model", "replace": "$1a current Imagen model$1", "sev": "error"}, {"pattern": "([\"'`])imagen\\-4\\.0\\-ultra\\-generate\\-001\\1", "flags": "", "message": "imagen-4.0-ultra-generate-001: Google stopped answering on 17 August 2026 (2026-08-17). Move to a current Imagen model.", "fix": "Replace with a current Imagen model", "replace": "$1a current Imagen model$1", "sev": "error"}, {"pattern": "([\"'`])imagen\\-4\\.0\\-fast\\-generate\\-001\\1", "flags": "", "message": "imagen-4.0-fast-generate-001: Google stopped answering on 17 August 2026 (2026-08-17). Move to a current Imagen model.", "fix": "Replace with a current Imagen model", "replace": "$1a current Imagen model$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-robotics\\-er\\-1\\.6\\-preview\\1", "flags": "", "message": "gemini-robotics-er-1.6-preview: Google stopped answering on 31 August 2026 (2026-08-31). Move to gemini-robotics-er-2-preview.", "fix": "Replace with gemini-robotics-er-2-preview", "replace": "$1gemini-robotics-er-2-preview$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-omni\\-flash\\-preview\\1", "flags": "", "message": "gemini-omni-flash-preview: Google stops answering on 30 September 2026 (2026-09-30). Move to gemini-omni-1.1-flash.", "fix": "Replace with gemini-omni-1.1-flash", "replace": "$1gemini-omni-1.1-flash$1", "sev": "warn"}, {"pattern": "([\"\\'`])NoAutoUpgrade\\1", "flags": "", "message": "versionUpgradeOption NoAutoUpgrade means Azure will not move this deployment at retirement - inference starts returning 410 Gone on the retirement date instead. Use OnceCurrentVersionExpired unless you are pinning deliberately.", "sev": "warn", "fix": "OnceCurrentVersionExpired"}, {"pattern": "lifecycleStatus\\s*[=!]==?\\s*([\"\\'`])Deprecated\\1", "flags": "", "message": "In the Azure Models API, lifecycleStatus \"Deprecated\" means RETIRED (410 Gone). A model that still serves inference reports \"Deprecating\". Comparing against \"Deprecated\" inverts the check.", "sev": "error", "fix": "Check for \"Deprecating\", or compare deprecation.inference to today"}];
@@ -89,13 +88,13 @@ document.getElementById('go').click();
89
  </script>
90
  </html>
91
 
92
- <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get one email when this rule changes</b><div style="opacity:.78;margin:.35rem 0 .8rem">We watch the regulation and vendor sources behind Model Sunset Lint - retired AI model IDs, dated every day. When a rule changes, you get a single email with what changed and the updated check. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Notify me</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">You're on the list. One email when it changes.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"model-sunset-lint",lang:"en",source:"rule_alert"})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script></section>
93
-
94
 
95
  <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://www.npmjs.com/package/@readystack/model-sunset-lint" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'model-sunset-lint',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://hub.docker.com/r/getreadystack/model-sunset-lint" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'model-sunset-lint',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">npx @readystack/model-sunset-lint &lt;file&gt;
96
- docker run --rm -v &quot;$PWD:/w&quot; getreadystack/model-sunset-lint /w</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://buy.polar.sh/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
97
- <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">Finds every model ID and API parameter in your code that a vendor has already switched off or has published a date for - 109 rules across OpenAI, Anthropic, Google and Azure, each carrying t</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">A US software engineer averages $70.92/hour (ZipRecruiter, August 2026). $29 is about 25 minutes of that, once.</p><a href="https://buy.polar.sh/polar_cl_L419KriWzJmPVgpnUDLnm67jUqWfQGdXNRqW43yeENB" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section>
98
- <section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does Model Sunset Lint actually do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads the file you have open and flags every model ID, endpoint and API parameter that a vendor has already switched off or has published a shutdown date for. Each finding names the vendor, the date itself, and the exact replacement string. 109 rules ship inside, covering OpenAI, Anthropic, Google and Azure.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is this for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Engineers who own a shipped LLM feature - the person paged when a call starts returning 404 - and reviewers of code an AI assistant wrote. An assistant cannot know a retirement date set after it was trained, so it confidently emits IDs that stopped answering months ago. This catches them at edit time instead of in production.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just ask an AI, or wait for the 404?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">An assistant answers from training data, and a retirement calendar changes after training ends - that is exactly the fact it cannot have. Dependabot bumps package versions and never reads a string literal like &quot;gpt-4&quot;. Type checkers see a valid string. Nothing in the free toolchain carries a date, so the 404 in production is the alarm.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what needs a licence?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">The free tier checks the open file, or only the lines you select, against all 109 rules. No key, no watermark, no usage cap, and no finding is hidden. The licence covers a different job: sweeping the whole repository in one pass, rewriting the retired IDs in place, exporting the dated inventory, and CI output.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What would this cost me otherwise?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A US software engineer averages $70.92 an hour (ZipRecruiter, August 2026). Auditing one repository by hand means grepping every model string and checking it against four vendors’ deprecation pages, then repeating that each quarter. This is $29 once, one licence key per person or team seat, with a seven-day full refund.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Model Sunset Lint actually do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads the file you have open and flags every model ID, endpoint and API parameter that a vendor has already switched off or has published a shutdown date for. Each finding names the vendor, the date itself, and the exact replacement string. 109 rules ship inside, covering OpenAI, Anthropic, Google and Azure."}}, {"@type": "Question", "name": "Who is this for?", "acceptedAnswer": {"@type": "Answer", "text": "Engineers who own a shipped LLM feature - the person paged when a call starts returning 404 - and reviewers of code an AI assistant wrote. An assistant cannot know a retirement date set after it was trained, so it confidently emits IDs that stopped answering months ago. This catches them at edit time instead of in production."}}, {"@type": "Question", "name": "Why not just ask an AI, or wait for the 404?", "acceptedAnswer": {"@type": "Answer", "text": "An assistant answers from training data, and a retirement calendar changes after training ends - that is exactly the fact it cannot have. Dependabot bumps package versions and never reads a string literal like \"gpt-4\". Type checkers see a valid string. Nothing in the free toolchain carries a date, so the 404 in production is the alarm."}}, {"@type": "Question", "name": "What is free and what needs a licence?", "acceptedAnswer": {"@type": "Answer", "text": "The free tier checks the open file, or only the lines you select, against all 109 rules. No key, no watermark, no usage cap, and no finding is hidden. The licence covers a different job: sweeping the whole repository in one pass, rewriting the retired IDs in place, exporting the dated inventory, and CI output."}}, {"@type": "Question", "name": "What would this cost me otherwise?", "acceptedAnswer": {"@type": "Answer", "text": "A US software engineer averages $70.92 an hour (ZipRecruiter, August 2026). Auditing one repository by hand means grepping every model string and checking it against four vendors’ deprecation pages, then repeating that each quarter. This is $29 once, one licence key per person or team seat, with a seven-day full refund."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:0,slug:"model-sunset-lint",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence, 7-day refund.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/play-release-blocker-lint"><span class="yj-rel-t">Google Play Release Blocker Lint - target API 36, Billing 8, 16 KB</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/personal-data-map-dsar-audit"><span class="yj-rel-t">Personal Data Map: find every column a GDPR subject access request has to reac</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/en/p/heloc-calculator-for-homeowners-real-payment-payoff-rate-sho"><span class="yj-rel-t">HELOC Calculator for Homeowners: Real Payment, Payoff &amp; Rate-Shock (Google She</span><span class="yj-rel-p">$39</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/real-estate-icon-set"><span class="yj-rel-t">Real Estate Listing UI Kit — Property Status Badges, Amenity Chips &amp; Agent Car</span><span class="yj-rel-p">$168</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/webflow-restaurant-template"><span class="yj-rel-t">Webflow Restaurant Template — delivered as self-contained HTML you own: 26 pag</span><span class="yj-rel-p">$49</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/robots-txt-ai-crawler-audit"><span class="yj-rel-t">AI Crawler Rules - robots.txt Audit for AI Search</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section><!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div>
 
 
99
 
100
 
101
  <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>
 
2
  <meta name="viewport" content="width=device-width,initial-scale=1">
3
  <title>Model Sunset Lint - retired AI model IDs, dated</title>
4
  <meta name="description" content="Finds every model ID and API parameter in your code that a vendor has already switched off or has published a date for - 109 rules across OpenAI, Anthropic, Google and Azure, each carrying the real shutdown date and the exact replacement string.">
 
5
  <style>
6
  :root{color-scheme:light dark}
7
  body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;
 
66
  </textarea>
67
  <button id="go">Check</button>
68
  <div id="out"></div>
69
+ <div class="next"><h2>In the full version</h2><ul><li>Every file in the repository</li><li>Rewrite the retired IDs</li><li>Dated inventory as CSV, JSON or HTML</li><li>CI JSON so the build fails first</li><li><a href="https://getreadystack.com">Get the full version - $29</a></li></ul></div>
70
  </div>
71
  <script>
72
  var RULES=[{"pattern": "([\"'`])gpt\\-4\\.5\\-preview\\1", "flags": "", "message": "gpt-4.5-preview: OpenAI stopped answering on 14 July 2025 (2025-07-14). Move to gpt-4.1.", "fix": "Replace with gpt-4.1", "replace": "$1gpt-4.1$1", "sev": "error"}, {"pattern": "([\"'`])o1\\-preview\\1", "flags": "", "message": "o1-preview: OpenAI stopped answering on 28 July 2025 (2025-07-28). Move to o3.", "fix": "Replace with o3", "replace": "$1o3$1", "sev": "error"}, {"pattern": "([\"'`])o1\\-mini\\1", "flags": "", "message": "o1-mini: OpenAI stopped answering on 27 October 2025 (2025-10-27). Move to gpt-5.6-terra. (The replacement OpenAI first listed is itself shut down.)", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "error"}, {"pattern": "([\"'`])text\\-moderation\\-latest\\1", "flags": "", "message": "text-moderation-latest: OpenAI stopped answering on 27 October 2025 (2025-10-27). Move to omni-moderation.", "fix": "Replace with omni-moderation", "replace": "$1omni-moderation$1", "sev": "error"}, {"pattern": "([\"'`])text\\-moderation\\-stable\\1", "flags": "", "message": "text-moderation-stable: OpenAI stopped answering on 27 October 2025 (2025-10-27). Move to omni-moderation.", "fix": "Replace with omni-moderation", "replace": "$1omni-moderation$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-audio\\-preview\\-2024\\-10\\-01\\1", "flags": "", "message": "gpt-4o-audio-preview-2024-10-01: OpenAI stopped answering on 10 October 2025 (2025-10-10). Move to gpt-audio-1.5.", "fix": "Replace with gpt-audio-1.5", "replace": "$1gpt-audio-1.5$1", "sev": "error"}, {"pattern": "([\"'`])codex\\-mini\\-latest\\1", "flags": "", "message": "codex-mini-latest: OpenAI stopped answering on 12 February 2026 (2026-02-12). Move to gpt-5-codex-mini.", "fix": "Replace with gpt-5-codex-mini", "replace": "$1gpt-5-codex-mini$1", "sev": "error"}, {"pattern": "([\"'`])chatgpt\\-4o\\-latest\\1", "flags": "", "message": "chatgpt-4o-latest: OpenAI stopped answering on 17 February 2026 (2026-02-17). Move to gpt-5.6-sol. (The replacement OpenAI first listed is itself shut down.)", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])whisper\\-1\\1", "flags": "", "message": "whisper-1: OpenAI stopped answering on 26 February 2026 (2026-02-26). Move to gpt-transcribe.", "fix": "Replace with gpt-transcribe", "replace": "$1gpt-transcribe$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-transcribe\\1", "flags": "", "message": "gpt-4o-transcribe: OpenAI stopped answering on 26 February 2026 (2026-02-26). Move to gpt-transcribe.", "fix": "Replace with gpt-transcribe", "replace": "$1gpt-transcribe$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-mini\\-transcribe\\1", "flags": "", "message": "gpt-4o-mini-transcribe: OpenAI stopped answering on 26 February 2026 (2026-02-26). Move to gpt-transcribe.", "fix": "Replace with gpt-transcribe", "replace": "$1gpt-transcribe$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4\\-0314\\1", "flags": "", "message": "gpt-4-0314: OpenAI stopped answering on 26 March 2026 (2026-03-26). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4\\-0125\\-preview\\1", "flags": "", "message": "gpt-4-0125-preview: OpenAI stopped answering on 26 March 2026 (2026-03-26). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4\\-turbo\\-preview\\1", "flags": "", "message": "gpt-4-turbo-preview: OpenAI stopped answering on 26 March 2026 (2026-03-26). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-realtime\\-preview\\1", "flags": "", "message": "gpt-4o-realtime-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-realtime-1.5.", "fix": "Replace with gpt-realtime-1.5", "replace": "$1gpt-realtime-1.5$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-audio\\-preview\\1", "flags": "", "message": "gpt-4o-audio-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-audio-1.5.", "fix": "Replace with gpt-audio-1.5", "replace": "$1gpt-audio-1.5$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-mini\\-audio\\-preview\\1", "flags": "", "message": "gpt-4o-mini-audio-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-audio-mini.", "fix": "Replace with gpt-audio-mini", "replace": "$1gpt-audio-mini$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-4o\\-mini\\-realtime\\-preview\\1", "flags": "", "message": "gpt-4o-mini-realtime-preview: OpenAI stopped answering on 7 May 2026 (2026-05-07). Move to gpt-realtime-mini.", "fix": "Replace with gpt-realtime-mini", "replace": "$1gpt-realtime-mini$1", "sev": "error"}, {"pattern": "([\"'`])dall\\-e\\-2\\1", "flags": "", "message": "dall-e-2: OpenAI stopped answering on 12 May 2026 (2026-05-12). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "error"}, {"pattern": "([\"'`])dall\\-e\\-3\\1", "flags": "", "message": "dall-e-3: OpenAI stopped answering on 12 May 2026 (2026-05-12). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "error"}, {"pattern": "([\"'`])computer\\-use\\-preview\\1", "flags": "", "message": "computer-use-preview: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\-chat\\-latest\\1", "flags": "", "message": "gpt-5-chat-latest: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\-codex\\1", "flags": "", "message": "gpt-5-codex: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-chat\\-latest\\1", "flags": "", "message": "gpt-5.1-chat-latest: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-codex\\1", "flags": "", "message": "gpt-5.1-codex: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-codex\\-max\\1", "flags": "", "message": "gpt-5.1-codex-max: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.1\\-codex\\-mini\\1", "flags": "", "message": "gpt-5.1-codex-mini: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.2\\-codex\\1", "flags": "", "message": "gpt-5.2-codex: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])o3\\-deep\\-research\\1", "flags": "", "message": "o3-deep-research: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])o4\\-mini\\-deep\\-research\\1", "flags": "", "message": "o4-mini-deep-research: OpenAI stopped answering on 23 July 2026 (2026-07-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.2\\-chat\\-latest\\1", "flags": "", "message": "gpt-5.2-chat-latest: OpenAI stopped answering on 10 August 2026 (2026-08-10). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])gpt\\-5\\.3\\-chat\\-latest\\1", "flags": "", "message": "gpt-5.3-chat-latest: OpenAI stopped answering on 10 August 2026 (2026-08-10). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "error"}, {"pattern": "([\"'`])sora\\-2\\1", "flags": "", "message": "sora-2: OpenAI stops answering on 24 September 2026 (2026-09-24). Move to the Videos API replacement OpenAI names.", "fix": "Replace with the Videos API replacement OpenAI names", "replace": "$1the Videos API replacement OpenAI names$1", "sev": "warn"}, {"pattern": "([\"'`])sora\\-2\\-pro\\1", "flags": "", "message": "sora-2-pro: OpenAI stops answering on 24 September 2026 (2026-09-24). Move to the Videos API replacement OpenAI names.", "fix": "Replace with the Videos API replacement OpenAI names", "replace": "$1the Videos API replacement OpenAI names$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\-instruct\\1", "flags": "", "message": "gpt-3.5-turbo-instruct: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])babbage\\-002\\1", "flags": "", "message": "babbage-002: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])davinci\\-002\\1", "flags": "", "message": "davinci-002: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\-1106\\1", "flags": "", "message": "gpt-3.5-turbo-1106: OpenAI stops answering on 28 September 2026 (2026-09-28). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\1", "flags": "", "message": "gpt-3.5-turbo: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-3\\.5\\-turbo\\-0125\\1", "flags": "", "message": "gpt-3.5-turbo-0125: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\1", "flags": "", "message": "gpt-4: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-0613\\1", "flags": "", "message": "gpt-4-0613: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-1106\\-preview\\1", "flags": "", "message": "gpt-4-1106-preview: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-turbo\\1", "flags": "", "message": "gpt-4-turbo: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\-turbo\\-2024\\-04\\-09\\1", "flags": "", "message": "gpt-4-turbo-2024-04-09: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4\\.1\\-nano\\1", "flags": "", "message": "gpt-4.1-nano: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-luna.", "fix": "Replace with gpt-5.6-luna", "replace": "$1gpt-5.6-luna$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-4o\\-2024\\-05\\-13\\1", "flags": "", "message": "gpt-4o-2024-05-13: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-image\\-1\\1", "flags": "", "message": "gpt-image-1: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])o1\\1", "flags": "", "message": "o1: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o1\\-pro\\1", "flags": "", "message": "o1-pro: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o3\\-mini\\1", "flags": "", "message": "o3-mini: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o4\\-mini\\1", "flags": "", "message": "o4-mini: OpenAI stops answering on 23 October 2026 (2026-10-23). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-image\\-1\\-mini\\1", "flags": "", "message": "gpt-image-1-mini: OpenAI stops answering on 1 December 2026 (2026-12-01). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-image\\-1\\.5\\1", "flags": "", "message": "gpt-image-1.5: OpenAI stops answering on 1 December 2026 (2026-12-01). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])chatgpt\\-image\\-latest\\1", "flags": "", "message": "chatgpt-image-latest: OpenAI stops answering on 1 December 2026 (2026-12-01). Move to gpt-image-2.", "fix": "Replace with gpt-image-2", "replace": "$1gpt-image-2$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-2025\\-08\\-07\\1", "flags": "", "message": "gpt-5-2025-08-07: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-mini\\-2025\\-08\\-07\\1", "flags": "", "message": "gpt-5-mini-2025-08-07: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-terra.", "fix": "Replace with gpt-5.6-terra", "replace": "$1gpt-5.6-terra$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-nano\\-2025\\-08\\-07\\1", "flags": "", "message": "gpt-5-nano-2025-08-07: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-luna.", "fix": "Replace with gpt-5.6-luna", "replace": "$1gpt-5.6-luna$1", "sev": "warn"}, {"pattern": "([\"'`])gpt\\-5\\-pro\\-2025\\-10\\-06\\1", "flags": "", "message": "gpt-5-pro-2025-10-06: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o3\\-2025\\-04\\-16\\1", "flags": "", "message": "o3-2025-04-16: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "([\"'`])o3\\-pro\\-2025\\-06\\-10\\1", "flags": "", "message": "o3-pro-2025-06-10: OpenAI stops answering on 11 December 2026 (2026-12-11). Move to gpt-5.6-sol.", "fix": "Replace with gpt-5.6-sol", "replace": "$1gpt-5.6-sol$1", "sev": "warn"}, {"pattern": "(beta\\.assistants|/v1/assistants)", "flags": "", "message": "Assistants API: OpenAI shut it down on 26 August 2026 (2026-08-26). Move to the Responses API and the Conversations API.", "sev": "error", "fix": "Rewrite against the Responses API / Conversations API"}, {"pattern": "/v1/prompts", "flags": "", "message": "The /v1/prompts API: OpenAI shuts it down on 30 November 2026 (2026-11-30). Move the prompt text into your application code.", "sev": "warn", "fix": "Inline the prompt in application code"}, {"pattern": "OpenAI-Beta[\"\\s:=]+realtime=v1", "flags": "", "message": "OpenAI-Beta: realtime=v1 was shut down on 12 May 2026 (2026-05-12). Use the current Realtime API without this header.", "sev": "error", "fix": "Drop the OpenAI-Beta realtime=v1 header"}, {"pattern": "([\"'`])claude\\-2\\.0\\1", "flags": "", "message": "claude-2.0: Anthropic stopped answering on 21 July 2025 (2025-07-21). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-2\\.1\\1", "flags": "", "message": "claude-2.1: Anthropic stopped answering on 21 July 2025 (2025-07-21). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-sonnet\\-20240229\\1", "flags": "", "message": "claude-3-sonnet-20240229: Anthropic stopped answering on 21 July 2025 (2025-07-21). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-5\\-sonnet\\-20240620\\1", "flags": "", "message": "claude-3-5-sonnet-20240620: Anthropic stopped answering on 28 October 2025 (2025-10-28). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-5\\-sonnet\\-20241022\\1", "flags": "", "message": "claude-3-5-sonnet-20241022: Anthropic stopped answering on 28 October 2025 (2025-10-28). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-opus\\-20240229\\1", "flags": "", "message": "claude-3-opus-20240229: Anthropic stopped answering on 5 January 2026 (2026-01-05). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-7\\-sonnet\\-20250219\\1", "flags": "", "message": "claude-3-7-sonnet-20250219: Anthropic stopped answering on 19 February 2026 (2026-02-19). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-5\\-haiku\\-20241022\\1", "flags": "", "message": "claude-3-5-haiku-20241022: Anthropic stopped answering on 19 February 2026 (2026-02-19). Move to claude-haiku-4-5.", "fix": "Replace with claude-haiku-4-5", "replace": "$1claude-haiku-4-5$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-3\\-haiku\\-20240307\\1", "flags": "", "message": "claude-3-haiku-20240307: Anthropic stopped answering on 20 April 2026 (2026-04-20). Move to claude-haiku-4-5.", "fix": "Replace with claude-haiku-4-5", "replace": "$1claude-haiku-4-5$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-sonnet\\-4\\-20250514\\1", "flags": "", "message": "claude-sonnet-4-20250514: Anthropic stopped answering on 15 June 2026 (2026-06-15). Move to claude-sonnet-4-6.", "fix": "Replace with claude-sonnet-4-6", "replace": "$1claude-sonnet-4-6$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-opus\\-4\\-20250514\\1", "flags": "", "message": "claude-opus-4-20250514: Anthropic stopped answering on 15 June 2026 (2026-06-15). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-opus\\-4\\-1\\-20250805\\1", "flags": "", "message": "claude-opus-4-1-20250805: Anthropic stopped answering on 5 August 2026 (2026-08-05). Move to claude-opus-4-8.", "fix": "Replace with claude-opus-4-8", "replace": "$1claude-opus-4-8$1", "sev": "error"}, {"pattern": "([\"'`])claude\\-sonnet\\-4\\-5\\-20250929\\1", "flags": "", "message": "claude-sonnet-4-5-20250929: Anthropic lists a tentative retirement not sooner than 29 September 2026 (2026-09-29). Plan the move to claude-sonnet-5.", "sev": "warn", "fix": "Plan the move to claude-sonnet-5"}, {"pattern": "([\"'`])claude\\-haiku\\-4\\-5\\-20251001\\1", "flags": "", "message": "claude-haiku-4-5-20251001: Anthropic lists a tentative retirement not sooner than 15 October 2026 (2026-10-15). Plan the move to claude-haiku-4-5.", "sev": "warn", "fix": "Plan the move to claude-haiku-4-5"}, {"pattern": "([\"'`])claude\\-opus\\-4\\-5\\-20251101\\1", "flags": "", "message": "claude-opus-4-5-20251101: Anthropic lists a tentative retirement not sooner than 24 November 2026 (2026-11-24). Plan the move to claude-opus-5.", "sev": "warn", "fix": "Plan the move to claude-opus-5"}, {"pattern": "([\"'`])claude-mythos-preview\\1", "flags": "", "message": "claude-mythos-preview is deprecated. Move to claude-mythos-5.", "sev": "warn", "fix": "Replace with claude-mythos-5", "replace": "$1claude-mythos-5$1"}, {"pattern": "([\"\\'`])claude-(opus-5|sonnet-5|fable-5|opus-4-[678]|sonnet-4-6|haiku-4-5)-\\d{8}\\1", "flags": "", "message": "Current-generation Claude model IDs carry no date suffix - a dated variant of this ID does not exist and returns a 404. Use the bare ID (for example claude-opus-5).", "sev": "error", "fix": "Drop the -YYYYMMDD suffix"}, {"pattern": "\\b(budget_tokens|budgetTokens)\\b", "flags": "", "message": "budget_tokens is removed on Claude Opus 4.7 and later (Opus 5, Opus 4.8, Sonnet 5, Fable 5) and returns a 400. Use thinking: {type: \"adaptive\"} with output_config.effort.", "sev": "error", "fix": "thinking: {type: \"adaptive\"} + output_config.effort"}, {"pattern": "([\"\\'`])web_search_20250305\\1", "flags": "", "message": "web_search_20250305 is the pre-2026 server-tool variant. On Opus 5/4.8/4.7/4.6, Sonnet 5 and Sonnet 4.6 use web_search_20260209. (Vertex AI still carries only the older variant.)", "sev": "warn", "fix": "Replace with web_search_20260209", "replace": "$1web_search_20260209$1"}, {"pattern": "([\"\\'`])web_fetch_20250910\\1", "flags": "", "message": "web_fetch_20250910 is the pre-2026 server-tool variant. On Opus 5/4.8/4.7/4.6, Sonnet 5 and Sonnet 4.6 use web_fetch_20260209.", "sev": "warn", "fix": "Replace with web_fetch_20260209", "replace": "$1web_fetch_20260209$1"}, {"pattern": "([\"\\'`])(files-api-2025-04-14|skills-2025-10-02)\\1", "flags": "", "message": "This beta header is obsolete - the Files API and Skills are out of beta. Remove the header and call client.files / client.skills.", "sev": "error", "fix": "Remove the beta header"}, {"pattern": "\\bclient\\.beta\\.(files|skills)\\b", "flags": "", "message": "client.beta.files / client.beta.skills changed shape when Files and Skills left beta. Use client.files / client.skills with no beta header.", "sev": "warn", "fix": "Use client.files / client.skills"}, {"pattern": "([\"\\'`])code_execution_tool_result\\1", "flags": "", "message": "code_execution_20260521 returns bash_code_execution_tool_result, not the bare code_execution_tool_result block. Matching the old type silently drops every result.", "sev": "warn", "fix": "Match bash_code_execution_tool_result"}, {"pattern": "\\boutput_format\\s*[=:]", "flags": "", "message": "The output_format parameter on the Anthropic Messages API is deprecated. Use output_config: {format: {...}}.", "sev": "info", "fix": "Use output_config.format"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-live\\-001\\1", "flags": "", "message": "gemini-2.0-flash-live-001: Google stopped answering on 9 December 2025 (2025-12-09). Move to a current Gemini Live model.", "fix": "Replace with a current Gemini Live model", "replace": "$1a current Gemini Live model$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-live\\-2\\.5\\-flash\\-preview\\1", "flags": "", "message": "gemini-live-2.5-flash-preview: Google stopped answering on 9 December 2025 (2025-12-09). Move to a current Gemini Live model.", "fix": "Replace with a current Gemini Live model", "replace": "$1a current Gemini Live model$1", "sev": "error"}, {"pattern": "([\"'`])text\\-embedding\\-004\\1", "flags": "", "message": "text-embedding-004: Google stopped answering on 14 January 2026 (2026-01-14). Move to a current Gemini embedding model.", "fix": "Replace with a current Gemini embedding model", "replace": "$1a current Gemini embedding model$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.5\\-flash\\-image\\-preview\\1", "flags": "", "message": "gemini-2.5-flash-image-preview: Google stopped answering on 15 January 2026 (2026-01-15). Move to gemini-3.1-flash-image.", "fix": "Replace with gemini-3.1-flash-image", "replace": "$1gemini-3.1-flash-image$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-3\\.1\\-flash\\-lite\\-preview\\1", "flags": "", "message": "gemini-3.1-flash-lite-preview: Google stopped answering on 25 May 2026 (2026-05-25). Move to gemini-3.1-flash-lite.", "fix": "Replace with gemini-3.1-flash-lite", "replace": "$1gemini-3.1-flash-lite$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\1", "flags": "", "message": "gemini-2.0-flash: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.5-flash.", "fix": "Replace with gemini-3.5-flash", "replace": "$1gemini-3.5-flash$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-001\\1", "flags": "", "message": "gemini-2.0-flash-001: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.5-flash.", "fix": "Replace with gemini-3.5-flash", "replace": "$1gemini-3.5-flash$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-lite\\1", "flags": "", "message": "gemini-2.0-flash-lite: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.1-flash-lite.", "fix": "Replace with gemini-3.1-flash-lite", "replace": "$1gemini-3.1-flash-lite$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-2\\.0\\-flash\\-lite\\-001\\1", "flags": "", "message": "gemini-2.0-flash-lite-001: Google stopped answering on 1 June 2026 (2026-06-01). Move to gemini-3.1-flash-lite.", "fix": "Replace with gemini-3.1-flash-lite", "replace": "$1gemini-3.1-flash-lite$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-3\\.1\\-flash\\-image\\-preview\\1", "flags": "", "message": "gemini-3.1-flash-image-preview: Google stopped answering on 25 June 2026 (2026-06-25). Move to gemini-3.1-flash-image.", "fix": "Replace with gemini-3.1-flash-image", "replace": "$1gemini-3.1-flash-image$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-3\\-pro\\-image\\-preview\\1", "flags": "", "message": "gemini-3-pro-image-preview: Google stopped answering on 25 June 2026 (2026-06-25). Move to gemini-3-pro-image.", "fix": "Replace with gemini-3-pro-image", "replace": "$1gemini-3-pro-image$1", "sev": "error"}, {"pattern": "([\"'`])veo\\-2\\.0\\-generate\\-001\\1", "flags": "", "message": "veo-2.0-generate-001: Google stopped answering on 30 June 2026 (2026-06-30). Move to veo-3.1-generate-preview.", "fix": "Replace with veo-3.1-generate-preview", "replace": "$1veo-3.1-generate-preview$1", "sev": "error"}, {"pattern": "([\"'`])veo\\-3\\.0\\-generate\\-001\\1", "flags": "", "message": "veo-3.0-generate-001: Google stopped answering on 30 June 2026 (2026-06-30). Move to veo-3.1-generate-preview.", "fix": "Replace with veo-3.1-generate-preview", "replace": "$1veo-3.1-generate-preview$1", "sev": "error"}, {"pattern": "([\"'`])veo\\-3\\.0\\-fast\\-generate\\-001\\1", "flags": "", "message": "veo-3.0-fast-generate-001: Google stopped answering on 30 June 2026 (2026-06-30). Move to veo-3.1-fast-generate-preview.", "fix": "Replace with veo-3.1-fast-generate-preview", "replace": "$1veo-3.1-fast-generate-preview$1", "sev": "error"}, {"pattern": "([\"'`])imagen\\-4\\.0\\-generate\\-001\\1", "flags": "", "message": "imagen-4.0-generate-001: Google stopped answering on 17 August 2026 (2026-08-17). Move to a current Imagen model.", "fix": "Replace with a current Imagen model", "replace": "$1a current Imagen model$1", "sev": "error"}, {"pattern": "([\"'`])imagen\\-4\\.0\\-ultra\\-generate\\-001\\1", "flags": "", "message": "imagen-4.0-ultra-generate-001: Google stopped answering on 17 August 2026 (2026-08-17). Move to a current Imagen model.", "fix": "Replace with a current Imagen model", "replace": "$1a current Imagen model$1", "sev": "error"}, {"pattern": "([\"'`])imagen\\-4\\.0\\-fast\\-generate\\-001\\1", "flags": "", "message": "imagen-4.0-fast-generate-001: Google stopped answering on 17 August 2026 (2026-08-17). Move to a current Imagen model.", "fix": "Replace with a current Imagen model", "replace": "$1a current Imagen model$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-robotics\\-er\\-1\\.6\\-preview\\1", "flags": "", "message": "gemini-robotics-er-1.6-preview: Google stopped answering on 31 August 2026 (2026-08-31). Move to gemini-robotics-er-2-preview.", "fix": "Replace with gemini-robotics-er-2-preview", "replace": "$1gemini-robotics-er-2-preview$1", "sev": "error"}, {"pattern": "([\"'`])gemini\\-omni\\-flash\\-preview\\1", "flags": "", "message": "gemini-omni-flash-preview: Google stops answering on 30 September 2026 (2026-09-30). Move to gemini-omni-1.1-flash.", "fix": "Replace with gemini-omni-1.1-flash", "replace": "$1gemini-omni-1.1-flash$1", "sev": "warn"}, {"pattern": "([\"\\'`])NoAutoUpgrade\\1", "flags": "", "message": "versionUpgradeOption NoAutoUpgrade means Azure will not move this deployment at retirement - inference starts returning 410 Gone on the retirement date instead. Use OnceCurrentVersionExpired unless you are pinning deliberately.", "sev": "warn", "fix": "OnceCurrentVersionExpired"}, {"pattern": "lifecycleStatus\\s*[=!]==?\\s*([\"\\'`])Deprecated\\1", "flags": "", "message": "In the Azure Models API, lifecycleStatus \"Deprecated\" means RETIRED (410 Gone). A model that still serves inference reports \"Deprecating\". Comparing against \"Deprecated\" inverts the check.", "sev": "error", "fix": "Check for \"Deprecating\", or compare deprecation.inference to today"}];
 
88
  </script>
89
  </html>
90
 
 
 
91
 
92
  <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://www.npmjs.com/package/@readystack/model-sunset-lint" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'model-sunset-lint',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://hub.docker.com/r/getreadystack/model-sunset-lint" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'model-sunset-lint',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">npx @readystack/model-sunset-lint &lt;file&gt;
93
+ docker run --rm -v &quot;$PWD:/w&quot; getreadystack/model-sunset-lint /w</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/cl/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
94
+ <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get one email when this rule changes</b><div style="opacity:.78;margin:.35rem 0 .8rem">We watch the regulation and vendor sources behind Model Sunset Lint - retired AI model IDs, dated every day. When a rule changes, you get a single email with what changed and the updated check. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Notify me</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">You're on the list. One email when it changes.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"model-sunset-lint",lang:"en",source:"rule_alert"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);})();</script></section>
95
+
96
+ <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">Finds every model ID and API parameter in your code that a vendor has already switched off or has published a date for - 109 rules across OpenAI, Anthropic, Google and Azure, each carrying t</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">A US software engineer averages $70.92/hour (ZipRecruiter, August 2026). $29 is about 25 minutes of that, once.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_L419KriWzJmPVgpnUDLnm67jUqWfQGdXNRqW43yeENB" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section>
97
+ <section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does Model Sunset Lint actually do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads the file you have open and flags every model ID, endpoint and API parameter that a vendor has already switched off or has published a shutdown date for. Each finding names the vendor, the date itself, and the exact replacement string. 109 rules ship inside, covering OpenAI, Anthropic, Google and Azure.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is this for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Engineers who own a shipped LLM feature - the person paged when a call starts returning 404 - and reviewers of code an AI assistant wrote. An assistant cannot know a retirement date set after it was trained, so it confidently emits IDs that stopped answering months ago. This catches them at edit time instead of in production.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just ask an AI, or wait for the 404?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">An assistant answers from training data, and a retirement calendar changes after training ends - that is exactly the fact it cannot have. Dependabot bumps package versions and never reads a string literal like &quot;gpt-4&quot;. Type checkers see a valid string. Nothing in the free toolchain carries a date, so the 404 in production is the alarm.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what needs a licence?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">The free tier checks the open file, or only the lines you select, against all 109 rules. No key, no watermark, no usage cap, and no finding is hidden. The licence covers a different job: sweeping the whole repository in one pass, rewriting the retired IDs in place, exporting the dated inventory, and CI output.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What would this cost me otherwise?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A US software engineer averages $70.92 an hour (ZipRecruiter, August 2026). Auditing one repository by hand means grepping every model string and checking it against four vendors’ deprecation pages, then repeating that each quarter. This is $29 once, one licence key per person or team seat.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Model Sunset Lint actually do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads the file you have open and flags every model ID, endpoint and API parameter that a vendor has already switched off or has published a shutdown date for. Each finding names the vendor, the date itself, and the exact replacement string. 109 rules ship inside, covering OpenAI, Anthropic, Google and Azure."}}, {"@type": "Question", "name": "Who is this for?", "acceptedAnswer": {"@type": "Answer", "text": "Engineers who own a shipped LLM feature - the person paged when a call starts returning 404 - and reviewers of code an AI assistant wrote. An assistant cannot know a retirement date set after it was trained, so it confidently emits IDs that stopped answering months ago. This catches them at edit time instead of in production."}}, {"@type": "Question", "name": "Why not just ask an AI, or wait for the 404?", "acceptedAnswer": {"@type": "Answer", "text": "An assistant answers from training data, and a retirement calendar changes after training ends - that is exactly the fact it cannot have. Dependabot bumps package versions and never reads a string literal like \"gpt-4\". Type checkers see a valid string. Nothing in the free toolchain carries a date, so the 404 in production is the alarm."}}, {"@type": "Question", "name": "What is free and what needs a licence?", "acceptedAnswer": {"@type": "Answer", "text": "The free tier checks the open file, or only the lines you select, against all 109 rules. No key, no watermark, no usage cap, and no finding is hidden. The licence covers a different job: sweeping the whole repository in one pass, rewriting the retired IDs in place, exporting the dated inventory, and CI output."}}, {"@type": "Question", "name": "What would this cost me otherwise?", "acceptedAnswer": {"@type": "Answer", "text": "A US software engineer averages $70.92 an hour (ZipRecruiter, August 2026). Auditing one repository by hand means grepping every model string and checking it against four vendors’ deprecation pages, then repeating that each quarter. This is $29 once, one licence key per person or team seat."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:0,slug:"model-sunset-lint",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/play-release-blocker-lint"><span class="yj-rel-t">Google Play Release Blocker Lint - target API 36, Billing 8, 16 KB</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/personal-data-map-dsar-audit"><span class="yj-rel-t">Personal Data Map: find every column a GDPR subject access request has to reac</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/en/p/heloc-calculator-for-homeowners-real-payment-payoff-rate-sho"><span class="yj-rel-t">HELOC Calculator for Homeowners: Real Payment, Payoff &amp; Rate-Shock (Google She</span><span class="yj-rel-p">$39</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/real-estate-icon-set"><span class="yj-rel-t">Real Estate Listing UI Kit — Property Status Badges, Amenity Chips &amp; Agent Car</span><span class="yj-rel-p">$168</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/webflow-restaurant-template"><span class="yj-rel-t">Webflow Restaurant Template — delivered as self-contained HTML you own: 26 pag</span><span class="yj-rel-p">$49</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/robots-txt-ai-crawler-audit"><span class="yj-rel-t">AI Crawler Rules - robots.txt Audit for AI Search</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section><!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div>
98
 
99
 
100
  <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>