parche-cli 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  Todas las versiones de `parche-cli` (npm) y de la Action `Pepo08/parche@v0`.
4
4
 
5
+ ## 0.6.3 — 2026-10-18
6
+
7
+ Pack de IA con el resto de la página de deprecaciones de OpenAI (verificada fila por fila el 18/10): los modelos que se apagan desde 2026. Como siempre, Parche avisa con la fecha y el reemplazo oficial, y no cambia el modelo.
8
+
9
+ ### Nuevo
10
+ - **Lo que viene:**
11
+ - 1/12/2026: `gpt-image-1-mini`, `gpt-image-1.5` y `chatgpt-image-latest` (reemplazo `gpt-image-2.5-sunburst` o `gpt-image-2.5-flare`).
12
+ - 6/1/2027: voz con `tts-1`, `tts-1-hd` y los snapshots `gpt-4o-mini-tts-2025-03-20` y `-2025-12-15` (`gpt-realtime-2.1-mini`).
13
+ - 14/1/2027: los snapshots `gpt-4o-2024-08-06`, `gpt-4o-2024-11-20`, `gpt-4o-mini-2024-07-18`, `gpt-4.1-2025-04-14` y `gpt-4.1-mini-2025-04-14` (`gpt-6-luna`), y sus modelos fine-tuned (`ft:…`), que se apagan con su modelo base. Los alias `gpt-4o`, `gpt-4o-mini`, `gpt-4.1` y `gpt-4.1-mini` no figuran en la página y no se avisan; un fine-tuned sobre el alias se avisa solo cuando ese alias tiene un único snapshot (no es el caso de `gpt-4o`).
14
+ - 20/1/2027: las familias `gpt-realtime`, `gpt-realtime-mini`, `gpt-audio` y `gpt-audio-mini` (alias y snapshots) y `gpt-4o-mini-transcribe-2025-03-20`.
15
+ - 26/2/2027: transcripción con `whisper-1`, `gpt-4o-transcribe`, `gpt-4o-mini-transcribe` y `gpt-4o-transcribe-diarize` (`gpt-live-transcribe` o `gpt-transcribe`). El aviso de `whisper-1` dice además que `/v1/audio/translations` cierra ese día.
16
+ - 1/4/2027: `gpt-5.1`, `gpt-5.3-codex` (`gpt-6-sol`) y `gpt-5.4-nano` (`gpt-6-luna`).
17
+ - **Lo que ya se apagó y faltaba:** 23/7/2026 (`computer-use-preview`, los `*-search-preview-2025-03-11`, `gpt-5-chat-latest`, `gpt-5.1-chat-latest`, los `gpt-5*-codex`, `o3-deep-research`, `o4-mini-deep-research` y los snapshots `-2025-10-06` de `gpt-audio-mini` y `gpt-realtime-mini`), 10/8 (`gpt-5.2-chat-latest`, `gpt-5.3-chat-latest`), 24/9 (Sora 2: `sora-2`, `sora-2-pro` y sus snapshots, sin reemplazo), 1/10 (`gpt-5.4-cyber`), 7/5 (`gpt-4o-mini-realtime-preview`, `gpt-4o-audio-preview`, `gpt-4o-mini-audio-preview`), 26/3 (`gpt-4-turbo-preview-completions`) y el header `OpenAI-Beta: realtime=v1` de la Realtime API Beta (12/5).
18
+ - El inventario reconoce como modelos de OpenAI `gpt-realtime*`, `gpt-audio*`, `gpt-6*`, `sora-2*`, `computer-use-preview*` y `o4-mini-deep-research`.
19
+
20
+ ### Todavía no cubre
21
+ - Los productos que OpenAI cierra y no son modelos: prompts reutilizables (`v1/prompts`, 30/11/2026), la plataforma de Evals (solo lectura el 31/10, cierre el 30/11/2026), Agent Builder (30/11/2026) y la Videos API (cerrada el 24/9/2026; sí se avisan los modelos `sora-2`).
22
+ - Las familias `gpt-4o-audio`, `gpt-4o-realtime`, `gpt-4o-mini-realtime` y `gpt-4o-mini-audio` (20/1/2027): la página no dice qué IDs siguen activos (sus alias `-preview` se apagaron el 7/5/2026).
23
+ - Los snapshots de un alias que la página nombra sin ellos (por ejemplo `gpt-5.1-2025-11-13`, `gpt-5.4-nano-2026-03-17`) y lo que OpenAI apagó antes de 2026.
24
+
25
+ ## 0.6.2 — 2026-10-18
26
+
27
+ Pack de IA completo para el apagado de OpenAI del **23/10/2026** (sección "2026-04-22: Legacy GPT model snapshots" de la página oficial, verificada el 18/10).
28
+
29
+ ### Nuevo
30
+ - **Alias `-completions`:** `gpt-3.5-turbo-completions` (reemplazo `gpt-5.6-terra`), `gpt-4-completions`, `gpt-4-0613-completions` y `gpt-4-turbo-completions` (reemplazo `gpt-5.6-sol`).
31
+ - **Modelos fine-tuned:** se avisan los IDs reales (`ft:<modelo base>:<org>:<sufijo>:<id>`, también con `:ckpt-step-…`) de las familias que OpenAI apaga: `ft-gpt-3.5-turbo` y `ft-babbage-002`, `ft-davinci-002` y `ft-o4-mini-2025-04-16` (base de reemplazo `gpt-5.6-terra`), `ft-gpt-4` (`gpt-5.6-sol`) y `ft-gpt-4.1-nano-2025-04-14` (`gpt-5.6-luna`). Se compara el modelo base entero: `ft:gpt-4o-mini-…`, `ft:gpt-4o-…` y `ft:gpt-4.1-…` no son de `gpt-4` y no se avisan (OpenAI los apaga en otra fecha). Como siempre, Parche avisa y no cambia el modelo.
32
+ - El pack cita la guía de fine-tuning de OpenAI como fuente del formato de los IDs. `last_verified`: 2026-10-18 (Anthropic y el resto de OpenAI, revisados contra sus páginas ese día: sin cambios).
33
+
5
34
  ## 0.6.1 — 2026-10-18
