@node-llm/core 0.7.0 → 1.0.0

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.
Files changed (117) hide show
  1. package/README.md +67 -62
  2. package/dist/chat/Chat.d.ts +3 -2
  3. package/dist/chat/Chat.d.ts.map +1 -1
  4. package/dist/chat/Chat.js +4 -4
  5. package/dist/chat/ChatStream.d.ts +25 -0
  6. package/dist/chat/ChatStream.d.ts.map +1 -0
  7. package/dist/chat/ChatStream.js +93 -0
  8. package/dist/config.d.ts +6 -2
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +3 -0
  11. package/dist/embedding/Embedding.d.ts +1 -1
  12. package/dist/embedding/Embedding.d.ts.map +1 -1
  13. package/dist/errors/index.d.ts +22 -0
  14. package/dist/errors/index.d.ts.map +1 -1
  15. package/dist/errors/index.js +32 -0
  16. package/dist/index.d.ts +5 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +5 -1
  19. package/dist/llm.d.ts +3 -1
  20. package/dist/llm.d.ts.map +1 -1
  21. package/dist/llm.js +26 -24
  22. package/dist/models/ModelRegistry.d.ts +3 -2
  23. package/dist/models/ModelRegistry.d.ts.map +1 -1
  24. package/dist/models/ModelRegistry.js +15 -3
  25. package/dist/models/models.d.ts +729 -60
  26. package/dist/models/models.d.ts.map +1 -1
  27. package/dist/models/models.js +24809 -2410
  28. package/dist/models/types.d.ts +3 -3
  29. package/dist/models/types.d.ts.map +1 -1
  30. package/dist/models/types.js +3 -0
  31. package/dist/providers/BaseProvider.d.ts +21 -0
  32. package/dist/providers/BaseProvider.d.ts.map +1 -0
  33. package/dist/providers/BaseProvider.js +28 -0
  34. package/dist/providers/Provider.d.ts +19 -1
  35. package/dist/providers/Provider.d.ts.map +1 -1
  36. package/dist/providers/anthropic/AnthropicProvider.d.ts +6 -7
  37. package/dist/providers/anthropic/AnthropicProvider.d.ts.map +1 -1
  38. package/dist/providers/anthropic/AnthropicProvider.js +16 -13
  39. package/dist/providers/anthropic/Streaming.d.ts +1 -1
  40. package/dist/providers/anthropic/Streaming.d.ts.map +1 -1
  41. package/dist/providers/anthropic/Streaming.js +80 -54
  42. package/dist/providers/deepseek/Capabilities.js +1 -1
  43. package/dist/providers/deepseek/DeepSeekProvider.d.ts +5 -1
  44. package/dist/providers/deepseek/DeepSeekProvider.d.ts.map +1 -1
  45. package/dist/providers/deepseek/DeepSeekProvider.js +15 -1
  46. package/dist/providers/deepseek/Streaming.d.ts +1 -1
  47. package/dist/providers/deepseek/Streaming.d.ts.map +1 -1
  48. package/dist/providers/deepseek/Streaming.js +80 -48
  49. package/dist/providers/gemini/Capabilities.d.ts.map +1 -1
  50. package/dist/providers/gemini/Embeddings.d.ts +1 -1
  51. package/dist/providers/gemini/Embeddings.d.ts.map +1 -1
  52. package/dist/providers/gemini/GeminiProvider.d.ts +6 -4
  53. package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -1
  54. package/dist/providers/gemini/GeminiProvider.js +14 -4
  55. package/dist/providers/gemini/Streaming.d.ts +1 -1
  56. package/dist/providers/gemini/Streaming.d.ts.map +1 -1
  57. package/dist/providers/gemini/Streaming.js +62 -39
  58. package/dist/providers/ollama/Capabilities.d.ts +13 -0
  59. package/dist/providers/ollama/Capabilities.d.ts.map +1 -0
  60. package/dist/providers/ollama/Capabilities.js +54 -0
  61. package/dist/providers/ollama/Embedding.d.ts +6 -0
  62. package/dist/providers/ollama/Embedding.d.ts.map +1 -0
  63. package/dist/providers/ollama/Embedding.js +12 -0
  64. package/dist/providers/ollama/Models.d.ts +8 -0
  65. package/dist/providers/ollama/Models.d.ts.map +1 -0
  66. package/dist/providers/ollama/Models.js +31 -0
  67. package/dist/providers/ollama/OllamaProvider.d.ts +9 -0
  68. package/dist/providers/ollama/OllamaProvider.d.ts.map +1 -0
  69. package/dist/providers/ollama/OllamaProvider.js +31 -0
  70. package/dist/providers/ollama/index.d.ts +9 -0
  71. package/dist/providers/ollama/index.d.ts.map +1 -0
  72. package/dist/providers/ollama/index.js +17 -0
  73. package/dist/providers/openai/Capabilities.d.ts +1 -1
  74. package/dist/providers/openai/Capabilities.d.ts.map +1 -1
  75. package/dist/providers/openai/Capabilities.js +4 -2
  76. package/dist/providers/openai/Embedding.d.ts +5 -3
  77. package/dist/providers/openai/Embedding.d.ts.map +1 -1
  78. package/dist/providers/openai/Embedding.js +13 -8
  79. package/dist/providers/openai/Models.d.ts +12 -2
  80. package/dist/providers/openai/Models.d.ts.map +1 -1
  81. package/dist/providers/openai/Models.js +50 -16
  82. package/dist/providers/openai/OpenAIProvider.d.ts +22 -12
  83. package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
  84. package/dist/providers/openai/OpenAIProvider.js +16 -2
  85. package/dist/providers/openai/Streaming.d.ts +1 -1
  86. package/dist/providers/openai/Streaming.d.ts.map +1 -1
  87. package/dist/providers/openai/Streaming.js +75 -43
  88. package/dist/providers/openrouter/Capabilities.d.ts +13 -0
  89. package/dist/providers/openrouter/Capabilities.d.ts.map +1 -0
  90. package/dist/providers/openrouter/Capabilities.js +67 -0
  91. package/dist/providers/openrouter/Models.d.ts +11 -0
  92. package/dist/providers/openrouter/Models.d.ts.map +1 -0
  93. package/dist/providers/openrouter/Models.js +88 -0
  94. package/dist/providers/openrouter/OpenRouterProvider.d.ts +21 -0
  95. package/dist/providers/openrouter/OpenRouterProvider.d.ts.map +1 -0
  96. package/dist/providers/openrouter/OpenRouterProvider.js +24 -0
  97. package/dist/providers/openrouter/index.d.ts +11 -0
  98. package/dist/providers/openrouter/index.d.ts.map +1 -0
  99. package/dist/providers/openrouter/index.js +26 -0
  100. package/dist/providers/registry.d.ts +11 -1
  101. package/dist/providers/registry.d.ts.map +1 -1
  102. package/dist/providers/registry.js +14 -0
  103. package/dist/streaming/Stream.d.ts +29 -0
  104. package/dist/streaming/Stream.d.ts.map +1 -0
  105. package/dist/streaming/Stream.js +67 -0
  106. package/dist/utils/FileLoader.d.ts.map +1 -1
  107. package/dist/utils/FileLoader.js +34 -3
  108. package/dist/utils/logger.d.ts +13 -0
  109. package/dist/utils/logger.d.ts.map +1 -0
  110. package/dist/utils/logger.js +24 -0
  111. package/package.json +1 -1
  112. package/dist/chat/Stream.d.ts +0 -21
  113. package/dist/chat/Stream.d.ts.map +0 -1
  114. package/dist/chat/Stream.js +0 -73
  115. package/dist/providers/Embedding.d.ts +0 -20
  116. package/dist/providers/Embedding.d.ts.map +0 -1
  117. package/dist/providers/Embedding.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Capabilities.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Capabilities.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACvB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUvD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASzD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO/C,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO9C,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOzD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOnD,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOxD,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOtD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOnD,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOlD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,qBAAqB,GAAG,cAAc;IAUtI,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAiB5E,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAoBjD,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI;IAMxG,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAOjD,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG;CAcxC"}
