@mariozechner/pi-ai 0.5.19 → 0.5.21

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/README.md CHANGED
@@ -28,7 +28,7 @@ import { createLLM } from '@mariozechner/pi-ai';
28
28
 
29
29
  const llm = createLLM('openai', 'gpt-4o-mini');
30
30
 
31
- const response = await llm.complete({
31
+ const response = await llm.generate({
32
32
  messages: [{ role: 'user', content: 'Hello!' }]
33
33
  });
34
34
 
@@ -48,7 +48,7 @@ import { readFileSync } from 'fs';
48
48
  const imageBuffer = readFileSync('image.png');
49
49
  const base64Image = imageBuffer.toString('base64');
50
50
 
51
- const response = await llm.complete({
51
+ const response = await llm.generate({
52
52
  messages: [{
53
53
  role: 'user',
54
54
  content: [
@@ -77,7 +77,7 @@ const tools = [{
77
77
  const messages = [];
78
78
  messages.push({ role: 'user', content: 'What is the weather in Paris?' });
79
79
 
80
- const response = await llm.complete({ messages, tools });
80
+ const response = await llm.generate({ messages, tools });
81
81
  messages.push(response);
82
82
 
83
83
  // Check for tool calls in the content blocks
@@ -99,7 +99,7 @@ for (const call of toolCalls) {
99
99
 
100
100
  if (toolCalls.length > 0) {
101
101
  // Continue conversation with tool results
102
- const followUp = await llm.complete({ messages, tools });
102
+ const followUp = await llm.generate({ messages, tools });
103
103
  messages.push(followUp);
104
104
 
105
105
  // Print text blocks from the response
@@ -114,7 +114,7 @@ if (toolCalls.length > 0) {
114
114
  ## Streaming
115
115
 
116
116
  ```typescript
117
- const response = await llm.complete({
117
+ const response = await llm.generate({
118
118
  messages: [{ role: 'user', content: 'Write a story' }]
119
119
  }, {
120
120
  onEvent: (event) => {
@@ -157,13 +157,17 @@ const response = await llm.complete({
157
157
 
158
158
  ## Abort Signal
159
159
 
160
+ The abort signal allows you to cancel in-progress requests. When aborted, providers return partial results accumulated up to the cancellation point, including accurate token counts and cost estimates.
161
+
162
+ ### Basic Usage
163
+
160
164
  ```typescript
161
165
  const controller = new AbortController();
162
166
 
163
167
  // Abort after 2 seconds
164
168
  setTimeout(() => controller.abort(), 2000);
165
169
 
166
- const response = await llm.complete({
170
+ const response = await llm.generate({
167
171
  messages: [{ role: 'user', content: 'Write a long story' }]
168
172
  }, {
169
173
  signal: controller.signal,
@@ -177,18 +181,132 @@ const response = await llm.complete({
177
181
  // Check if the request was aborted
178
182
  if (response.stopReason === 'error' && response.error) {
179
183
  console.log('Request was aborted:', response.error);
184
+ console.log('Partial content received:', response.content);
185
+ console.log('Tokens used:', response.usage);
180
186
  } else {
181
187
  console.log('Request completed successfully');
182
188
  }
183
189
  ```
184
190
 
191
+ ### Partial Results and Token Tracking
192
+
193
+ When a request is aborted, the API returns an `AssistantMessage` with:
194
+ - `stopReason: 'error'` - Indicates the request was aborted
195
+ - `error: string` - Error message describing the abort
196
+ - `content: array` - **Partial content** accumulated before the abort
197
+ - `usage: object` - **Token counts and costs** (may be incomplete depending on when abort occurred)
198
+
199
+ ```typescript
200
+ // Example: User interrupts a long-running request
201
+ const controller = new AbortController();
202
+ document.getElementById('stop-button').onclick = () => controller.abort();
203
+
204
+ const response = await llm.generate(context, {
205
+ signal: controller.signal,
206
+ onEvent: (e) => {
207
+ if (e.type === 'text_delta') updateUI(e.delta);
208
+ }
209
+ });
210
+
211
+ // Even if aborted, you get:
212
+ // - Partial text that was streamed
213
+ // - Token count (may be partial/estimated)
214
+ // - Cost calculations (may be incomplete)
215
+ console.log(`Generated ${response.content.length} content blocks`);
216
+ console.log(`Estimated ${response.usage.output} output tokens`);
217
+ console.log(`Estimated cost: $${response.usage.cost.total}`);
218
+ ```
219
+
220
+ ### Continuing After Abort
221
+
222
+ Aborted messages can be added to the conversation context and continued in subsequent requests:
223
+
224
+ ```typescript
225
+ const context = {
226
+ messages: [
227
+ { role: 'user', content: 'Explain quantum computing in detail' }
228
+ ]
229
+ };
230
+
231
+ // First request gets aborted after 2 seconds
232
+ const controller1 = new AbortController();
233
+ setTimeout(() => controller1.abort(), 2000);
234
+
235
+ const partial = await llm.generate(context, { signal: controller1.signal });
236
+
237
+ // Add the partial response to context
238
+ context.messages.push(partial);
239
+ context.messages.push({ role: 'user', content: 'Please continue' });
240
+
241
+ // Continue the conversation
242
+ const continuation = await llm.generate(context);
243
+ ```
244
+
245
+ When an aborted message (with `stopReason: 'error'`) is resubmitted in the context:
246
+ - **OpenAI Responses**: Filters out thinking blocks and tool calls from aborted messages, as API call will fail if incomplete thinking and tool calls are submitted
247
+ - **Anthropic, Google, OpenAI Completions**: Send all blocks as-is (text, thinking, tool calls)
248
+
249
+ ## Cross-Provider Handoffs
250
+
251
+ The library supports seamless handoffs between different LLM providers within the same conversation. This allows you to switch models mid-conversation while preserving context, including thinking blocks, tool calls, and tool results.
252
+
253
+ ### How It Works
254
+
255
+ When messages from one provider are sent to a different provider, the library automatically transforms them for compatibility:
256
+
257
+ - **User and tool result messages** are passed through unchanged
258
+ - **Assistant messages from the same provider/model** are preserved as-is
259
+ - **Assistant messages from different providers** have their thinking blocks converted to text with `<thinking>` tags
260
+ - **Tool calls and regular text** are preserved unchanged
261
+
262
+ ### Example: Multi-Provider Conversation
263
+
264
+ ```typescript
265
+ import { createLLM } from '@mariozechner/pi-ai';
266
+
267
+ // Start with Claude
268
+ const claude = createLLM('anthropic', 'claude-sonnet-4-0');
269
+ const messages = [];
270
+
271
+ messages.push({ role: 'user', content: 'What is 25 * 18?' });
272
+ const claudeResponse = await claude.generate({ messages }, {
273
+ thinking: { enabled: true }
274
+ });
275
+ messages.push(claudeResponse);
276
+
277
+ // Switch to GPT-5 - it will see Claude's thinking as <thinking> tagged text
278
+ const gpt5 = createLLM('openai', 'gpt-5-mini');
279
+ messages.push({ role: 'user', content: 'Is that calculation correct?' });
280
+ const gptResponse = await gpt5.generate({ messages });
281
+ messages.push(gptResponse);
282
+
283
+ // Switch to Gemini
284
+ const gemini = createLLM('google', 'gemini-2.5-flash');
285
+ messages.push({ role: 'user', content: 'What was the original question?' });
286
+ const geminiResponse = await gemini.generate({ messages });
287
+ ```
288
+
289
+ ### Provider Compatibility
290
+
291
+ All providers can handle messages from other providers, including:
292
+ - Text content
293
+ - Tool calls and tool results
294
+ - Thinking/reasoning blocks (transformed to tagged text for cross-provider compatibility)
295
+ - Aborted messages with partial content
296
+
297
+ This enables flexible workflows where you can:
298
+ - Start with a fast model for initial responses
299
+ - Switch to a more capable model for complex reasoning
300
+ - Use specialized models for specific tasks
301
+ - Maintain conversation continuity across provider outages
302
+
185
303
  ## Provider-Specific Options
186
304
 
187
305
  ### OpenAI Reasoning (o1, o3)
188
306
  ```typescript
189
307
  const llm = createLLM('openai', 'o1-mini');
190
308
 
191
- await llm.complete(context, {
309
+ await llm.generate(context, {
192
310
  reasoningEffort: 'medium' // 'minimal' | 'low' | 'medium' | 'high'
193
311
  });
194
312
  ```
@@ -197,7 +315,7 @@ await llm.complete(context, {
197
315
  ```typescript
198
316
  const llm = createLLM('anthropic', 'claude-3-5-sonnet-20241022');
199
317
 
200
- await llm.complete(context, {
318
+ await llm.generate(context, {
201
319
  thinking: {
202
320
  enabled: true,
203
321
  budgetTokens: 2048 // Optional thinking token limit
@@ -209,7 +327,7 @@ await llm.complete(context, {
209
327
  ```typescript
210
328
  const llm = createLLM('google', 'gemini-2.5-pro');
211
329
 
212
- await llm.complete(context, {
330
+ await llm.generate(context, {
213
331
  thinking: { enabled: true }
214
332
  });
215
333
  ```
@@ -1593,7 +1593,7 @@ export declare const PROVIDERS: {
1593
1593
  contextWindow: number;
1594
1594
  maxTokens: number;
1595
1595
  };
1596
- readonly "meta-llama/llama-3.1-70b-instruct": {
1596
+ readonly "meta-llama/llama-3.1-405b-instruct": {
1597
1597
  id: string;
1598
1598
  name: string;
1599
1599
  provider: string;
@@ -1609,7 +1609,7 @@ export declare const PROVIDERS: {
1609
1609
  contextWindow: number;
1610
1610
  maxTokens: number;
1611
1611
  };
1612
- readonly "meta-llama/llama-3.1-405b-instruct": {
1612
+ readonly "meta-llama/llama-3.1-70b-instruct": {
1613
1613
  id: string;
1614
1614
  name: string;
1615
1615
  provider: string;
@@ -1641,7 +1641,7 @@ export declare const PROVIDERS: {
1641
1641
  contextWindow: number;
1642
1642
  maxTokens: number;
1643
1643
  };
1644
- readonly "mistralai/mistral-7b-instruct-v0.3": {
1644
+ readonly "mistralai/mistral-7b-instruct:free": {
1645
1645
  id: string;
1646
1646
  name: string;
1647
1647
  provider: string;
@@ -1657,7 +1657,7 @@ export declare const PROVIDERS: {
1657
1657
  contextWindow: number;
1658
1658
  maxTokens: number;
1659
1659
  };
1660
- readonly "mistralai/mistral-7b-instruct:free": {
1660
+ readonly "mistralai/mistral-7b-instruct": {
1661
1661
  id: string;
1662
1662
  name: string;
1663
1663
  provider: string;
@@ -1673,7 +1673,7 @@ export declare const PROVIDERS: {
1673
1673
  contextWindow: number;
1674
1674
  maxTokens: number;
1675
1675
  };
1676
- readonly "mistralai/mistral-7b-instruct": {
1676
+ readonly "mistralai/mistral-7b-instruct-v0.3": {
1677
1677
  id: string;
1678
1678
  name: string;
1679
1679
  provider: string;
@@ -1721,7 +1721,7 @@ export declare const PROVIDERS: {
1721
1721
  contextWindow: number;
1722
1722
  maxTokens: number;
1723
1723
  };
1724
- readonly "meta-llama/llama-3-70b-instruct": {
1724
+ readonly "meta-llama/llama-3-8b-instruct": {
1725
1725
  id: string;
1726
1726
  name: string;
1727
1727
  provider: string;
@@ -1737,7 +1737,7 @@ export declare const PROVIDERS: {
1737
1737
  contextWindow: number;
1738
1738
  maxTokens: number;
1739
1739
  };
1740
- readonly "meta-llama/llama-3-8b-instruct": {
1740
+ readonly "meta-llama/llama-3-70b-instruct": {
1741
1741
  id: string;
1742
1742
  name: string;
1743
1743
  provider: string;
@@ -1849,7 +1849,7 @@ export declare const PROVIDERS: {
1849
1849
  contextWindow: number;
1850
1850
  maxTokens: number;
1851
1851
  };
1852
- readonly "mistralai/mistral-tiny": {
1852
+ readonly "mistralai/mistral-small": {
1853
1853
  id: string;
1854
1854
  name: string;
1855
1855
  provider: string;
@@ -1865,7 +1865,7 @@ export declare const PROVIDERS: {
1865
1865
  contextWindow: number;
1866
1866
  maxTokens: number;
1867
1867
  };
1868
- readonly "mistralai/mistral-small": {
1868
+ readonly "mistralai/mistral-tiny": {
1869
1869
  id: string;
1870
1870
  name: string;
1871
1871
  provider: string;
@@ -2468,7 +2468,7 @@ export declare const PROVIDERS: {
2468
2468
  contextWindow: number;
2469
2469
  maxTokens: number;
2470
2470
  };
2471
- readonly "gpt-4": {
2471
+ readonly "gpt-3.5-turbo": {
2472
2472
  id: string;
2473
2473
  name: string;
2474
2474
  provider: string;
@@ -2483,7 +2483,7 @@ export declare const PROVIDERS: {
2483
2483
  contextWindow: number;
2484
2484
  maxTokens: number;
2485
2485
  };
2486
- readonly "gpt-4-0314": {
2486
+ readonly "gpt-4": {
2487
2487
  id: string;
2488
2488
  name: string;
2489
2489
  provider: string;
@@ -2498,7 +2498,7 @@ export declare const PROVIDERS: {
2498
2498
  contextWindow: number;
2499
2499
  maxTokens: number;
2500
2500
  };
2501
- readonly "gpt-3.5-turbo": {
2501
+ readonly "gpt-4-0314": {
2502
2502
  id: string;
2503
2503
  name: string;
2504
2504
  provider: string;
@@ -2592,7 +2592,7 @@ export declare const PROVIDERS: {
2592
2592
  contextWindow: number;
2593
2593
  maxTokens: number;
2594
2594
  };
2595
- readonly "claude-3-5-haiku-20241022": {
2595
+ readonly "claude-3-5-haiku-latest": {
2596
2596
  id: string;
2597
2597
  name: string;
2598
2598
  provider: string;
@@ -2607,7 +2607,7 @@ export declare const PROVIDERS: {
2607
2607
  contextWindow: number;
2608
2608
  maxTokens: number;
2609
2609
  };
2610
- readonly "claude-3-5-haiku-latest": {
2610
+ readonly "claude-3-5-haiku-20241022": {
2611
2611
  id: string;
2612
2612
  name: string;
2613
2613
  provider: string;
@@ -1595,36 +1595,36 @@ export const PROVIDERS = {
1595
1595
  contextWindow: 131072,
1596
1596
  maxTokens: 16384,
1597
1597
  },
1598
- "meta-llama/llama-3.1-70b-instruct": {
1599
- id: "meta-llama/llama-3.1-70b-instruct",
1600
- name: "Meta: Llama 3.1 70B Instruct",
1598
+ "meta-llama/llama-3.1-405b-instruct": {
1599
+ id: "meta-llama/llama-3.1-405b-instruct",
1600
+ name: "Meta: Llama 3.1 405B Instruct",
1601
1601
  provider: "openrouter",
1602
1602
  baseUrl: "https://openrouter.ai/api/v1",
1603
1603
  reasoning: false,
1604
1604
  input: ["text"],
1605
1605
  cost: {
1606
- input: 0.09999999999999999,
1607
- output: 0.28,
1606
+ input: 0.7999999999999999,
1607
+ output: 0.7999999999999999,
1608
1608
  cacheRead: 0,
1609
1609
  cacheWrite: 0,
1610
1610
  },
1611
- contextWindow: 131072,
1611
+ contextWindow: 32768,
1612
1612
  maxTokens: 16384,
1613
1613
  },
1614
- "meta-llama/llama-3.1-405b-instruct": {
1615
- id: "meta-llama/llama-3.1-405b-instruct",
1616
- name: "Meta: Llama 3.1 405B Instruct",
1614
+ "meta-llama/llama-3.1-70b-instruct": {
1615
+ id: "meta-llama/llama-3.1-70b-instruct",
1616
+ name: "Meta: Llama 3.1 70B Instruct",
1617
1617
  provider: "openrouter",
1618
1618
  baseUrl: "https://openrouter.ai/api/v1",
1619
1619
  reasoning: false,
1620
1620
  input: ["text"],
1621
1621
  cost: {
1622
- input: 0.7999999999999999,
1623
- output: 0.7999999999999999,
1622
+ input: 0.09999999999999999,
1623
+ output: 0.28,
1624
1624
  cacheRead: 0,
1625
1625
  cacheWrite: 0,
1626
1626
  },
1627
- contextWindow: 32768,
1627
+ contextWindow: 131072,
1628
1628
  maxTokens: 16384,
1629
1629
  },
1630
1630
  "mistralai/mistral-nemo": {
@@ -1643,41 +1643,41 @@ export const PROVIDERS = {
1643
1643
  contextWindow: 32000,
1644
1644
  maxTokens: 4096,
1645
1645
  },
1646
- "mistralai/mistral-7b-instruct-v0.3": {
1647
- id: "mistralai/mistral-7b-instruct-v0.3",
1648
- name: "Mistral: Mistral 7B Instruct v0.3",
1646
+ "mistralai/mistral-7b-instruct:free": {
1647
+ id: "mistralai/mistral-7b-instruct:free",
1648
+ name: "Mistral: Mistral 7B Instruct (free)",
1649
1649
  provider: "openrouter",
1650
1650
  baseUrl: "https://openrouter.ai/api/v1",
1651
1651
  reasoning: false,
1652
1652
  input: ["text"],
1653
1653
  cost: {
1654
- input: 0.028,
1655
- output: 0.054,
1654
+ input: 0,
1655
+ output: 0,
1656
1656
  cacheRead: 0,
1657
1657
  cacheWrite: 0,
1658
1658
  },
1659
1659
  contextWindow: 32768,
1660
1660
  maxTokens: 16384,
1661
1661
  },
1662
- "mistralai/mistral-7b-instruct:free": {
1663
- id: "mistralai/mistral-7b-instruct:free",
1664
- name: "Mistral: Mistral 7B Instruct (free)",
1662
+ "mistralai/mistral-7b-instruct": {
1663
+ id: "mistralai/mistral-7b-instruct",
1664
+ name: "Mistral: Mistral 7B Instruct",
1665
1665
  provider: "openrouter",
1666
1666
  baseUrl: "https://openrouter.ai/api/v1",
1667
1667
  reasoning: false,
1668
1668
  input: ["text"],
1669
1669
  cost: {
1670
- input: 0,
1671
- output: 0,
1670
+ input: 0.028,
1671
+ output: 0.054,
1672
1672
  cacheRead: 0,
1673
1673
  cacheWrite: 0,
1674
1674
  },
1675
1675
  contextWindow: 32768,
1676
1676
  maxTokens: 16384,
1677
1677
  },
1678
- "mistralai/mistral-7b-instruct": {
1679
- id: "mistralai/mistral-7b-instruct",
1680
- name: "Mistral: Mistral 7B Instruct",
1678
+ "mistralai/mistral-7b-instruct-v0.3": {
1679
+ id: "mistralai/mistral-7b-instruct-v0.3",
1680
+ name: "Mistral: Mistral 7B Instruct v0.3",
1681
1681
  provider: "openrouter",
1682
1682
  baseUrl: "https://openrouter.ai/api/v1",
1683
1683
  reasoning: false,
@@ -1723,32 +1723,32 @@ export const PROVIDERS = {
1723
1723
  contextWindow: 128000,
1724
1724
  maxTokens: 4096,
1725
1725
  },
1726
- "meta-llama/llama-3-70b-instruct": {
1727
- id: "meta-llama/llama-3-70b-instruct",
1728
- name: "Meta: Llama 3 70B Instruct",
1726
+ "meta-llama/llama-3-8b-instruct": {
1727
+ id: "meta-llama/llama-3-8b-instruct",
1728
+ name: "Meta: Llama 3 8B Instruct",
1729
1729
  provider: "openrouter",
1730
1730
  baseUrl: "https://openrouter.ai/api/v1",
1731
1731
  reasoning: false,
1732
1732
  input: ["text"],
1733
1733
  cost: {
1734
- input: 0.3,
1735
- output: 0.39999999999999997,
1734
+ input: 0.03,
1735
+ output: 0.06,
1736
1736
  cacheRead: 0,
1737
1737
  cacheWrite: 0,
1738
1738
  },
1739
1739
  contextWindow: 8192,
1740
1740
  maxTokens: 16384,
1741
1741
  },
1742
- "meta-llama/llama-3-8b-instruct": {
1743
- id: "meta-llama/llama-3-8b-instruct",
1744
- name: "Meta: Llama 3 8B Instruct",
1742
+ "meta-llama/llama-3-70b-instruct": {
1743
+ id: "meta-llama/llama-3-70b-instruct",
1744
+ name: "Meta: Llama 3 70B Instruct",
1745
1745
  provider: "openrouter",
1746
1746
  baseUrl: "https://openrouter.ai/api/v1",
1747
1747
  reasoning: false,
1748
1748
  input: ["text"],
1749
1749
  cost: {
1750
- input: 0.03,
1751
- output: 0.06,
1750
+ input: 0.3,
1751
+ output: 0.39999999999999997,
1752
1752
  cacheRead: 0,
1753
1753
  cacheWrite: 0,
1754
1754
  },
@@ -1851,32 +1851,32 @@ export const PROVIDERS = {
1851
1851
  contextWindow: 128000,
1852
1852
  maxTokens: 4096,
1853
1853
  },
1854
- "mistralai/mistral-tiny": {
1855
- id: "mistralai/mistral-tiny",
1856
- name: "Mistral Tiny",
1854
+ "mistralai/mistral-small": {
1855
+ id: "mistralai/mistral-small",
1856
+ name: "Mistral Small",
1857
1857
  provider: "openrouter",
1858
1858
  baseUrl: "https://openrouter.ai/api/v1",
1859
1859
  reasoning: false,
1860
1860
  input: ["text"],
1861
1861
  cost: {
1862
- input: 0.25,
1863
- output: 0.25,
1862
+ input: 0.19999999999999998,
1863
+ output: 0.6,
1864
1864
  cacheRead: 0,
1865
1865
  cacheWrite: 0,
1866
1866
  },
1867
1867
  contextWindow: 32768,
1868
1868
  maxTokens: 4096,
1869
1869
  },
1870
- "mistralai/mistral-small": {
1871
- id: "mistralai/mistral-small",
1872
- name: "Mistral Small",
1870
+ "mistralai/mistral-tiny": {
1871
+ id: "mistralai/mistral-tiny",
1872
+ name: "Mistral Tiny",
1873
1873
  provider: "openrouter",
1874
1874
  baseUrl: "https://openrouter.ai/api/v1",
1875
1875
  reasoning: false,
1876
1876
  input: ["text"],
1877
1877
  cost: {
1878
- input: 0.19999999999999998,
1879
- output: 0.6,
1878
+ input: 0.25,
1879
+ output: 0.25,
1880
1880
  cacheRead: 0,
1881
1881
  cacheWrite: 0,
1882
1882
  },
@@ -2470,24 +2470,24 @@ export const PROVIDERS = {
2470
2470
  contextWindow: 16385,
2471
2471
  maxTokens: 4096,
2472
2472
  },
2473
- "gpt-4": {
2474
- id: "gpt-4",
2475
- name: "OpenAI: GPT-4",
2473
+ "gpt-3.5-turbo": {
2474
+ id: "gpt-3.5-turbo",
2475
+ name: "OpenAI: GPT-3.5 Turbo",
2476
2476
  provider: "openai",
2477
2477
  reasoning: false,
2478
2478
  input: ["text"],
2479
2479
  cost: {
2480
- input: 30,
2481
- output: 60,
2480
+ input: 0.5,
2481
+ output: 1.5,
2482
2482
  cacheRead: 0,
2483
2483
  cacheWrite: 0,
2484
2484
  },
2485
- contextWindow: 8191,
2485
+ contextWindow: 16385,
2486
2486
  maxTokens: 4096,
2487
2487
  },
2488
- "gpt-4-0314": {
2489
- id: "gpt-4-0314",
2490
- name: "OpenAI: GPT-4 (older v0314)",
2488
+ "gpt-4": {
2489
+ id: "gpt-4",
2490
+ name: "OpenAI: GPT-4",
2491
2491
  provider: "openai",
2492
2492
  reasoning: false,
2493
2493
  input: ["text"],
@@ -2500,19 +2500,19 @@ export const PROVIDERS = {
2500
2500
  contextWindow: 8191,
2501
2501
  maxTokens: 4096,
2502
2502
  },
2503
- "gpt-3.5-turbo": {
2504
- id: "gpt-3.5-turbo",
2505
- name: "OpenAI: GPT-3.5 Turbo",
2503
+ "gpt-4-0314": {
2504
+ id: "gpt-4-0314",
2505
+ name: "OpenAI: GPT-4 (older v0314)",
2506
2506
  provider: "openai",
2507
2507
  reasoning: false,
2508
2508
  input: ["text"],
2509
2509
  cost: {
2510
- input: 0.5,
2511
- output: 1.5,
2510
+ input: 30,
2511
+ output: 60,
2512
2512
  cacheRead: 0,
2513
2513
  cacheWrite: 0,
2514
2514
  },
2515
- contextWindow: 16385,
2515
+ contextWindow: 8191,
2516
2516
  maxTokens: 4096,
2517
2517
  },
2518
2518
  }
@@ -2594,9 +2594,9 @@ export const PROVIDERS = {
2594
2594
  contextWindow: 200000,
2595
2595
  maxTokens: 64000,
2596
2596
  },
2597
- "claude-3-5-haiku-20241022": {
2598
- id: "claude-3-5-haiku-20241022",
2599
- name: "Anthropic: Claude 3.5 Haiku (2024-10-22)",
2597
+ "claude-3-5-haiku-latest": {
2598
+ id: "claude-3-5-haiku-latest",
2599
+ name: "Anthropic: Claude 3.5 Haiku",
2600
2600
  provider: "anthropic",
2601
2601
  reasoning: false,
2602
2602
  input: ["text", "image"],
@@ -2609,9 +2609,9 @@ export const PROVIDERS = {
2609
2609
  contextWindow: 200000,
2610
2610
  maxTokens: 8192,
2611
2611
  },
2612
- "claude-3-5-haiku-latest": {
2613
- id: "claude-3-5-haiku-latest",
2614
- name: "Anthropic: Claude 3.5 Haiku",
2612
+ "claude-3-5-haiku-20241022": {
2613
+ id: "claude-3-5-haiku-20241022",
2614
+ name: "Anthropic: Claude 3.5 Haiku (2024-10-22)",
2615
2615
  provider: "anthropic",
2616
2616
  reasoning: false,
2617
2617
  input: ["text", "image"],