6
35
 
7
36
  Lo que encontró el frente de tracción al preparar los PRs con la 0.6.0.
package/README.md CHANGED
@@ -131,7 +131,7 @@ Con el tag, el workflow corre los tests, controla que la versión de `package.js
131
131
  |---|---|---|---|---|
132
132
  | `arca.wsfe.condicion-iva-receptor` | ARCA | rompe | 2026-12-01 | sí, en JS (`afip.js`) y PHP (`afipsdk/afip.php` y forks): consumidor final y DNI B/C; con `DocTipo` en una variable, consumidor final al ejecutarse (PR parcial) |
133
133
  | `mercadopago.payments-to-orders` | Mercado Pago | migración | — | sí (creación de pagos en SDK Node v2) |
134
- | `ai.model-retirements` | Anthropic, OpenAI | retiro | varias | solo detección |
134
+ | `ai.model-retirements` | Anthropic, OpenAI | retiro | varias | solo detección (también modelos fine-tuned de OpenAI, `ft:…`). De OpenAI, los modelos que su página de deprecaciones apaga desde 2026: texto, código, imagen, video, voz, transcripción y realtime |
135
135
 
136
136
  ## Verificación
137
137
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parche-cli",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Dependabot para APIs: detecta cambios de APIs de terceros en tu código y abre el PR con el arreglo.",
5
5
  "keywords": [
6
6
  "api",
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "id": "ai.model-retirements",
3
- "version": "2026.10.16",
3
+ "version": "2026.10.18",
4
4
  "provider": "Modelos de IA",
5
5
  "title": "Modelos y endpoints de IA retirados o por retirarse",
6
6
  "kind": "retirement",
7
7
  "severity": "high",
8
8
  "deadline": null,
9
- "last_verified": "2026-10-16",
9
+ "last_verified": "2026-10-18",
10
10
  "summary_es": "Tu código usa modelos o APIs de IA que ya no responden o tienen fecha de retiro.",
11
11
  "why_es": "Los proveedores de modelos retiran IDs de modelo y endpoints con algunas semanas o meses de aviso. Después de la fecha, las llamadas fallan. Parche no reemplaza el modelo automáticamente porque cambiar de modelo cambia el comportamiento: te avisa, te dice la fecha y el reemplazo que recomienda el proveedor.",
12
12
  "sources": [
13
13
  { "title": "Anthropic: Model deprecations", "url": "https://platform.claude.com/docs/en/about-claude/model-deprecations" },
14
- { "title": "OpenAI: Deprecations", "url": "https://developers.openai.com/api/docs/deprecations" }
14
+ { "title": "OpenAI: Deprecations", "url": "https://developers.openai.com/api/docs/deprecations" },
15
+ { "title": "OpenAI: Supervised fine-tuning (formato de los IDs ft:)", "url": "https://developers.openai.com/api/docs/guides/supervised-fine-tuning" },
16
+ { "title": "OpenAI: Models (snapshots de cada familia y de cada modelo base)", "url": "https://developers.openai.com/api/docs/models" }
15
17
  ],
16
18
  "detect": {
17
19
  "packages": ["@anthropic-ai/sdk", "openai"],
@@ -37,19 +39,51 @@
37
39
  "claude-1.1": { "date": "2024-11-06", "replacement": "claude-haiku-4-5-20251001" },
38
40
  "claude-1.0": { "date": "2024-11-06", "replacement": "claude-haiku-4-5-20251001" },
39
41
 
42
+ "gpt-5.1": { "date": "2027-04-01", "replacement": "gpt-6-sol" },
43
+ "gpt-5.3-codex": { "date": "2027-04-01", "replacement": "gpt-6-sol" },
44
+ "gpt-5.4-nano": { "date": "2027-04-01", "replacement": "gpt-6-luna" },
45
+ "whisper-1": { "date": "2027-02-26", "replacement": "gpt-live-transcribe o gpt-transcribe", "note_es": "Si lo usás para traducir (/v1/audio/translations), ese endpoint cierra el mismo día y el reemplazo es v1/realtime/translations." },
46
+ "gpt-4o-transcribe": { "date": "2027-02-26", "replacement": "gpt-live-transcribe o gpt-transcribe" },
47
+ "gpt-4o-mini-transcribe": { "date": "2027-02-26", "replacement": "gpt-live-transcribe o gpt-transcribe" },
48
+ "gpt-4o-transcribe-diarize": { "date": "2027-02-26", "replacement": "gpt-live-transcribe o gpt-transcribe" },
49
+ "gpt-realtime": { "date": "2027-01-20", "replacement": "gpt-realtime-2.1" },
50
+ "gpt-realtime-2025-08-28": { "date": "2027-01-20", "replacement": "gpt-realtime-2.1" },
51
+ "gpt-realtime-mini": { "date": "2027-01-20", "replacement": "gpt-realtime-2.1-mini" },
52
+ "gpt-realtime-mini-2025-12-15": { "date": "2027-01-20", "replacement": "gpt-realtime-2.1-mini" },
53
+ "gpt-audio": { "date": "2027-01-20", "replacement": "gpt-audio-1.5" },
54
+ "gpt-audio-2025-08-28": { "date": "2027-01-20", "replacement": "gpt-audio-1.5" },
55
+ "gpt-audio-mini": { "date": "2027-01-20", "replacement": "gpt-audio-1.5" },
56
+ "gpt-audio-mini-2025-12-15": { "date": "2027-01-20", "replacement": "gpt-audio-1.5" },
57
+ "gpt-4o-mini-transcribe-2025-03-20": { "date": "2027-01-20", "replacement": "gpt-4o-mini-transcribe-2025-12-15" },
58
+ "gpt-4o-2024-08-06": { "date": "2027-01-14", "replacement": "gpt-6-luna" },
59
+ "gpt-4o-2024-11-20": { "date": "2027-01-14", "replacement": "gpt-6-luna" },
60
+ "gpt-4o-mini-2024-07-18": { "date": "2027-01-14", "replacement": "gpt-6-luna" },
61
+ "gpt-4.1-2025-04-14": { "date": "2027-01-14", "replacement": "gpt-6-luna" },
62
+ "gpt-4.1-mini-2025-04-14": { "date": "2027-01-14", "replacement": "gpt-6-luna" },
63
+ "tts-1": { "date": "2027-01-06", "replacement": "gpt-realtime-2.1-mini" },
64
+ "tts-1-hd": { "date": "2027-01-06", "replacement": "gpt-realtime-2.1-mini" },
65
+ "gpt-4o-mini-tts-2025-03-20": { "date": "2027-01-06", "replacement": "gpt-realtime-2.1-mini" },
66
+ "gpt-4o-mini-tts-2025-12-15": { "date": "2027-01-06", "replacement": "gpt-realtime-2.1-mini" },
40
67
  "gpt-5-2025-08-07": { "date": "2026-12-11", "replacement": "gpt-5.6-sol" },
41
68
  "gpt-5-mini-2025-08-07": { "date": "2026-12-11", "replacement": "gpt-5.6-terra" },
42
69
  "gpt-5-nano-2025-08-07": { "date": "2026-12-11", "replacement": "gpt-5.6-luna" },
43
70
  "gpt-5-pro-2025-10-06": { "date": "2026-12-11", "replacement": "gpt-5.6-sol (reasoning.mode: pro)" },
44
71
  "o3-2025-04-16": { "date": "2026-12-11", "replacement": "gpt-5.6-sol" },
45
72
  "o3-pro-2025-06-10": { "date": "2026-12-11", "replacement": "gpt-5.6-sol (reasoning.mode: pro)" },
73
+ "gpt-image-1-mini": { "date": "2026-12-01", "replacement": "gpt-image-2.5-sunburst o gpt-image-2.5-flare" },
74
+ "gpt-image-1.5": { "date": "2026-12-01", "replacement": "gpt-image-2.5-sunburst o gpt-image-2.5-flare" },
75
+ "chatgpt-image-latest": { "date": "2026-12-01", "replacement": "gpt-image-2.5-sunburst o gpt-image-2.5-flare" },
46
76
  "gpt-3.5-turbo": { "date": "2026-10-23", "replacement": "gpt-5.6-terra" },
47
77
  "gpt-3.5-turbo-0125": { "date": "2026-10-23", "replacement": "gpt-5.6-terra" },
78
+ "gpt-3.5-turbo-completions": { "date": "2026-10-23", "replacement": "gpt-5.6-terra" },
48
79
  "gpt-4": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
49
80
  "gpt-4-0613": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
81
+ "gpt-4-completions": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
82
+ "gpt-4-0613-completions": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
50
83
  "gpt-4-1106-preview": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
51
84
  "gpt-4-turbo": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
52
85
  "gpt-4-turbo-2024-04-09": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
86
+ "gpt-4-turbo-completions": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
53
87
  "gpt-4.1-nano": { "date": "2026-10-23", "replacement": "gpt-5.6-luna" },
54
88
  "gpt-4.1-nano-2025-04-14": { "date": "2026-10-23", "replacement": "gpt-5.6-luna" },
55
89
  "gpt-4o-2024-05-13": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
@@ -62,29 +96,71 @@
62
96
  "o3-mini-2025-01-31": { "date": "2026-10-23", "replacement": "gpt-5.6-sol" },
63
97
  "o4-mini": { "date": "2026-10-23", "replacement": "gpt-5.6-terra" },
64
98
  "o4-mini-2025-04-16": { "date": "2026-10-23", "replacement": "gpt-5.6-terra" },
99
+ "gpt-5.4-cyber": { "date": "2026-10-01", "replacement_es": "el modelo cyber más capaz al que tengas acceso" },
65
100
  "gpt-3.5-turbo-instruct": { "date": "2026-09-28", "replacement": "gpt-5.6-terra" },
66
101
  "gpt-3.5-turbo-1106": { "date": "2026-09-28", "replacement": "gpt-5.6-terra" },
67
102
  "babbage-002": { "date": "2026-09-28", "replacement": "gpt-5.6-terra" },
68
103
  "davinci-002": { "date": "2026-09-28", "replacement": "gpt-5.6-terra" },
104
+ "sora-2": { "date": "2026-09-24", "note_es": "OpenAI no indica reemplazo y ese día también cerró la Videos API." },
105
+ "sora-2-pro": { "date": "2026-09-24", "note_es": "OpenAI no indica reemplazo y ese día también cerró la Videos API." },
106
+ "sora-2-2025-10-06": { "date": "2026-09-24", "note_es": "OpenAI no indica reemplazo y ese día también cerró la Videos API." },
107
+ "sora-2-2025-12-08": { "date": "2026-09-24", "note_es": "OpenAI no indica reemplazo y ese día también cerró la Videos API." },
108
+ "sora-2-pro-2025-10-06": { "date": "2026-09-24", "note_es": "OpenAI no indica reemplazo y ese día también cerró la Videos API." },
109
+ "gpt-5.2-chat-latest": { "date": "2026-08-10", "replacement": "gpt-5.6-sol" },
110
+ "gpt-5.3-chat-latest": { "date": "2026-08-10", "replacement": "gpt-5.6-sol" },
111
+ "computer-use-preview": { "date": "2026-07-23", "replacement": "gpt-5.6-terra" },
112
+ "computer-use-preview-2025-03-11": { "date": "2026-07-23", "replacement": "gpt-5.6-terra" },
113
+ "gpt-4o-mini-search-preview-2025-03-11": { "date": "2026-07-23", "replacement": "gpt-5.6-terra" },
114
+ "gpt-4o-search-preview-2025-03-11": { "date": "2026-07-23", "replacement": "gpt-5.6-terra" },
115
+ "gpt-5-chat-latest": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
116
+ "gpt-5-codex": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
117
+ "gpt-5.1-chat-latest": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
118
+ "gpt-5.1-codex": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
119
+ "gpt-5.1-codex-max": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
120
+ "gpt-5.1-codex-mini": { "date": "2026-07-23", "replacement": "gpt-5.6-terra" },
121
+ "gpt-5.2-codex": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
122
+ "gpt-audio-mini-2025-10-06": { "date": "2026-07-23", "replacement": "gpt-audio-1.5" },
123
+ "gpt-realtime-mini-2025-10-06": { "date": "2026-07-23", "replacement": "gpt-realtime-2.1-mini" },
124
+ "o3-deep-research": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
125
+ "o3-deep-research-2025-06-26": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
126
+ "o4-mini-deep-research": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
127
+ "o4-mini-deep-research-2025-06-26": { "date": "2026-07-23", "replacement": "gpt-5.6-sol" },
69
128
  "dall-e-3": { "date": "2026-05-12", "replacement": "gpt-image-2, gpt-image-1 o gpt-image-1-mini" },
70
129
  "dall-e-2": { "date": "2026-05-12", "replacement": "gpt-image-2, gpt-image-1 o gpt-image-1-mini" },
71
130
  "gpt-4o-realtime-preview": { "date": "2026-05-07", "replacement": "gpt-realtime-1.5" },
72
131
  "gpt-4o-realtime-preview-2025-06-03": { "date": "2026-05-07", "replacement": "gpt-realtime-1.5" },
73
132
  "gpt-4o-realtime-preview-2024-12-17": { "date": "2026-05-07", "replacement": "gpt-realtime-1.5" },
133
+ "gpt-4o-mini-realtime-preview": { "date": "2026-05-07", "replacement": "gpt-realtime-mini" },
134
+ "gpt-4o-audio-preview": { "date": "2026-05-07", "replacement": "gpt-audio-1.5" },
135
+ "gpt-4o-mini-audio-preview": { "date": "2026-05-07", "replacement": "gpt-audio-mini" },
74
136
  "gpt-4-0314": { "date": "2026-03-26", "replacement": "gpt-5 o gpt-4.1" },
75
137
  "gpt-4-0125-preview": { "date": "2026-03-26", "replacement": "gpt-5 o gpt-4.1" },
76
138
  "gpt-4-turbo-preview": { "date": "2026-03-26", "replacement": "gpt-5 o gpt-4.1" },
139
+ "gpt-4-turbo-preview-completions": { "date": "2026-03-26", "replacement": "gpt-5 o gpt-4.1" },
77
140
  "chatgpt-4o-latest": { "date": "2026-02-17", "replacement": "gpt-5.1-chat-latest" },
78
141
  "codex-mini-latest": { "date": "2026-02-12", "replacement": "gpt-5-codex-mini" }
79
142
  },
143
+ "retired_fine_tunes": {
144
+ "ft-gpt-4o": { "date": "2027-01-14", "replacement": "gpt-6-luna", "bases": ["gpt-4o-2024-08-06", "gpt-4o-2024-11-20"] },
145
+ "ft-gpt-4o-mini": { "date": "2027-01-14", "replacement": "gpt-6-luna", "bases": ["gpt-4o-mini-2024-07-18", "gpt-4o-mini"] },
146
+ "ft-gpt-4.1": { "date": "2027-01-14", "replacement": "gpt-6-luna", "bases": ["gpt-4.1-2025-04-14", "gpt-4.1"] },
147
+ "ft-gpt-4.1-mini": { "date": "2027-01-14", "replacement": "gpt-6-luna", "bases": ["gpt-4.1-mini-2025-04-14", "gpt-4.1-mini"] },
148
+ "ft-gpt-3.5-turbo": { "date": "2026-10-23", "replacement": "gpt-5.6-terra", "bases": ["gpt-3.5-turbo", "gpt-3.5-turbo-0125", "gpt-3.5-turbo-1106", "gpt-3.5-turbo-0613"] },
149
+ "ft-gpt-4": { "date": "2026-10-23", "replacement": "gpt-5.6-sol", "bases": ["gpt-4", "gpt-4-0613"] },
150
+ "ft-gpt-4.1-nano-2025-04-14": { "date": "2026-10-23", "replacement": "gpt-5.6-luna", "bases": ["gpt-4.1-nano-2025-04-14", "gpt-4.1-nano"] },
151
+ "ft-o4-mini-2025-04-16": { "date": "2026-10-23", "replacement": "gpt-5.6-terra", "bases": ["o4-mini-2025-04-16", "o4-mini"] },
152
+ "ft-babbage-002": { "date": "2026-10-23", "replacement": "gpt-5.6-terra", "bases": ["babbage-002"] },
153
+ "ft-davinci-002": { "date": "2026-10-23", "replacement": "gpt-5.6-terra", "bases": ["davinci-002"] }
154
+ },
80
155
  "retirement_floors": {
81
156
  "claude-haiku-4-5-20251001": "2026-10-15",
82
157
  "claude-opus-4-5-20251101": "2026-11-24"
83
158
  },
84
159
  "retired_endpoints": [
85
- { "pattern": ".beta.assistants", "retired": "2026-08-26", "replacement_es": "Responses API + Conversations API", "provider": "openai" },
86
- { "pattern": ".beta.threads", "retired": "2026-08-26", "replacement_es": "Responses API + Conversations API", "provider": "openai" },
87
- { "pattern": "/v1/assistants", "retired": "2026-08-26", "replacement_es": "Responses API + Conversations API", "provider": "openai" }
160
+ { "pattern": ".beta.assistants", "retired": "2026-08-26", "api_es": "Assistants API", "replacement_es": "Responses API + Conversations API", "provider": "openai" },
161
+ { "pattern": ".beta.threads", "retired": "2026-08-26", "api_es": "Assistants API", "replacement_es": "Responses API + Conversations API", "provider": "openai" },
162
+ { "pattern": "/v1/assistants", "retired": "2026-08-26", "api_es": "Assistants API", "replacement_es": "Responses API + Conversations API", "provider": "openai" },
163
+ { "pattern": "realtime=v1", "retired": "2026-05-12", "api_es": "Realtime API Beta", "replacement_es": "la Realtime API (GA)", "provider": "openai" }
88
164
  ]
89
165
  },
90
166
  "codemod": null,
@@ -8,15 +8,25 @@ const PACK = 'ai.model-retirements';
8
8
 
9
9
  const MODEL_CONTEXT = /\bmodel(?:Id|Name)?\b\s*[:=(]|["']model["']\s*[:=]|\b(?:DEFAULT|default)_?(?:MODEL|Model)\b|\bmodel\s*\(/i;
10
10
  const AZURE = /azure|AzureOpenAI|openai\.azure\.com/i;
11
+ // Modelos fine-tuned de OpenAI: el ID real es `ft:<modelo base>:<org>:<sufijo>:<id>` (guía de fine-tuning).
12
+ // Se compara el modelo base entero, hasta el `:`, contra `bases` del pack: nunca un prefijo, porque
13
+ // `ft:gpt-4o-mini-2024-07-18:...` no es un fine-tuned de `gpt-4` y se apaga en otra fecha.
14
+ const FINE_TUNE = /["'`]ft:([\w.-]+):/g;
11
15
 
