190proof 1.0.87 → 1.0.89

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
@@ -1,6 +1,6 @@
1
1
  # 190proof
2
2
 
3
- A unified interface for interacting with multiple AI providers including **OpenAI**, **Anthropic**, **Google**, **Groq**, and **AWS Bedrock**. This package provides a consistent API for making requests to different LLM providers while handling retries, streaming, and multimodal inputs.
3
+ A unified interface for interacting with multiple AI providers including **OpenAI**, **Anthropic**, **Google**, **Groq**, **OpenRouter**, and **AWS Bedrock**. This package provides a consistent API for making requests to different LLM providers while handling retries, streaming, and multimodal inputs.
4
4
 
5
5
  ## Features
6
6
 
@@ -12,6 +12,7 @@ Fully-local unified interface across multiple AI providers that includes:
12
12
  - 🔄 Automatic retries with configurable attempts
13
13
  - 📡 Streaming by default
14
14
  - ☁️ Cloud service providers supported (Azure, AWS Bedrock)
15
+ - 🔌 Provider prefix strings for any model without waiting for package updates
15
16
 
16
17
  ## Installation
17
18
 
@@ -23,12 +24,13 @@ npm install 190proof
23
24
 
24
25
  ### Basic Example
25
26
 
27
+ Use any model from any provider with the `provider:model-id` format:
28
+
26
29
  ```typescript
27
- import { callWithRetries } from "190proof";
28
- import { GPTModel, GenericPayload } from "190proof/interfaces";
30
+ import { callWithRetries, GenericPayload } from "190proof";
29
31
 
30
32
  const payload: GenericPayload = {
31
- model: GPTModel.GPT4O_MINI,
33
+ model: "openai:gpt-4o-mini",
32
34
  messages: [
33
35
  {
34
36
  role: "user",
@@ -44,29 +46,35 @@ console.log(response.content);
44
46
  ### Using Different Providers
45
47
 
46
48
  ```typescript
47
- import { callWithRetries } from "190proof";
48
- import {
49
- ClaudeModel,
50
- GeminiModel,
51
- GroqModel,
52
- GenericPayload,
53
- } from "190proof/interfaces";
49
+ import { callWithRetries, GenericPayload } from "190proof";
50
+
51
+ // OpenAI
52
+ const openaiPayload: GenericPayload = {
53
+ model: "openai:gpt-5",
54
+ messages: [{ role: "user", content: "Hello!" }],
55
+ };
54
56
 
55
57
  // Anthropic
56
58
  const claudePayload: GenericPayload = {
57
- model: ClaudeModel.SONNET_4,
59
+ model: "anthropic:claude-sonnet-4-5",
58
60
  messages: [{ role: "user", content: "Hello!" }],
59
61
  };
60
62
 
61
63
  // Google
62
64
  const geminiPayload: GenericPayload = {
63
- model: GeminiModel.GEMINI_2_0_FLASH,
65
+ model: "google:gemini-2.0-flash",
64
66
  messages: [{ role: "user", content: "Hello!" }],
65
67
  };
66
68
 
67
69
  // Groq
68
70
  const groqPayload: GenericPayload = {
69
- model: GroqModel.LLAMA_3_70B_8192,
71
+ model: "groq:llama-3.3-70b-versatile",
72
+ messages: [{ role: "user", content: "Hello!" }],
73
+ };
74
+
75
+ // OpenRouter
76
+ const openRouterPayload: GenericPayload = {
77
+ model: "openrouter:google/gemma-4-31b-it:free",
70
78
  messages: [{ role: "user", content: "Hello!" }],
71
79
  };
72
80
 
@@ -77,7 +85,7 @@ const response = await callWithRetries("request-id", claudePayload);
77
85
 
78
86
  ```typescript
79
87
  const payload: GenericPayload = {
80
- model: GPTModel.GPT4O,
88
+ model: "openai:gpt-4o",
81
89
  messages: [
82
90
  {
83
91
  role: "user",
@@ -110,7 +118,7 @@ const response = await callWithRetries("function-call-example", payload);
110
118
 
111
119
  ```typescript