1
+ {"version":3,"file":"Capabilities.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Capabilities.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACvB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUvD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASzD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO/C,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO9C,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOzD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOnD,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOxD,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOtD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOnD,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOlD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,qBAAqB,GAAG,cAAc;IAWvI,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAiB5E,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAoBjD,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI;IAMxG,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAOjD,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG;CAcxC"}
@@ -30,7 +30,7 @@ export class Capabilities {
30
30
  }
31
31
  static supportsTools(modelId) {
32
32
  const model = ModelRegistry.find(modelId, "openai");
33
- if (model?.capabilities?.includes("function_calling"))
33
+ if (model?.capabilities?.includes("function_calling") || model?.capabilities?.includes("tools"))
34
34
  return true;
35
35
  return !/embedding|moderation|dall-e|tts|whisper/.test(modelId);
36
36
  }
@@ -74,10 +74,12 @@ export class Capabilities {
74
74
  return /o\d|gpt-5/.test(modelId);
75
75
  }
76
76
  static getModelType(modelId) {
77
+ if (this.supportsEmbeddings(modelId))
78
+ return "embeddings";
77
79
  if (/moderation/.test(modelId))
78
80
  return "moderation";
79
81
  if (/embedding/.test(modelId))
80
- return "embedding";
82
+ return "embeddings";
81
83
  if (/dall-e|image/.test(modelId))
82
84
  return "image";
83
85
  if (/whisper|transcribe/.test(modelId))
@@ -1,8 +1,10 @@
1
- import { EmbeddingRequest, EmbeddingResponse } from "../Embedding.js";
1
+ import { EmbeddingRequest, EmbeddingResponse } from "../Provider.js";
2
2
  export declare class OpenAIEmbedding {
3
- private readonly baseUrl;
4
- private readonly apiKey;
3
+ protected readonly baseUrl: string;
4
+ protected readonly apiKey: string;
5
5
  constructor(baseUrl: string, apiKey: string);
6
+ protected getProviderName(): string;
7
+ protected validateModel(model: string): void;
6
8
  execute(request: EmbeddingRequest): Promise<EmbeddingResponse>;
7
9
  }
8
10
  //# sourceMappingURL=Embedding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMtE,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAG3B,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA8CrE"}
1
+ {"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMrE,qBAAa,eAAe;IAExB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM;IAClC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAGnC,SAAS,CAAC,eAAe,IAAI,MAAM;IAInC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMtC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA2CrE"}
@@ -9,12 +9,17 @@ export class OpenAIEmbedding {
9
9
  this.baseUrl = baseUrl;
10
10
  this.apiKey = apiKey;
11
11
  }
12
- async execute(request) {
13
- const model = request.model || DEFAULT_MODELS.EMBEDDING;
14
- // Validate that the model is an embedding model
15
- if (Capabilities.getModelType(model) !== "embedding") {
12
+ getProviderName() {
13
+ return "openai";
14
+ }
15
+ validateModel(model) {
16
+ if (Capabilities.getModelType(model) !== "embeddings") {
16
17
  throw new Error(`Model ${model} does not support embeddings.`);
17
18
  }
19
+ }
20
+ async execute(request) {
21
+ const model = request.model || DEFAULT_MODELS.EMBEDDING;
22
+ this.validateModel(model);
18
23
  const body = {
19
24
  input: request.input,
20
25
  model,
@@ -36,13 +41,13 @@ export class OpenAIEmbedding {
36
41
  if (!response.ok) {
37
42
  await handleOpenAIError(response, request.model || DEFAULT_MODELS.EMBEDDING);
38
43
  }
39
- const json = await response.json();
44
+ const { data, model: responseModel, usage } = await response.json();
40
45
  // Extract vectors from the response
41
- const vectors = json.data.map((item) => item.embedding);
46
+ const vectors = data.map((item) => item.embedding);
42
47
  return {
43
48
  vectors,
44
- model: json.model,
45
- input_tokens: json.usage.prompt_tokens,
49
+ model: responseModel,
50
+ input_tokens: usage.prompt_tokens,
46
51
  dimensions: vectors[0]?.length || 0,
47
52
  };
48
53
  }
@@ -1,8 +1,18 @@
1
1
  import { ModelInfo } from "../Provider.js";
2
2
  export declare class OpenAIModels {
3
- private readonly baseUrl;
4
- private readonly apiKey;
3
+ protected readonly baseUrl: string;
4
+ protected readonly apiKey: string;
5
5
  constructor(baseUrl: string, apiKey: string);
6
+ protected getProviderName(): string;
7
+ protected formatDisplayName(modelId: string): string;
8
+ protected getContextWindow(modelId: string): number | null;
9
+ protected getMaxOutputTokens(modelId: string): number | null;
10
+ protected getModalities(modelId: string): {
11
+ input: string[];
12
+ output: string[];
13
+ };
14
+ protected getCapabilities(modelId: string): string[];
15
+ protected getPricing(modelId: string): any;
6
16
  execute(): Promise<ModelInfo[]>;
7
17
  find(modelId: string): import("../../models/types.js").Model | undefined;
8
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAM3C,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAkDrC,IAAI,CAAC,OAAO,EAAE,MAAM;CAGrB"}
1
+ {"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK3C,qBAAa,YAAY;IAErB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM;IAClC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAGnC,SAAS,CAAC,eAAe,IAAI,MAAM;IAInC,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAMpD,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI1D,SAAS,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI5D,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM;;;;IAKvC,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAKpD,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM;IAK9B,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAwDrC,IAAI,CAAC,OAAO,EAAE,MAAM;CAGrB"}
@@ -8,7 +8,35 @@ export class OpenAIModels {
8
8
  this.baseUrl = baseUrl;
9
9
  this.apiKey = apiKey;
10
10
  }
11
+ getProviderName() {
12
+ return "openai";
13
+ }
14
+ formatDisplayName(modelId) {
15
+ const model = ModelRegistry.find(modelId, this.getProviderName());
16
+ if (model?.name && model.name !== modelId)
17
+ return model.name;
18
+ return Capabilities.formatDisplayName(modelId);
19
+ }
20
+ getContextWindow(modelId) {
21
+ return ModelRegistry.getContextWindow(modelId, this.getProviderName()) || Capabilities.getContextWindow(modelId) || null;
22
+ }
23
+ getMaxOutputTokens(modelId) {
24
+ return ModelRegistry.getMaxOutputTokens(modelId, this.getProviderName()) || Capabilities.getMaxOutputTokens(modelId) || null;
25
+ }
26
+ getModalities(modelId) {
27
+ const model = ModelRegistry.find(modelId, this.getProviderName());
28
+ return model?.modalities || Capabilities.getModalities(modelId);
29
+ }
30
+ getCapabilities(modelId) {
31
+ const model = ModelRegistry.find(modelId, this.getProviderName());
32
+ return model?.capabilities || Capabilities.getCapabilities(modelId);
33
+ }
34
+ getPricing(modelId) {
35
+ const model = ModelRegistry.find(modelId, this.getProviderName());
36
+ return model?.pricing || Capabilities.getPricing(modelId);
37
+ }
11
38
  async execute() {
39
+ const provider = this.getProviderName();
12
40
  try {
13
41
  const response = await fetch(buildUrl(this.baseUrl, '/models'), {
14
42
  method: "GET",
@@ -21,39 +49,45 @@ export class OpenAIModels {
21
49
  const { data } = await response.json();
22
50
  return data.map(m => {
23
51
  const modelId = m.id;
24
- const registryModel = ModelRegistry.find(modelId, "openai");
25
- const info = {
52
+ const registryModel = ModelRegistry.find(modelId, provider);
53
+ return {
26
54
  id: modelId,
27
- name: registryModel?.name || Capabilities.formatDisplayName(modelId),
28
- provider: "openai",
55
+ name: this.formatDisplayName(modelId),
56
+ provider: provider,
29
57
  family: registryModel?.family || modelId,
30
- context_window: registryModel?.context_window || Capabilities.getContextWindow(modelId),
31
- max_output_tokens: registryModel?.max_output_tokens || Capabilities.getMaxOutputTokens(modelId),
32
- modalities: registryModel?.modalities || Capabilities.getModalities(modelId),
33
- capabilities: Capabilities.getCapabilities(modelId),
34
- pricing: registryModel?.pricing || Capabilities.getPricing(modelId),
58
+ context_window: this.getContextWindow(modelId),
59
+ max_output_tokens: this.getMaxOutputTokens(modelId),
60
+ modalities: this.getModalities(modelId),
61
+ capabilities: this.getCapabilities(modelId),
62
+ pricing: this.getPricing(modelId),
35
63
  metadata: {
36
64
  ...(registryModel?.metadata || {}),
37
65
  created: m.created,
38
66
  owned_by: m.owned_by
39
67
  }
40
68
  };
41
- return info;
42
69
  });
43
70
  }
44
71
  }
45
72
  catch (_error) {
46
- // Fallback to registry if API call fails (e.g. in tests without network)
73
+ // Fallback to registry if API call fails
47
74
  }
48
75
  // Fallback to registry data
49
76
  return ModelRegistry.all()
50
- .filter(m => m.provider === "openai")
51
- .map(m => ({
52
- ...m,
53
- capabilities: Capabilities.getCapabilities(m.id)
77
+ .filter((m) => m.provider === provider)
78
+ .map((m) => ({
79
+ id: m.id,
80
+ name: m.name,
81
+ family: m.family || m.id,
82
+ provider: provider,
83
+ context_window: m.context_window ?? null,
84
+ capabilities: m.capabilities,
85
+ modalities: m.modalities,
86
+ max_output_tokens: m.max_output_tokens ?? null,
87
+ pricing: m.pricing || {}
54
88
  }));
55
89
  }
56
90
  find(modelId) {
57
- return ModelRegistry.find(modelId, "openai");
91
+ return ModelRegistry.find(modelId, this.getProviderName());
58
92
  }
59
93
  }
@@ -1,20 +1,27 @@
1
- import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk, ImageRequest, ImageResponse, ModerationRequest, ModerationResponse } from "../Provider.js";
1
+ import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk, ImageRequest, ImageResponse, ModerationRequest, ModerationResponse, EmbeddingRequest, EmbeddingResponse } from "../Provider.js";
2
+ import { BaseProvider } from "../BaseProvider.js";
3
+ import { OpenAIChat } from "./Chat.js";
4
+ import { OpenAIStreaming } from "./Streaming.js";
5
+ import { OpenAIModels } from "./Models.js";
6
+ import { OpenAIImage } from "./Image.js";
7
+ import { OpenAITranscription } from "./Transcription.js";
8
+ import { OpenAIModeration } from "./Moderation.js";
9
+ import { OpenAIEmbedding } from "./Embedding.js";
2
10
  import { TranscriptionRequest, TranscriptionResponse } from "../Provider.js";
3
- import { EmbeddingRequest, EmbeddingResponse } from "../Embedding.js";
4
11
  export interface OpenAIProviderOptions {
5
12
  apiKey: string;
6
13
  baseUrl?: string;
7
14
  }
8
- export declare class OpenAIProvider implements Provider {
9
- private readonly options;
10
- private readonly baseUrl;
11
- private readonly chatHandler;
12
- private readonly streamingHandler;
13
- private readonly modelsHandler;
14
- private readonly imageHandler;
15
- private readonly transcriptionHandler;
16
- private readonly moderationHandler;
17
- private readonly embeddingHandler;
15
+ export declare class OpenAIProvider extends BaseProvider implements Provider {
16
+ protected readonly options: OpenAIProviderOptions;
17
+ protected baseUrl: string;
18
+ protected chatHandler: OpenAIChat;
19
+ protected streamingHandler: OpenAIStreaming;
20
+ protected modelsHandler: OpenAIModels;
21
+ protected imageHandler: OpenAIImage;
22
+ protected transcriptionHandler: OpenAITranscription;
23
+ protected moderationHandler: OpenAIModeration;
24
+ protected embeddingHandler: OpenAIEmbedding;
18
25
  capabilities: {
19
26
  supportsVision: (model: string) => boolean;
20
27
  supportsTools: (model: string) => boolean;
@@ -27,6 +34,9 @@ export declare class OpenAIProvider implements Provider {
27
34
  getContextWindow: (model: string) => number | null;
28
35
  };
29
36
  constructor(options: OpenAIProviderOptions);
37
+ apiBase(): string;
38
+ headers(): Record<string, string>;
39
+ protected providerName(): string;
30
40
  chat(request: ChatRequest): Promise<ChatResponse>;
31
41
  stream(request: ChatRequest): AsyncGenerator<ChatChunk>;
32
42
  listModels(): Promise<ModelInfo[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/OpenAIProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAS/J,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,QAAQ;IAsBjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IArBpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IAE5C,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;oCACZ,MAAM;yCACD,MAAM;uCACR,MAAM;oCACT,MAAM;mCACP,MAAM;kCACP,MAAM;MAChC;gBAE2B,OAAO,EAAE,qBAAqB;IAWrD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;IAIxD,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpD,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAIzE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIjE,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGnE"}
1
+ {"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/OpenAIProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACpM,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,YAAa,YAAW,QAAQ;IAsBtD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,qBAAqB;IArB7D,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC;IAClC,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAC5C,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC;IACtC,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC;IACpC,SAAS,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACpD,SAAS,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;IAC9C,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAErC,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;oCACZ,MAAM;yCACD,MAAM;uCACR,MAAM;oCACT,MAAM;mCACP,MAAM;kCACP,MAAM;MAChC;gBAE6B,OAAO,EAAE,qBAAqB;IAYtD,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOxC,SAAS,CAAC,YAAY,IAAI,MAAM;IAI1B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;IAIxD,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpD,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAIzE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIjE,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGnE"}
@@ -1,3 +1,4 @@
1
+ import { BaseProvider } from "../BaseProvider.js";
1
2
  import { Capabilities } from "./Capabilities.js";
2
3
  import { OpenAIChat } from "./Chat.js";
3
4
  import { OpenAIStreaming } from "./Streaming.js";
@@ -6,7 +7,7 @@ import { OpenAIImage } from "./Image.js";
6
7
  import { OpenAITranscription } from "./Transcription.js";
7
8
  import { OpenAIModeration } from "./Moderation.js";
8
9
  import { OpenAIEmbedding } from "./Embedding.js";
9
- export class OpenAIProvider {
10
+ export class OpenAIProvider extends BaseProvider {
10
11
  options;
11
12
  baseUrl;
12
13
  chatHandler;
@@ -25,9 +26,10 @@ export class OpenAIProvider {
25
26
  supportsTranscription: (model) => Capabilities.supportsTranscription(model),
26
27
  supportsModeration: (model) => Capabilities.supportsModeration(model),
27
28
  supportsReasoning: (model) => Capabilities.supportsReasoning(model),
28
- getContextWindow: (model) => Capabilities.getContextWindow(model),
29
+ getContextWindow: (model) => Capabilities.getContextWindow(model) || null,
29
30
  };
30
31
  constructor(options) {
32
+ super();
31
33
  this.options = options;
32
34
  this.baseUrl = options.baseUrl ?? "https://api.openai.com/v1";
33
35
  this.chatHandler = new OpenAIChat(this.baseUrl, options.apiKey);
@@ -38,6 +40,18 @@ export class OpenAIProvider {
38
40
  this.moderationHandler = new OpenAIModeration(this.baseUrl, options.apiKey);
39
41
  this.embeddingHandler = new OpenAIEmbedding(this.baseUrl, options.apiKey);
40
42
  }
43
+ apiBase() {
44
+ return this.baseUrl;
45
+ }
46
+ headers() {
47
+ return {
48
+ "Authorization": `Bearer ${this.options.apiKey}`,
49
+ "Content-Type": "application/json",
50
+ };
51
+ }
52
+ providerName() {
53
+ return "OpenAI";
54
+ }
41
55
  async chat(request) {
42
56
  return this.chatHandler.execute(request);
43
57
  }
@@ -3,6 +3,6 @@ export declare class OpenAIStreaming {
3
3
  private readonly baseUrl;
4
4
  private readonly apiKey;
5
5
  constructor(baseUrl: string, apiKey: string);
6
- execute(request: ChatRequest): AsyncGenerator<ChatChunk>;
6
+ execute(request: ChatRequest, controller?: AbortController): AsyncGenerator<ChatChunk>;
7
7
  }
8
8
  //# sourceMappingURL=Streaming.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKxD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;CAyEhE"}
1
+ {"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAMxD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CACZ,OAAO,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,eAAe,GAC3B,cAAc,CAAC,SAAS,CAAC;CAgH7B"}
@@ -1,6 +1,7 @@
1
1
  import { Capabilities } from "./Capabilities.js";
2
2
  import { handleOpenAIError } from "./Errors.js";
3
3
  import { buildUrl } from "./utils.js";
4
+ import { APIError } from "../../errors/index.js";
4
5
  export class OpenAIStreaming {
5
6
  baseUrl;
6
7
  apiKey;
@@ -8,7 +9,8 @@ export class OpenAIStreaming {
8
9
  this.baseUrl = baseUrl;
9
10
  this.apiKey = apiKey;
10
11
  }
11
- async *execute(request) {
12
+ async *execute(request, controller) {
13
+ const abortController = controller || new AbortController();
12
14
  const temperature = Capabilities.normalizeTemperature(request.temperature, request.model);
13
15
  const body = {
14
16
  model: request.model,
@@ -24,50 +26,80 @@ export class OpenAIStreaming {
24
26
  if (request.response_format) {
25
27
  body.response_format = request.response_format;
26
28
  }
27
- const response = await fetch(buildUrl(this.baseUrl, '/chat/completions'), {
28
- method: "POST",
29
- headers: {
30
- "Authorization": `Bearer ${this.apiKey}`,
31
- "Content-Type": "application/json",
32
- ...request.headers,
33
- },
34
- body: JSON.stringify(body),
35
- });
36
- if (!response.ok) {
37
- await handleOpenAIError(response, request.model);
38
- }
39
- if (!response.body) {
40
- throw new Error("No response body for streaming");
41
- }
42
- const reader = response.body.getReader();
43
- const decoder = new TextDecoder();
44
- let buffer = "";
45
- while (true) {
46
- const { value, done } = await reader.read();
47
- if (done)
48
- break;
49
- const chunk = decoder.decode(value, { stream: true });
50
- buffer += chunk;
51
- const lines = buffer.split("\n\n");
52
- buffer = lines.pop() || ""; // Keep the last incomplete part in the buffer
53
- for (const line of lines) {
54
- const trimmed = line.trim();
55
- if (!trimmed.startsWith("data: "))
56
- continue;
57
- const data = trimmed.replace("data: ", "").trim();
58
- if (data === "[DONE]")
59
- return;
60
- try {
61
- const json = JSON.parse(data);
62
- const delta = json.choices?.[0]?.delta?.content;
63
- if (delta) {
64
- yield { content: delta };
29
+ let done = false;
30
+ try {
31
+ const response = await fetch(buildUrl(this.baseUrl, '/chat/completions'), {
32
+ method: "POST",
33
+ headers: {
34
+ "Authorization": `Bearer ${this.apiKey}`,
35
+ "Content-Type": "application/json",
36
+ ...request.headers,
37
+ },
38
+ body: JSON.stringify(body),
39
+ signal: abortController.signal,
40
+ });
41
+ if (!response.ok) {
42
+ await handleOpenAIError(response, request.model);
43
+ }
44
+ if (!response.body) {
45
+ throw new Error("No response body for streaming");
46
+ }
47
+ const reader = response.body.getReader();
48
+ const decoder = new TextDecoder();
49
+ let buffer = "";
50
+ while (true) {
51
+ const { value, done: readerDone } = await reader.read();
52
+ if (readerDone)
53
+ break;
54
+ const chunk = decoder.decode(value, { stream: true });
55
+ buffer += chunk;
56
+ const lines = buffer.split("\n\n");
57
+ buffer = lines.pop() || ""; // Keep the last incomplete part in the buffer
58
+ for (const line of lines) {
59
+ let trimmed = line.trim();
60
+ // Handle carriage returns
61
+ if (trimmed.endsWith('\r')) {
62
+ trimmed = trimmed.substring(0, trimmed.length - 1);
63
+ }
64
+ if (!trimmed.startsWith("data: "))
65
+ continue;
66
+ const data = trimmed.replace("data: ", "").trim();
67
+ if (data === "[DONE]") {
68
+ done = true;
69
+ return;
70
+ }
71
+ try {
72
+ const json = JSON.parse(data);
73
+ // Check for errors in the data
74
+ if (json.error) {
75
+ throw new APIError("OpenAI", response.status, json.error.message || "Stream error");
76
+ }
77
+ const delta = json.choices?.[0]?.delta?.content;
78
+ if (delta) {
79
+ yield { content: delta };
80
+ }
81
+ }
82
+ catch (e) {
83
+ // Re-throw APIError
84
+ if (e instanceof APIError)
85
+ throw e;
86
+ // Ignore other parse errors
65
87
  }
66
88
  }
67
- catch (e) {
68
- // Ignore parse errors for now, or log them
69
- // console.warn("JSON parse error in stream:", e);
70
- }
89
+ }
90
+ done = true;
91
+ }
92
+ catch (e) {
93
+ // Graceful exit on abort
94
+ if (e instanceof Error && e.name === 'AbortError') {
95
+ return;
96
+ }
97
+ throw e;
98
+ }
99
+ finally {
100
+ // Cleanup: abort if user breaks early
101
+ if (!done) {
102
+ abortController.abort();
71
103
  }
72
104
  }
73
105
  }
@@ -0,0 +1,13 @@
1
+ export declare class OpenRouterCapabilities {
2
+ private static findModel;
3
+ static supportsVision(model: string): boolean;
4
+ static supportsTools(model: string): boolean;
5
+ static supportsStructuredOutput(model: string): boolean;
6
+ static supportsEmbeddings(model: string): boolean;
7
+ static supportsImageGeneration(model: string): boolean;
8
+ static supportsTranscription(model: string): boolean;
9
+ static supportsModeration(model: string): boolean;
10
+ static supportsReasoning(model: string): boolean;
11
+ static getContextWindow(model: string): number | null;
12
+ }
13
+ //# sourceMappingURL=Capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Capabilities.d.ts","sourceRoot":"","sources":["../../../src/providers/openrouter/Capabilities.ts"],"names":[],"mappings":"AAEA,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAc7C,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAS5C,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAUvD,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IASjD,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAItD,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIpD,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIjD,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAWhD,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAItD"}
@@ -0,0 +1,67 @@
1
+ import { ModelRegistry } from "../../models/ModelRegistry.js";
2
+ export class OpenRouterCapabilities {
3
+ static findModel(model) {
4
+ return ModelRegistry.find(model, "openrouter");
5
+ }
6
+ static supportsVision(model) {
7
+ const info = this.findModel(model);
8
+ if (info)
9
+ return info.capabilities.includes('vision') || info.modalities.input.includes('image');
10
+ // Fallback heuristics
11
+ return model.includes('vision') ||
12
+ model.includes('gpt-4o') ||
13
+ model.includes('claude-3') ||
14
+ model.includes('gemini-1.5') ||
15
+ model.includes('gemini-2.0') ||
16
+ model.includes('flash') ||
17
+ model.includes('gemini-pro-vision');
18
+ }
19
+ static supportsTools(model) {
20
+ const info = this.findModel(model);
21
+ if (info)
22
+ return info.capabilities.includes('tools') || info.capabilities.includes('function_calling');
23
+ // Fallback: Default to true for OpenRouter as most models support tools
24
+ // but this is the "honest" check we wanted.
25
+ return true;
26
+ }
27
+ static supportsStructuredOutput(model) {
28
+ const info = this.findModel(model);
29
+ if (info)
30
+ return info.capabilities.includes('structured_output') || info.id.includes('gpt-4');
31
+ // Fallback heuristics
32
+ return model.includes('gpt-4') ||
33
+ model.includes('gpt-3.5') ||
34
+ model.includes('claude-3');
35
+ }
36
+ static supportsEmbeddings(model) {
37
+ const info = this.findModel(model);
38
+ if (info)
39
+ return info.capabilities.includes('embeddings');
40
+ // Fallback heuristics
41
+ return model.includes('embedding') ||
42
+ model.includes('text-sdk');
43
+ }
44
+ static supportsImageGeneration(model) {
45
+ return false;
46
+ }
47
+ static supportsTranscription(model) {
48
+ return false;
49
+ }
50
+ static supportsModeration(model) {
51
+ return false;
52
+ }
53
+ static supportsReasoning(model) {
54
+ const info = this.findModel(model);
55
+ if (info)
56
+ return info.capabilities.includes('reasoning');
57
+ // Fallback heuristics
58
+ return model.includes('o1') ||
59
+ model.includes('o3') ||
60
+ model.includes('deepseek-r1') ||
61
+ model.includes('qwq');
62
+ }
63
+ static getContextWindow(model) {
64
+ const info = this.findModel(model);
65
+ return info?.context_window ?? null;
66
+ }
67
+ }
@@ -0,0 +1,11 @@
1
+ import { ModelInfo } from "../Provider.js";
2
+ export declare class OpenRouterModels {
3
+ private readonly baseUrl;
4
+ private readonly apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ execute(): Promise<ModelInfo[]>;
7
+ private parseModel;
8
+ private parseCapabilities;
9
+ private parsePricing;
10
+ }
11
+ //# sourceMappingURL=Models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../../src/providers/openrouter/Models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwB3C,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAG3B,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAiBrC,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,YAAY;CA2BrB"}