12
- // Acepta el formato nuevo ({ date, replacement }) y el viejo (solo la fecha).
16
+ // Acepta el formato nuevo ({ date, replacement }) y el viejo (solo la fecha). `replacement` es un ID de modelo
17
+ // y va entre backticks; `replacement_es` es un reemplazo que el proveedor da en prosa ("el modelo cyber más
18
+ // capaz al que tengas acceso"); `note_es` es una oración más, para lo que la página dice además de la fecha.
13
19
  const entry = (v) => (typeof v === 'string' ? { date: v, replacement: null } : v);
14
20
  const quoted = (line, id) => line.includes(`'${id}'`) || line.includes(`"${id}"`) || line.includes(`\`${id}\``);
21
+ const replacementText = ({ replacement, replacement_es: prose, note_es: note }) =>
22
+ (replacement ? ` Reemplazo recomendado: \`${replacement}\`.` : prose ? ` Reemplazo recomendado: ${prose}.` : '') + (note ? ` ${note}` : '');
15
23
 
16
24
  export default function detect({ source, file, pack, today = new Date().toISOString().slice(0, 10) }) {
17
25
  const findings = [];
18
26
  const usages = [];
19
27
  const { retired_models: retired, retirement_floors: floors, retired_endpoints: endpoints } = pack.detect;
28
+ const fineTunes = new Map();
29
+ for (const [name, e] of Object.entries(pack.detect.retired_fine_tunes || {})) for (const b of e.bases) fineTunes.set(b, { name, ...e });
20
30
  const azure = AZURE.test(source);
21
31
  const lines = source.split('\n');
22
32
  lines.forEach((l, i) => {
@@ -24,9 +34,10 @@ export default function detect({ source, file, pack, today = new Date().toISOStr
24
34
  const inCall = MODEL_CONTEXT.test(l);
25
35
  for (const [model, raw] of Object.entries(retired)) {
26
36
  if (!quoted(l, model)) continue;
27
- const { date, replacement } = entry(raw);
37
+ const e = entry(raw);
38
+ const { date } = e;
28
39
  const past = date <= today;
29
- const repl = replacement ? ` Reemplazo recomendado: \`${replacement}\`.` : '';
40
+ const repl = replacementText(e);
30
41
  const when = past ? `fue retirado el ${date}` : `se retira el ${date}`;
31
42
  const message = inCall
32
43
  ? `El modelo \`${model}\` ${when}${past ? ': las llamadas ya fallan' : ''}.${repl} Corré tus pruebas de prompts antes de cambiarlo.`
@@ -34,6 +45,18 @@ export default function detect({ source, file, pack, today = new Date().toISOStr
34
45
  findings.push({ pack: PACK, file, line, status: 'detect-only', message });
35
46
  usages.push({ provider: 'ia', op: `modelo ${model}`, line });
36
47
  }
48
+ for (const [, base] of l.matchAll(FINE_TUNE)) {
49
+ const ft = fineTunes.get(base);
50
+ if (!ft) continue;
51
+ const past = ft.date <= today;
52
+ const when = past ? `fue retirado el ${ft.date}` : `se retira el ${ft.date}`;
53
+ const repl = `OpenAI recomienda como modelo base de reemplazo \`${ft.replacement}\`; el modelo fine-tuned no se migra solo.`;
54
+ const message = inCall
55
+ ? `El modelo fine-tuned sobre \`${base}\` (\`${ft.name}\`) ${when}${past ? ': las llamadas ya fallan' : ''}. ${repl} Corré tus pruebas de prompts antes de cambiarlo.`
56
+ : `Aparece un modelo fine-tuned sobre \`${base}\` (\`${ft.name}\`, ${when}) fuera de una llamada: si es una lista o un catálogo de modelos, actualizalo. ${repl}`;
57
+ findings.push({ pack: PACK, file, line, status: 'detect-only', message });
58
+ usages.push({ provider: 'ia', op: `modelo fine-tuned ${base}`, line });
59
+ }
37
60
  for (const [model, date] of Object.entries(floors)) {
38
61
  if (!l.includes(model)) continue;
39
62
  findings.push({ pack: PACK, file, line, status: 'detect-only',
@@ -42,10 +65,11 @@ export default function detect({ source, file, pack, today = new Date().toISOStr
42
65
  }
43
66
  for (const ep of endpoints) {
44
67
  if (!l.includes(ep.pattern)) continue;
68
+ const closed = ep.retired <= today ? `cerrada el ${ep.retired}` : `que cierra el ${ep.retired}`;
45
69
  findings.push({ pack: PACK, file, line, status: 'detect-only', message: azure && ep.provider === 'openai'
46
- ? `\`${ep.pattern}\` es la Assistants API. En Azure OpenAI sigue su propio calendario (el cierre del ${ep.retired} es el de la API de OpenAI): revisá el de Azure.`
47
- : `\`${ep.pattern}\` pertenece a la Assistants API de OpenAI, cerrada el ${ep.retired}. Reemplazo: ${ep.replacement_es}.` });
48
- usages.push({ provider: 'ia', op: 'OpenAI Assistants API', line });
70
+ ? `\`${ep.pattern}\` es la ${ep.api_es}. En Azure OpenAI sigue su propio calendario (el cierre del ${ep.retired} es el de la API de OpenAI): revisá el de Azure.`
71
+ : `\`${ep.pattern}\` pertenece a la ${ep.api_es} de OpenAI, ${closed}. Reemplazo: ${ep.replacement_es}.` });
72
+ usages.push({ provider: 'ia', op: `OpenAI ${ep.api_es}`, line });
49
73
  }
50
74
  });
51
75
  return { output: null, findings, usages };
@@ -10,10 +10,11 @@ const HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'
10
10
  const FETCH_PACKAGES = new Set(['node-fetch', 'cross-fetch', 'isomorphic-fetch', 'undici']);
11
11
  const SKIP_KEYS = new Set(['loc', 'start', 'end', 'extra', 'range', 'comments', 'leadingComments', 'trailingComments', 'innerComments', 'tokens']);
12
12
 
13
- // IDs de modelos de IA. Prefijos inequívocos; la serie o1/o3/o4 de OpenAI solo cuenta si el archivo usa OpenAI.
13
+ // IDs de modelos de IA. Prefijos inequívocos; la serie o1/o3/o4, Sora y computer-use de OpenAI solo cuentan si
14
+ // el archivo usa OpenAI.
14
15
  const MODEL_PATTERNS = [
15
- [/^(gpt-(3\.5|4|4\.1|4o|4\.5|5)[\w.-]*|chatgpt-[\w.-]+|text-embedding-[\w-]+|dall-e-[23]|whisper-1|tts-1(-hd)?|gpt-image-[\w.-]+)$/, 'OpenAI'],
16
- [/^o[1-9](-(mini|pro|preview|deep-research))?(-\d{4}-\d{2}-\d{2})?$/, 'OpenAI', { needs: 'openai' }],
16
+ [/^(gpt-(3\.5|4|4\.1|4o|4\.5|5|6|realtime|audio)[\w.-]*|chatgpt-[\w.-]+|text-embedding-[\w-]+|dall-e-[23]|whisper-1|tts-1(-hd)?|gpt-image-[\w.-]+)$/, 'OpenAI'],
17
+ [/^(o[1-9](-(mini|pro|preview))?(-deep-research)?(-\d{4}-\d{2}-\d{2})?|sora-2[\w.-]*|computer-use-preview[\w.-]*)$/, 'OpenAI', { needs: 'openai' }],
17
18
  [/^claude-[\w.-]+$/, 'Anthropic'],
18
19
  [/^(gemini|gemma)-[\w.-]+$/, 'Google (Gemini)'],
19
20
  [/^(mistral|mixtral|codestral|pixtral|ministral)-[\w.-]+$/, 'Mistral'],