112
120
  const payload: GenericPayload = {
113
- model: ClaudeModel.SONNET_4,
121
+ model: "anthropic:claude-sonnet-4-5",
114
122
  messages: [
115
123
  {
116
124
  role: "user",
@@ -132,7 +140,7 @@ const response = await callWithRetries("image-example", payload);
132
140
 
133
141
  ```typescript
134
142
  const payload: GenericPayload = {
135
- model: GeminiModel.GEMINI_2_0_FLASH,
143
+ model: "google:gemini-2.0-flash",
136
144
  messages: [
137
145
  {
138
146
  role: "system",
@@ -148,57 +156,83 @@ const payload: GenericPayload = {
148
156
  const response = await callWithRetries("system-message-example", payload);
149
157
  ```
150
158
 
159
+ ### Inspecting Model Routing
160
+
161
+ Use `parseModelString` to see how a model string will be routed:
162
+
163
+ ```typescript
164
+ import { parseModelString } from "190proof";
165
+
166
+ parseModelString("openai:gpt-7");
167
+ // → { provider: "openai", modelId: "gpt-7" }
168
+
169
+ parseModelString("openrouter:org/model-name:free");
170
+ // → { provider: "openrouter", modelId: "org/model-name:free" }
171
+
172
+ ```
173
+
174
+ ## Provider Prefix Format
175
+
176
+ The model string format is `provider:model-id`, where the provider prefix is one of:
177
+
178
+ | Prefix | Provider |
179
+ |---|---|
180
+ | `openai` | OpenAI |
181
+ | `anthropic` | Anthropic |
182
+ | `google` | Google (Gemini) |
183
+ | `groq` | Groq |
184
+ | `openrouter` | OpenRouter |
185
+
186
+ The prefix is stripped before sending to the API, so the model ID should be exactly what the provider expects (e.g. `"openai:gpt-4o"` sends `"gpt-4o"` to OpenAI).
187
+
151
188
  ## Supported Models
152
189
 
153
- ### OpenAI Models
154
-
155
- - `gpt-3.5-turbo-0613`
156
- - `gpt-3.5-turbo-16k-0613`
157
- - `gpt-3.5-turbo-0125`
158
- - `gpt-4-1106-preview`
159
- - `gpt-4-0125-preview`
160
- - `gpt-4-turbo-2024-04-09`
161
- - `gpt-4o`
162
- - `gpt-4o-mini`
163
- - `o1-preview`
164
- - `o1-mini`
165
- - `o3-mini`
166
- - `gpt-4.1`
167
- - `gpt-4.1-mini`
168
- - `gpt-4.1-nano`
169
- - `gpt-5`
170
- - `gpt-5-mini`
171
-
172
- ### Anthropic Models
173
-
174
- - `claude-3-haiku-20240307`
175
- - `claude-3-sonnet-20240229`
176
- - `claude-3-opus-20240229`
177
- - `claude-3-5-haiku-20241022`
178
- - `claude-3-5-sonnet-20241022`
179
- - `claude-sonnet-4-20250514`
180
- - `claude-opus-4-20250514`
181
- - `claude-opus-4-1`
182
- - `claude-haiku-4-5`
183
- - `claude-sonnet-4-5`
184
- - `claude-opus-4-5`
185
-
186
- ### Google Models
187
-
188
- - `gemini-1.5-pro-latest`
189
- - `gemini-exp-1206`
190
- - `gemini-2.0-flash`
191
- - `gemini-2.0-flash-exp-image-generation`
192
- - `gemini-2.0-flash-thinking-exp`
193
- - `gemini-2.0-flash-thinking-exp-01-21`
194
- - `gemini-2.5-flash-preview-04-17`
195
- - `gemini-3-flash-preview`
196
- - `gemini-3.1-flash-lite-preview`
197
-
198
- ### Groq Models
199
-
200
- - `llama3-70b-8192`
201
- - `deepseek-r1-distill-llama-70b`
190
+ These models are tested. You can use any model with the `provider:model-id` format.
191
+
192
+ ### OpenAI
193
+
194
+ - `openai:gpt-5`
195
+ - `openai:gpt-5-mini`
196
+ - `openai:gpt-4.1`
197
+ - `openai:gpt-4.1-mini`
198
+ - `openai:gpt-4.1-nano`
199
+ - `openai:gpt-4o`
200
+ - `openai:gpt-4o-mini`
201
+ - `openai:o3-mini`
202
+ - `openai:o1-preview`
203
+ - `openai:o1-mini`
204
+
205
+ ### Anthropic
206
+
207
+ - `anthropic:claude-opus-4-5`
208
+ - `anthropic:claude-sonnet-4-5`
209
+ - `anthropic:claude-haiku-4-5`
210
+ - `anthropic:claude-opus-4-1`
211
+ - `anthropic:claude-opus-4-20250514`
212
+ - `anthropic:claude-sonnet-4-20250514`
213
+ - `anthropic:claude-3-5-sonnet-20241022`
214
+ - `anthropic:claude-3-5-haiku-20241022`
215
+
216
+ ### Google
217
+
218
+ - `google:gemini-3.1-flash-lite-preview`
219
+ - `google:gemini-3-flash-preview`
220
+ - `google:gemini-2.5-flash-preview-04-17`
221
+ - `google:gemini-2.0-flash`
222
+ - `google:gemini-2.0-flash-exp-image-generation`
223
+ - `google:gemini-1.5-pro-latest`
224
+
225
+ ### Groq
226
+
227
+ - `groq:llama-3.3-70b-versatile`
228
+ - `groq:llama3-70b-8192`
229
+ - `groq:qwen/qwen3-32b`
230
+ - `groq:deepseek-r1-distill-llama-70b`
231
+
232
+ ### OpenRouter
233
+
234
+ - `openrouter:google/gemma-4-31b-it:free`
235
+ - `openrouter:google/gemma-4-31b-it`
202
236
 
203
237
  ## Environment Variables
204
238
 
@@ -217,6 +251,9 @@ GEMINI_API_KEY=your-gemini-api-key
217
251
  # Groq
218
252
  GROQ_API_KEY=your-groq-api-key
219
253
 
254
+ # OpenRouter
255
+ OPENROUTER_API_KEY=your-openrouter-api-key
256
+
220
257
  # AWS Bedrock (for Anthropic via Bedrock)
221
258
  AWS_ACCESS_KEY_ID=your-aws-access-key
222
259
  AWS_SECRET_ACCESS_KEY=your-aws-secret-key
@@ -255,6 +292,18 @@ interface ParsedResponseMessage {
255
292
  }
256
293
  ```
257
294
 
295
+ ### `parseModelString(model)`
296
+
297
+ Parses a model string into its provider and model ID components.
298
+
299
+ #### Parameters
300
+
301
+ - `model`: `string` - A model string in `"provider:model-id"` format
302
+
303
+ #### Returns
304
+
305
+ `{ provider: Provider, modelId: string }`
306
+
258
307
  ### Configuration Options
259
308
 
260
309
  #### OpenAI Config
@@ -266,7 +315,7 @@ interface OpenAIConfig {
266
315
  baseUrl: string;
267
316
  orgId?: string;
268
317
  modelConfigMap?: Record<
269
- GPTModel,
318
+ string,
270
319
  {
271
320
  resource: string;
272
321
  deployment: string;
package/dist/index.d.mts CHANGED
@@ -1,3 +1,4 @@
1
+ /** @deprecated Use provider prefix strings instead, e.g. `"anthropic:claude-sonnet-4-5"` */
1
2
  declare enum ClaudeModel {
2
3
  HAIKU_3 = "claude-3-haiku-20240307",
3
4
  SONNET_3 = "claude-3-sonnet-20240229",
@@ -11,6 +12,7 @@ declare enum ClaudeModel {
11
12
  SONNET_4_5 = "claude-sonnet-4-5",
12
13
  OPUS_4_5 = "claude-opus-4-5"
13
14
  }
15
+ /** @deprecated Use provider prefix strings instead, e.g. `"openai:gpt-4o"` */
14
16
  declare enum GPTModel {
15
17
  GPT35_0613 = "gpt-3.5-turbo-0613",
16
18
  GPT35_0613_16K = "gpt-3.5-turbo-16k-0613",
@@ -29,12 +31,19 @@ declare enum GPTModel {
29
31
  GPT5 = "gpt-5",
30
32
  GPT5_MINI = "gpt-5-mini"
31
33
  }
34
+ /** @deprecated Use provider prefix strings instead, e.g. `"groq:llama-3.3-70b-versatile"` */
32
35
  declare enum GroqModel {
33
36
  LLAMA_3_70B_8192 = "llama3-70b-8192",
34
37
  LLAMA_3_3_70B_VERSATILE = "llama-3.3-70b-versatile",
35
38
  QWEN3_32B = "qwen/qwen3-32b",
36
39
  DEEPSEEK_R1_DISTILL_LLAMA_70B = "deepseek-r1-distill-llama-70b"
37
40
  }
41
+ /** @deprecated Use provider prefix strings instead, e.g. `"openrouter:qwen/qwen3.6-plus:free"` */
42
+ declare enum OpenRouterModel {
43
+ GEMMA_4_31B_IT_FREE = "google/gemma-4-31b-it:free",
44
+ GEMMA_4_31B_IT = "google/gemma-4-31b-it"
45
+ }
46
+ /** @deprecated Use provider prefix strings instead, e.g. `"google:gemini-2.0-flash"` */
38
47
  declare enum GeminiModel {
39
48
  GEMINI_1_5_PRO = "gemini-1.5-pro-latest",
40
49
  GEMINI_EXP_1206 = "gemini-exp-1206",
@@ -99,7 +108,8 @@ interface FunctionDefinition {
99
108
  description?: string;
100
109
  parameters: Record<string, any>;
101
110
  }
102
- type AnyModel = GPTModel | ClaudeModel | GroqModel | GeminiModel;
111
+ type Provider = "openai" | "anthropic" | "google" | "groq" | "openrouter";
112
+ type AnyModel = GPTModel | ClaudeModel | GroqModel | GeminiModel | OpenRouterModel | (string & {});
103
113
  interface GenericPayload {
104
114
  model: AnyModel;
105
115
  messages: GenericMessage[];
@@ -111,6 +121,10 @@ interface GenericPayload {
111
121
  fallbackModel?: AnyModel;
112
122
  }
113
123
 
124
+ declare function parseModelString(model: string): {
125
+ provider: Provider;
126
+ modelId: string;
127
+ };
114
128
  declare function callWithRetries(id: string | string[], aiPayload: GenericPayload, aiConfig?: OpenAIConfig | AnthropicAIConfig, retries?: number, chunkTimeoutMs?: number): Promise<ParsedResponseMessage>;
115
129
 
116
- export { type AnyModel, ClaudeModel, type FunctionDefinition, GPTModel, GeminiModel, type GenericMessage, type GenericPayload, GroqModel, type OpenAIConfig, callWithRetries };
130
+ export { type AnyModel, ClaudeModel, type FunctionDefinition, GPTModel, GeminiModel, type GenericMessage, type GenericPayload, GroqModel, type OpenAIConfig, OpenRouterModel, type Provider, callWithRetries, parseModelString };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /** @deprecated Use provider prefix strings instead, e.g. `"anthropic:claude-sonnet-4-5"` */
1
2
  declare enum ClaudeModel {
2
3
  HAIKU_3 = "claude-3-haiku-20240307",
3
4
  SONNET_3 = "claude-3-sonnet-20240229",
@@ -11,6 +12,7 @@ declare enum ClaudeModel {
11
12
  SONNET_4_5 = "claude-sonnet-4-5",
12
13
  OPUS_4_5 = "claude-opus-4-5"
13
14
  }
15
+ /** @deprecated Use provider prefix strings instead, e.g. `"openai:gpt-4o"` */
14
16
  declare enum GPTModel {
15
17
  GPT35_0613 = "gpt-3.5-turbo-0613",
16
18
  GPT35_0613_16K = "gpt-3.5-turbo-16k-0613",
@@ -29,12 +31,19 @@ declare enum GPTModel {
29
31
  GPT5 = "gpt-5",
30
32
  GPT5_MINI = "gpt-5-mini"
31
33
  }
34
+ /** @deprecated Use provider prefix strings instead, e.g. `"groq:llama-3.3-70b-versatile"` */
32
35
  declare enum GroqModel {
33
36
  LLAMA_3_70B_8192 = "llama3-70b-8192",
34
37
  LLAMA_3_3_70B_VERSATILE = "llama-3.3-70b-versatile",
35
38
  QWEN3_32B = "qwen/qwen3-32b",
36
39
  DEEPSEEK_R1_DISTILL_LLAMA_70B = "deepseek-r1-distill-llama-70b"
37
40
  }
41
+ /** @deprecated Use provider prefix strings instead, e.g. `"openrouter:qwen/qwen3.6-plus:free"` */
42
+ declare enum OpenRouterModel {
43
+ GEMMA_4_31B_IT_FREE = "google/gemma-4-31b-it:free",
44
+ GEMMA_4_31B_IT = "google/gemma-4-31b-it"
45
+ }
46
+ /** @deprecated Use provider prefix strings instead, e.g. `"google:gemini-2.0-flash"` */
38
47
  declare enum GeminiModel {
39
48
  GEMINI_1_5_PRO = "gemini-1.5-pro-latest",
40
49
  GEMINI_EXP_1206 = "gemini-exp-1206",
@@ -99,7 +108,8 @@ interface FunctionDefinition {
99
108
  description?: string;
100
109
  parameters: Record<string, any>;
101
110
  }
102
- type AnyModel = GPTModel | ClaudeModel | GroqModel | GeminiModel;
111
+ type Provider = "openai" | "anthropic" | "google" | "groq" | "openrouter";
112
+ type AnyModel = GPTModel | ClaudeModel | GroqModel | GeminiModel | OpenRouterModel | (string & {});
103
113
  interface GenericPayload {
104
114
  model: AnyModel;
105
115
  messages: GenericMessage[];
@@ -111,6 +121,10 @@ interface GenericPayload {
111
121
  fallbackModel?: AnyModel;
112
122
  }
113
123
 
124
+ declare function parseModelString(model: string): {
125
+ provider: Provider;
126
+ modelId: string;
127
+ };
114
128
  declare function callWithRetries(id: string | string[], aiPayload: GenericPayload, aiConfig?: OpenAIConfig | AnthropicAIConfig, retries?: number, chunkTimeoutMs?: number): Promise<ParsedResponseMessage>;
115
129
 
116
- export { type AnyModel, ClaudeModel, type FunctionDefinition, GPTModel, GeminiModel, type GenericMessage, type GenericPayload, GroqModel, type OpenAIConfig, callWithRetries };
130
+ export { type AnyModel, ClaudeModel, type FunctionDefinition, GPTModel, GeminiModel, type GenericMessage, type GenericPayload, GroqModel, type OpenAIConfig, OpenRouterModel, type Provider, callWithRetries, parseModelString };
package/dist/index.js CHANGED
@@ -34,7 +34,9 @@ __export(proof_exports, {
34
34
  GPTModel: () => GPTModel,
35
35
  GeminiModel: () => GeminiModel,
36
36
  GroqModel: () => GroqModel,
37
- callWithRetries: () => callWithRetries
37
+ OpenRouterModel: () => OpenRouterModel,
38
+ callWithRetries: () => callWithRetries,
39
+ parseModelString: () => parseModelString
38
40
  });
39
41
  module.exports = __toCommonJS(proof_exports);
40
42
 
@@ -79,6 +81,11 @@ var GroqModel = /* @__PURE__ */ ((GroqModel2) => {
79
81
  GroqModel2["DEEPSEEK_R1_DISTILL_LLAMA_70B"] = "deepseek-r1-distill-llama-70b";
80
82
  return GroqModel2;
81
83
  })(GroqModel || {});
84
+ var OpenRouterModel = /* @__PURE__ */ ((OpenRouterModel2) => {
85
+ OpenRouterModel2["GEMMA_4_31B_IT_FREE"] = "google/gemma-4-31b-it:free";
86
+ OpenRouterModel2["GEMMA_4_31B_IT"] = "google/gemma-4-31b-it";
87
+ return OpenRouterModel2;
88
+ })(OpenRouterModel || {});
82
89
  var GeminiModel = /* @__PURE__ */ ((GeminiModel2) => {
83
90
  GeminiModel2["GEMINI_1_5_PRO"] = "gemini-1.5-pro-latest";
84
91
  GeminiModel2["GEMINI_EXP_1206"] = "gemini-exp-1206";
@@ -498,7 +505,8 @@ async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries =
498
505
  openAiConfig == null ? void 0 : openAiConfig.service,
499
506
  openAiPayload.model
500
507
  );
501
- const useStreaming = openAiPayload.model !== "o1-mini" /* O1_MINI */ && openAiPayload.model !== "o1-preview" /* O1_PREVIEW */;
508
+ const modelStr = openAiPayload.model;
509
+ const useStreaming = modelStr !== "o1-mini" /* O1_MINI */ && modelStr !== "o1-preview" /* O1_PREVIEW */ && !modelStr.startsWith("o1");
502
510
  return withRetries(
503
511
  id,
504
512
  "OpenAI",
@@ -1029,52 +1037,140 @@ async function callGroq(id, payload) {
1029
1037
  async function callGroqWithRetries(id, payload, retries = 5) {
1030
1038
  return withRetries(id, "Groq", () => callGroq(id, payload), { retries });
1031
1039
  }
1032
- function isAnthropicPayload(payload) {
1033
- return Object.values(ClaudeModel).includes(payload.model);
1040
+ function prepareOpenRouterPayload(payload) {
1041
+ var _a;
1042
+ return {
1043
+ model: payload.model,
1044
+ messages: payload.messages.map((message) => ({
1045
+ role: message.role,
1046
+ content: normalizeMessageContent(message.content)
1047
+ })),
1048
+ tools: (_a = payload.functions) == null ? void 0 : _a.map((fn) => ({
1049
+ type: "function",
1050
+ function: fn
1051
+ })),
1052
+ tool_choice: payload.function_call ? typeof payload.function_call === "string" ? payload.function_call : { type: "function", function: payload.function_call } : void 0,
1053
+ temperature: payload.temperature
1054
+ };
1034
1055
  }
1035
- function isOpenAiPayload(payload) {
1036
- return Object.values(GPTModel).includes(payload.model);
1056
+ async function callOpenRouter(id, payload) {
1057
+ var _a, _b;
1058
+ const response = await import_axios.default.post(
1059
+ "https://openrouter.ai/api/v1/chat/completions",
1060
+ payload,
1061
+ {
1062
+ headers: {
1063
+ "content-type": "application/json",
1064
+ Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`
1065
+ }
1066
+ }
1067
+ );
1068
+ const answer = (_a = response.data.choices[0]) == null ? void 0 : _a.message;
1069
+ if (!answer) {
1070
+ logger_default.error(id, "Missing answer in OpenRouter API response:", response.data);
1071
+ throw new Error("Missing answer in OpenRouter API");
1072
+ }
1073
+ const functionCalls = [];
1074
+ if ((_b = answer.tool_calls) == null ? void 0 : _b.length) {
1075
+ for (const tc of answer.tool_calls) {
1076
+ functionCalls.push({
1077
+ name: tc.function.name,
1078
+ arguments: JSON.parse(tc.function.arguments)
1079
+ });
1080
+ }
1081
+ }
1082
+ return {
1083
+ role: "assistant",
1084
+ content: answer.content || null,
1085
+ function_call: functionCalls[0] || null,
1086
+ function_calls: functionCalls,
1087
+ files: [],
1088
+ usage: response.data.usage ? {
1089
+ prompt_tokens: response.data.usage.prompt_tokens,
1090
+ completion_tokens: response.data.usage.completion_tokens,
1091
+ total_tokens: response.data.usage.total_tokens
1092
+ } : null
1093
+ };
1037
1094
  }
1038
- function isGroqPayload(payload) {
1039
- return Object.values(GroqModel).includes(payload.model);
1095
+ async function callOpenRouterWithRetries(id, payload, retries = 5) {
1096
+ return withRetries(id, "OpenRouter", () => callOpenRouter(id, payload), { retries });
1040
1097
  }
1041
- function isGoogleAIPayload(payload) {
1042
- return Object.values(GeminiModel).includes(payload.model);
1098
+ var VALID_PROVIDERS = ["openai", "anthropic", "google", "groq", "openrouter"];
1099
+ var ENUM_PROVIDER_MAP = [
1100
+ { values: new Set(Object.values(GPTModel)), provider: "openai" },
1101
+ { values: new Set(Object.values(ClaudeModel)), provider: "anthropic" },
1102
+ { values: new Set(Object.values(GeminiModel)), provider: "google" },
1103
+ { values: new Set(Object.values(GroqModel)), provider: "groq" },
1104
+ { values: new Set(Object.values(OpenRouterModel)), provider: "openrouter" }
1105
+ ];
1106
+ function parseModelString(model) {
1107
+ const colonIndex = model.indexOf(":");
1108
+ if (colonIndex !== -1) {
1109
+ const prefix = model.substring(0, colonIndex);
1110
+ if (VALID_PROVIDERS.includes(prefix)) {
1111
+ const modelId = model.substring(colonIndex + 1);
1112
+ if (!modelId) {
1113
+ throw new Error(
1114
+ `Empty model ID in model string '${model}'. Expected format: 'provider:model-id'`
1115
+ );
1116
+ }
1117
+ return { provider: prefix, modelId };
1118
+ }
1119
+ }
1120
+ for (const { values, provider } of ENUM_PROVIDER_MAP) {
1121
+ if (values.has(model)) {
1122
+ return { provider, modelId: model };
1123
+ }
1124
+ }
1125
+ if (colonIndex !== -1) {
1126
+ const prefix = model.substring(0, colonIndex);
1127
+ throw new Error(
1128
+ `Unknown provider '${prefix}' in model string '${model}'. Valid providers: ${VALID_PROVIDERS.join(", ")}`
1129
+ );
1130
+ }
1131
+ throw new Error(
1132
+ `Unable to determine provider for model '${model}'. Use a provider prefix (e.g. 'openai:${model}') or a known model enum value. Valid providers: ${VALID_PROVIDERS.join(", ")}`
1133
+ );
1043
1134
  }
1044
1135
  async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeoutMs = 15e3) {
1045
1136
  try {
1046
- if (isAnthropicPayload(aiPayload)) {
1047
- return await callAnthropicWithRetries(
1048
- id,
1049
- await prepareAnthropicPayload(id, aiPayload),
1050
- aiConfig,
1051
- retries
1052
- );
1053
- }
1054
- if (isOpenAiPayload(aiPayload)) {
1055
- return await callOpenAiWithRetries(
1056
- id,
1057
- await prepareOpenAIPayload(id, aiPayload),
1058
- aiConfig,
1059
- retries,
1060
- chunkTimeoutMs
1061
- );
1062
- }
1063
- if (isGroqPayload(aiPayload)) {
1064
- return await callGroqWithRetries(
1065
- id,
1066
- prepareGroqPayload(aiPayload),
1067
- retries
1068
- );
1069
- }
1070
- if (isGoogleAIPayload(aiPayload)) {
1071
- return await callGoogleAIWithRetries(
1072
- id,
1073
- await prepareGoogleAIPayload(id, aiPayload),
1074
- retries
1075
- );
1137
+ const { provider, modelId } = parseModelString(aiPayload.model);
1138
+ const routingPayload = { ...aiPayload, model: modelId };
1139
+ switch (provider) {
1140
+ case "anthropic":
1141
+ return await callAnthropicWithRetries(
1142
+ id,
1143
+ await prepareAnthropicPayload(id, routingPayload),
1144
+ aiConfig,
1145
+ retries
1146
+ );
1147
+ case "openai":
1148
+ return await callOpenAiWithRetries(
1149
+ id,
1150
+ await prepareOpenAIPayload(id, routingPayload),
1151
+ aiConfig,
1152
+ retries,
1153
+ chunkTimeoutMs
1154
+ );
1155
+ case "groq":
1156
+ return await callGroqWithRetries(
1157
+ id,
1158
+ prepareGroqPayload(routingPayload),
1159
+ retries
1160
+ );
1161
+ case "google":
1162
+ return await callGoogleAIWithRetries(
1163
+ id,
1164
+ await prepareGoogleAIPayload(id, routingPayload),
1165
+ retries
1166
+ );
1167
+ case "openrouter":
1168
+ return await callOpenRouterWithRetries(
1169
+ id,
1170
+ prepareOpenRouterPayload(routingPayload),
1171
+ retries
1172
+ );
1076
1173
  }
1077
- throw new Error("Invalid AI payload: Unknown model type.");
1078
1174
  } catch (error2) {
1079
1175
  if (aiPayload.fallbackModel) {
1080
1176
  logger_default.error(
@@ -1106,6 +1202,8 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1106
1202
  GPTModel,
1107
1203
  GeminiModel,
1108
1204
  GroqModel,
1109
- callWithRetries
1205
+ OpenRouterModel,
1206
+ callWithRetries,
1207
+ parseModelString
1110
1208
  });
1111
1209
  //# sourceMappingURL=index.js.map