@node-llm/core 0.1.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 (74) hide show
  1. package/README.md +215 -0
  2. package/dist/chat/Chat.d.ts +35 -0
  3. package/dist/chat/Chat.d.ts.map +1 -0
  4. package/dist/chat/Chat.js +147 -0
  5. package/dist/chat/ChatOptions.d.ts +10 -0
  6. package/dist/chat/ChatOptions.d.ts.map +1 -0
  7. package/dist/chat/ChatOptions.js +1 -0
  8. package/dist/chat/Content.d.ts +22 -0
  9. package/dist/chat/Content.d.ts.map +1 -0
  10. package/dist/chat/Content.js +1 -0
  11. package/dist/chat/Message.d.ts +11 -0
  12. package/dist/chat/Message.d.ts.map +1 -0
  13. package/dist/chat/Message.js +1 -0
  14. package/dist/chat/Role.d.ts +2 -0
  15. package/dist/chat/Role.d.ts.map +1 -0
  16. package/dist/chat/Role.js +1 -0
  17. package/dist/chat/Tool.d.ts +18 -0
  18. package/dist/chat/Tool.d.ts.map +1 -0
  19. package/dist/chat/Tool.js +1 -0
  20. package/dist/executor/Executor.d.ts +11 -0
  21. package/dist/executor/Executor.d.ts.map +1 -0
  22. package/dist/executor/Executor.js +26 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +5 -0
  26. package/dist/llm.d.ts +25 -0
  27. package/dist/llm.d.ts.map +1 -0
  28. package/dist/llm.js +46 -0
  29. package/dist/providers/Provider.d.ts +45 -0
  30. package/dist/providers/Provider.d.ts.map +1 -0
  31. package/dist/providers/Provider.js +1 -0
  32. package/dist/providers/openai/Capabilities.d.ts +25 -0
  33. package/dist/providers/openai/Capabilities.d.ts.map +1 -0
  34. package/dist/providers/openai/Capabilities.js +322 -0
  35. package/dist/providers/openai/Chat.d.ts +8 -0
  36. package/dist/providers/openai/Chat.d.ts.map +1 -0
  37. package/dist/providers/openai/Chat.js +47 -0
  38. package/dist/providers/openai/Models.d.ts +8 -0
  39. package/dist/providers/openai/Models.d.ts.map +1 -0
  40. package/dist/providers/openai/Models.js +35 -0
  41. package/dist/providers/openai/OpenAIProvider.d.ts +23 -0
  42. package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -0
  43. package/dist/providers/openai/OpenAIProvider.js +33 -0
  44. package/dist/providers/openai/Streaming.d.ts +8 -0
  45. package/dist/providers/openai/Streaming.d.ts.map +1 -0
  46. package/dist/providers/openai/Streaming.js +55 -0
  47. package/dist/providers/openai/index.d.ts +2 -0
  48. package/dist/providers/openai/index.d.ts.map +1 -0
  49. package/dist/providers/openai/index.js +11 -0
  50. package/dist/providers/openai/register.d.ts +2 -0
  51. package/dist/providers/openai/register.d.ts.map +1 -0
  52. package/dist/providers/openai/register.js +15 -0
  53. package/dist/providers/openai/types.d.ts +23 -0
  54. package/dist/providers/openai/types.d.ts.map +1 -0
  55. package/dist/providers/openai/types.js +1 -0
  56. package/dist/providers/registry.d.ts +20 -0
  57. package/dist/providers/registry.d.ts.map +1 -0
  58. package/dist/providers/registry.js +29 -0
  59. package/dist/tools/Tool.d.ts +8 -0
  60. package/dist/tools/Tool.d.ts.map +1 -0
  61. package/dist/tools/Tool.js +1 -0
  62. package/dist/tools/ToolSet.d.ts +15 -0
  63. package/dist/tools/ToolSet.d.ts.map +1 -0
  64. package/dist/tools/ToolSet.js +29 -0
  65. package/dist/tools/index.d.ts +2 -0
  66. package/dist/tools/index.d.ts.map +1 -0
  67. package/dist/tools/index.js +1 -0
  68. package/dist/tools/runCommandTool.d.ts +8 -0
  69. package/dist/tools/runCommandTool.d.ts.map +1 -0
  70. package/dist/tools/runCommandTool.js +19 -0
  71. package/dist/utils/FileLoader.d.ts +5 -0
  72. package/dist/utils/FileLoader.d.ts.map +1 -0
  73. package/dist/utils/FileLoader.js +71 -0
  74. package/package.json +29 -0
@@ -0,0 +1,45 @@
1
+ import { Message } from "../chat/Message.js";
2
+ import { Tool, ToolCall } from "../chat/Tool.js";
3
+ export interface ChatRequest {
4
+ model: string;
5
+ messages: Message[];
6
+ tools?: Tool[];
7
+ temperature?: number;
8
+ max_tokens?: number;
9
+ }
10
+ export interface ChatChunk {
11
+ content: string;
12
+ done?: boolean;
13
+ }
14
+ export interface ChatResponse {
15
+ content: string | null;
16
+ tool_calls?: ToolCall[];
17
+ }
18
+ export interface ProviderCapabilities {
19
+ supportsVision: (model: string) => boolean;
20
+ supportsTools: (model: string) => boolean;
21
+ supportsStructuredOutput: (model: string) => boolean;
22
+ getContextWindow: (model: string) => number | null;
23
+ }
24
+ export interface ModelInfo {
25
+ id: string;
26
+ name: string;
27
+ provider: string;
28
+ family: string;
29
+ context_window: number | null;
30
+ max_output_tokens: number | null;
31
+ modalities: {
32
+ input: string[];
33
+ output: string[];
34
+ };
35
+ capabilities: string[];
36
+ pricing: any;
37
+ metadata?: Record<string, any>;
38
+ }
39
+ export interface Provider {
40
+ chat(request: ChatRequest): Promise<ChatResponse>;
41
+ stream?(request: ChatRequest): AsyncIterable<ChatChunk>;
42
+ listModels?(): Promise<ModelInfo[]>;
43
+ capabilities?: ProviderCapabilities;
44
+ }
45
+ //# sourceMappingURL=Provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Provider.d.ts","sourceRoot":"","sources":["../../src/providers/Provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACxD,UAAU,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ export type ModelFamily = "dall_e" | "chatgpt4o" | "gpt41" | "gpt41_mini" | "gpt41_nano" | "gpt4" | "gpt4_turbo" | "gpt45" | "gpt35_turbo" | "gpt4o" | "gpt4o_audio" | "gpt4o_mini" | "gpt4o_mini_audio" | "gpt4o_mini_realtime" | "gpt4o_mini_transcribe" | "gpt4o_mini_tts" | "gpt4o_realtime" | "gpt4o_search" | "gpt4o_transcribe" | "gpt5" | "gpt5_mini" | "gpt5_nano" | "o1" | "o1_mini" | "o1_pro" | "o3_mini" | "babbage" | "davinci" | "embedding3_large" | "embedding3_small" | "embedding_ada" | "tts1" | "tts1_hd" | "whisper" | "moderation" | "other";
2
+ export declare class Capabilities {
3
+ static getFamily(modelId: string): ModelFamily;
4
+ static getContextWindow(modelId: string): number | null;
5
+ static getMaxOutputTokens(modelId: string): number | null;
6
+ static supportsVision(modelId: string): boolean;
7
+ static supportsTools(modelId: string): boolean;
8
+ static supportsStructuredOutput(modelId: string): boolean;
9
+ static supportsJsonMode(modelId: string): boolean;
10
+ static getInputPrice(modelId: string): number;
11
+ static getCachedInputPrice(modelId: string): number | undefined;
12
+ static getOutputPrice(modelId: string): number;
13
+ static getModelType(modelId: string): "embedding" | "audio" | "moderation" | "image" | "chat";
14
+ static formatDisplayName(modelId: string): string;
15
+ private static applySpecialFormatting;
16
+ private static specialPrefixFormat;
17
+ static normalizeTemperature(temperature: number | undefined, modelId: string): number | undefined | null;
18
+ static getModalities(modelId: string): {
19
+ input: string[];
20
+ output: string[];
21
+ };
22
+ static getCapabilities(modelId: string): string[];
23
+ static getPricing(modelId: string): any;
24
+ }
25
+ //# sourceMappingURL=Capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Capabilities.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Capabilities.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,WAAW,GACX,OAAO,GACP,YAAY,GACZ,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,OAAO,GACP,aAAa,GACb,OAAO,GACP,aAAa,GACb,YAAY,GACZ,kBAAkB,GAClB,qBAAqB,GACrB,uBAAuB,GACvB,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,kBAAkB,GAClB,MAAM,GACN,WAAW,GACX,WAAW,GACX,IAAI,GACJ,SAAS,GACT,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,GACf,MAAM,GACN,SAAS,GACT,SAAS,GACT,YAAY,GACZ,OAAO,CAAC;AA4EZ,qBAAa,YAAY;IACvB,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IAS9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA8CvD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAgDzD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAS/C,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQ9C,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQzD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjD,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAM7C,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM/D,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAM9C,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM;IAS7F,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKjD,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAarC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAUlC,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI;IAUxG,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAgB5E,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAmBjD,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM;CAyBlC"}
@@ -0,0 +1,322 @@
1
+ const MODEL_PATTERNS = {
2
+ dall_e: /^dall-e/,
3
+ chatgpt4o: /^chatgpt-4o/,
4
+ gpt41: /^gpt-4\.1(?!-(?:mini|nano))/,
5
+ gpt41_mini: /^gpt-4\.1-mini/,
6
+ gpt41_nano: /^gpt-4\.1-nano/,
7
+ gpt4: /^gpt-4(?:-\d{6})?$/,
8
+ gpt4_turbo: /^gpt-4(?:\.5)?-(?:\d{6}-)?(preview|turbo)/,
9
+ gpt35_turbo: /^gpt-3\.5-turbo/,
10
+ gpt4o: /^gpt-4o(?!-(?:mini|audio|realtime|transcribe|tts|search))/,
11
+ gpt4o_audio: /^gpt-4o-(?:audio)/,
12
+ gpt4o_mini: /^gpt-4o-mini(?!-(?:audio|realtime|transcribe|tts|search))/,
13
+ gpt4o_mini_audio: /^gpt-4o-mini-audio/,
14
+ gpt4o_mini_realtime: /^gpt-4o-mini-realtime/,
15
+ gpt4o_mini_transcribe: /^gpt-4o-mini-transcribe/,
16
+ gpt4o_mini_tts: /^gpt-4o-mini-tts/,
17
+ gpt4o_realtime: /^gpt-4o-realtime/,
18
+ gpt4o_search: /^gpt-4o-search/,
19
+ gpt4o_transcribe: /^gpt-4o-transcribe/,
20
+ gpt5: /^gpt-5/,
21
+ gpt5_mini: /^gpt-5-mini/,
22
+ gpt5_nano: /^gpt-5-nano/,
23
+ o1: /^o1(?!-(?:mini|pro))/,
24
+ o1_mini: /^o1-mini/,
25
+ o1_pro: /^o1-pro/,
26
+ o3_mini: /^o3-mini/,
27
+ babbage: /^babbage/,
28
+ davinci: /^davinci/,
29
+ embedding3_large: /^text-embedding-3-large/,
30
+ embedding3_small: /^text-embedding-3-small/,
31
+ embedding_ada: /^text-embedding-ada/,
32
+ tts1: /^tts-1(?!-hd)/,
33
+ tts1_hd: /^tts-1-hd/,
34
+ whisper: /^whisper/,
35
+ moderation: /^(?:omni|text)-moderation/,
36
+ };
37
+ const PRICES = {
38
+ gpt5: { input: 1.25, output: 10.0, cached_input: 0.125 },
39
+ gpt5_mini: { input: 0.25, output: 2.0, cached_input: 0.025 },
40
+ gpt5_nano: { input: 0.05, output: 0.4, cached_input: 0.005 },
41
+ gpt41: { input: 2.0, output: 8.0, cached_input: 0.5 },
42
+ gpt41_mini: { input: 0.4, output: 1.6, cached_input: 0.1 },
43
+ gpt41_nano: { input: 0.1, output: 0.4 },
44
+ chatgpt4o: { input: 5.0, output: 15.0 },
45
+ gpt4: { input: 10.0, output: 30.0 },
46
+ gpt4_turbo: { input: 10.0, output: 30.0 },
47
+ gpt45: { input: 75.0, output: 150.0 },
48
+ gpt35_turbo: { input: 0.5, output: 1.5 },
49
+ gpt4o: { input: 2.5, output: 10.0 },
50
+ gpt4o_audio: { input: 2.5, output: 10.0, audio_input: 40.0, audio_output: 80.0 },
51
+ gpt4o_mini: { input: 0.15, output: 0.6 },
52
+ gpt4o_mini_audio: { input: 0.15, output: 0.6, audio_input: 10.0, audio_output: 20.0 },
53
+ gpt4o_mini_realtime: { input: 0.6, output: 2.4 },
54
+ gpt4o_mini_transcribe: { input: 1.25, output: 5.0, audio_input: 3.0 },
55
+ gpt4o_mini_tts: { input: 0.6, output: 12.0 },
56
+ gpt4o_realtime: { input: 5.0, output: 20.0 },
57
+ gpt4o_search: { input: 2.5, output: 10.0 },
58
+ gpt4o_transcribe: { input: 2.5, output: 10.0, audio_input: 6.0 },
59
+ o1: { input: 15.0, output: 60.0 },
60
+ o1_mini: { input: 1.1, output: 4.4 },
61
+ o1_pro: { input: 150.0, output: 600.0 },
62
+ o3_mini: { input: 1.1, output: 4.4 },
63
+ babbage: { input: 0.4, output: 0.4 },
64
+ davinci: { input: 2.0, output: 2.0 },
65
+ embedding3_large: { price: 0.13 },
66
+ embedding3_small: { price: 0.02 },
67
+ embedding_ada: { price: 0.10 },
68
+ tts1: { price: 15.0 },
69
+ tts1_hd: { price: 30.0 },
70
+ whisper: { price: 0.006 },
71
+ moderation: { price: 0.0 }
72
+ };
73
+ export class Capabilities {
74
+ static getFamily(modelId) {
75
+ for (const [family, pattern] of Object.entries(MODEL_PATTERNS)) {
76
+ if (pattern.test(modelId)) {
77
+ return family;
78
+ }
79
+ }
80
+ return "other";
81
+ }
82
+ static getContextWindow(modelId) {
83
+ const family = this.getFamily(modelId);
84
+ switch (family) {
85
+ case "gpt41":
86
+ case "gpt41_mini":
87
+ case "gpt41_nano":
88
+ return 1_047_576;
89
+ case "gpt5":
90
+ case "gpt5_mini":
91
+ case "gpt5_nano":
92
+ case "chatgpt4o":
93
+ case "gpt4_turbo":
94
+ case "gpt4o":
95
+ case "gpt4o_audio":
96
+ case "gpt4o_mini":
97
+ case "gpt4o_mini_audio":
98
+ case "gpt4o_mini_realtime":
99
+ case "gpt4o_realtime":
100
+ case "gpt4o_search":
101
+ case "gpt4o_transcribe":
102
+ case "o1_mini":
103
+ return 128_000;
104
+ case "gpt4":
105
+ return 8_192;
106
+ case "gpt4o_mini_transcribe":
107
+ return 16_000;
108
+ case "o1":
109
+ case "o1_pro":
110
+ case "o3_mini":
111
+ return 200_000;
112
+ case "gpt35_turbo":
113
+ return 16_385;
114
+ case "gpt4o_mini_tts":
115
+ case "tts1":
116
+ case "tts1_hd":
117
+ case "whisper":
118
+ case "moderation":
119
+ case "embedding3_large":
120
+ case "embedding3_small":
121
+ case "embedding_ada":
122
+ return null;
123
+ default:
124
+ return 4_096;
125
+ }
126
+ }
127
+ static getMaxOutputTokens(modelId) {
128
+ const family = this.getFamily(modelId);
129
+ switch (family) {
130
+ case "gpt5":
131
+ case "gpt5_mini":
132
+ case "gpt5_nano":
133
+ return 400_000;
134
+ case "gpt41":
135
+ case "gpt41_mini":
136
+ case "gpt41_nano":
137
+ return 32_768;
138
+ case "chatgpt4o":
139
+ case "gpt4o":
140
+ case "gpt4o_mini":
141
+ return 16_384;
142
+ case "babbage":
143
+ case "davinci":
144
+ return 16_384;
145
+ case "gpt4":
146
+ return 8_192;
147
+ case "gpt35_turbo":
148
+ return 4_096;
149
+ case "gpt4_turbo":
150
+ case "gpt4o_realtime":
151
+ case "gpt4o_mini_realtime":
152
+ return 4_096;
153
+ case "gpt4o_mini_transcribe":
154
+ return 2_000;
155
+ case "o1":
156
+ case "o1_pro":
157
+ case "o3_mini":
158
+ return 100_000;
159
+ case "o1_mini":
160
+ return 65_536;
161
+ case "gpt4o_mini_tts":
162
+ case "tts1":
163
+ case "tts1_hd":
164
+ case "whisper":
165
+ case "moderation":
166
+ case "embedding3_large":
167
+ case "embedding3_small":
168
+ case "embedding_ada":
169
+ return null;
170
+ default:
171
+ return 16_384;
172
+ }
173
+ }
174
+ static supportsVision(modelId) {
175
+ const family = this.getFamily(modelId);
176
+ return [
177
+ "gpt5", "gpt5_mini", "gpt5_nano", "gpt41", "gpt41_mini", "gpt41_nano",
178
+ "chatgpt4o", "gpt4", "gpt4_turbo", "gpt4o", "gpt4o_mini", "o1", "o1_pro",
179
+ "moderation", "gpt4o_search", "gpt4o_mini_search"
180
+ ].includes(family);
181
+ }
182
+ static supportsTools(modelId) {
183
+ const family = this.getFamily(modelId);
184
+ return [
185
+ "gpt5", "gpt5_mini", "gpt5_nano", "gpt41", "gpt41_mini", "gpt41_nano",
186
+ "gpt4", "gpt4_turbo", "gpt4o", "gpt4o_mini", "o1", "o1_pro", "o3_mini"
187
+ ].includes(family);
188
+ }
189
+ static supportsStructuredOutput(modelId) {
190
+ const family = this.getFamily(modelId);
191
+ return [
192
+ "gpt5", "gpt5_mini", "gpt5_nano", "gpt41", "gpt41_mini", "gpt41_nano",
193
+ "chatgpt4o", "gpt4o", "gpt4o_mini", "o1", "o1_pro", "o3_mini"
194
+ ].includes(family);
195
+ }
196
+ static supportsJsonMode(modelId) {
197
+ return this.supportsStructuredOutput(modelId);
198
+ }
199
+ static getInputPrice(modelId) {
200
+ const family = this.getFamily(modelId);
201
+ const prices = PRICES[family] || { input: 0.5 };
202
+ return prices.input || prices.price || 0.5;
203
+ }
204
+ static getCachedInputPrice(modelId) {
205
+ const family = this.getFamily(modelId);
206
+ const prices = PRICES[family] || {};
207
+ return prices.cached_input;
208
+ }
209
+ static getOutputPrice(modelId) {
210
+ const family = this.getFamily(modelId);
211
+ const prices = PRICES[family] || { output: 1.5 };
212
+ return prices.output || prices.price || 1.5;
213
+ }
214
+ static getModelType(modelId) {
215
+ const family = this.getFamily(modelId);
216
+ if (/embedding/.test(family))
217
+ return "embedding";
218
+ if (/^tts|whisper|gpt4o_(?:mini_)?(?:transcribe|tts)$/.test(family))
219
+ return "audio";
220
+ if (family === "moderation")
221
+ return "moderation";
222
+ if (/dall/.test(family))
223
+ return "image";
224
+ return "chat";
225
+ }
226
+ static formatDisplayName(modelId) {
227
+ const humanized = modelId.replace(/-/g, " ").split(" ").map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
228
+ return this.applySpecialFormatting(humanized);
229
+ }
230
+ static applySpecialFormatting(name) {
231
+ return name
232
+ .replace(/(\d{4}) (\d{2}) (\d{2})/, "$1$2$3")
233
+ .replace(/^(?:Gpt|Chatgpt|Tts|Dall E) /g, (m) => this.specialPrefixFormat(m.trim()))
234
+ .replace(/^O([13]) /g, "O$1-")
235
+ .replace(/^O[13] Mini/g, (m) => m.replace(" ", "-"))
236
+ .replace(/\d\.\d /g, (m) => m.replace(" ", "-"))
237
+ .replace(/4o (?=Mini|Preview|Turbo|Audio|Realtime|Transcribe|Tts)/g, "4o-")
238
+ .replace(/\bHd\b/g, "HD")
239
+ .replace(/(?:Omni|Text) Moderation/g, (m) => m.replace(" ", "-"))
240
+ .replace("Text Embedding", "text-embedding-");
241
+ }
242
+ static specialPrefixFormat(prefix) {
243
+ switch (prefix) {
244
+ case "Gpt": return "GPT-";
245
+ case "Chatgpt": return "ChatGPT-";
246
+ case "Tts": return "TTS-";
247
+ case "Dall E": return "DALL-E-";
248
+ default: return prefix + "-";
249
+ }
250
+ }
251
+ static normalizeTemperature(temperature, modelId) {
252
+ if (/^(o\d|gpt-5)/.test(modelId)) {
253
+ return 1.0;
254
+ }
255
+ if (/-search/.test(modelId)) {
256
+ return null;
257
+ }
258
+ return temperature;
259
+ }
260
+ static getModalities(modelId) {
261
+ const modalities = {
262
+ input: ["text"],
263
+ output: ["text"]
264
+ };
265
+ if (this.supportsVision(modelId))
266
+ modalities.input.push("image", "pdf");
267
+ if (/whisper|audio|tts|transcribe/.test(modelId))
268
+ modalities.input.push("audio");
269
+ if (/tts|audio/.test(modelId))
270
+ modalities.output.push("audio");
271
+ if (/dall-e|image/.test(modelId))
272
+ modalities.output.push("image");
273
+ if (/embedding/.test(modelId))
274
+ modalities.output.push("embeddings");
275
+ if (/moderation/.test(modelId))
276
+ modalities.output.push("moderation");
277
+ return modalities;
278
+ }
279
+ static getCapabilities(modelId) {
280
+ const capabilities = [];
281
+ if (!/moderation|embedding/.test(modelId))
282
+ capabilities.push("streaming");
283
+ if (this.supportsTools(modelId))
284
+ capabilities.push("function_calling");
285
+ if (this.supportsStructuredOutput(modelId))
286
+ capabilities.push("structured_output");
287
+ if (/embedding|batch/.test(modelId))
288
+ capabilities.push("batch");
289
+ if (/o\d|gpt-5|codex/.test(modelId))
290
+ capabilities.push("reasoning");
291
+ if (/gpt-4-turbo|gpt-4o/.test(modelId)) {
292
+ if (/vision/.test(modelId))
293
+ capabilities.push("image_generation");
294
+ if (/audio/.test(modelId)) {
295
+ capabilities.push("speech_generation", "transcription");
296
+ }
297
+ }
298
+ return capabilities;
299
+ }
300
+ static getPricing(modelId) {
301
+ const standardPricing = {
302
+ input_per_million: this.getInputPrice(modelId),
303
+ output_per_million: this.getOutputPrice(modelId)
304
+ };
305
+ const cachedPrice = this.getCachedInputPrice(modelId);
306
+ const pricing = {
307
+ text_tokens: {
308
+ standard: {
309
+ ...standardPricing,
310
+ ...(cachedPrice ? { cached_input_per_million: cachedPrice } : {})
311
+ }
312
+ }
313
+ };
314
+ if (/embedding|batch/.test(modelId)) {
315
+ pricing.text_tokens.batch = {
316
+ input_per_million: standardPricing.input_per_million * 0.5,
317
+ output_per_million: standardPricing.output_per_million * 0.5
318
+ };
319
+ }
320
+ return pricing;
321
+ }
322
+ }
@@ -0,0 +1,8 @@
1
+ import { ChatRequest, ChatResponse } from "../Provider.js";
2
+ export declare class OpenAIChat {
3
+ private readonly baseUrl;
4
+ private readonly apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ execute(request: ChatRequest): Promise<ChatResponse>;
7
+ }
8
+ //# sourceMappingURL=Chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI3D,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA+C3D"}
@@ -0,0 +1,47 @@
1
+ import { Capabilities } from "./Capabilities.js";
2
+ export class OpenAIChat {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl;
7
+ this.apiKey = apiKey;
8
+ }
9
+ async execute(request) {
10
+ const temperature = Capabilities.normalizeTemperature(request.temperature, request.model);
11
+ const body = {
12
+ model: request.model,
13
+ messages: request.messages,
14
+ };
15
+ if (temperature !== undefined) {
16
+ if (temperature !== null) {
17
+ body.temperature = temperature;
18
+ }
19
+ }
20
+ if (request.max_tokens) {
21
+ body.max_tokens = request.max_tokens;
22
+ }
23
+ if (request.tools) {
24
+ body.tools = request.tools;
25
+ }
26
+ const response = await fetch(`${this.baseUrl}/chat/completions`, {
27
+ method: "POST",
28
+ headers: {
29
+ "Authorization": `Bearer ${this.apiKey}`,
30
+ "Content-Type": "application/json",
31
+ },
32
+ body: JSON.stringify(body),
33
+ });
34
+ if (!response.ok) {
35
+ const errorText = await response.text();
36
+ throw new Error(`OpenAI error (${response.status}): ${errorText}`);
37
+ }
38
+ const json = (await response.json());
39
+ const message = json.choices[0]?.message;
40
+ const content = message?.content ?? null;
41
+ const tool_calls = message?.tool_calls;
42
+ if (!content && !tool_calls) {
43
+ throw new Error("OpenAI returned empty response");
44
+ }
45
+ return { content, tool_calls };
46
+ }
47
+ }
@@ -0,0 +1,8 @@
1
+ import { ModelInfo } from "../Provider.js";
2
+ export declare class OpenAIModels {
3
+ private readonly baseUrl;
4
+ private readonly apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ execute(): Promise<ModelInfo[]>;
7
+ }
8
+ //# sourceMappingURL=Models.d.ts.map
@@ -0,0 +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;AAG3C,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;CA4BtC"}
@@ -0,0 +1,35 @@
1
+ import { Capabilities } from "./Capabilities.js";
2
+ export class OpenAIModels {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl;
7
+ this.apiKey = apiKey;
8
+ }
9
+ async execute() {
10
+ const response = await fetch(`${this.baseUrl}/models`, {
11
+ headers: {
12
+ "Authorization": `Bearer ${this.apiKey}`,
13
+ },
14
+ });
15
+ if (!response.ok) {
16
+ const errorText = await response.text();
17
+ throw new Error(`OpenAI error (${response.status}): ${errorText}`);
18
+ }
19
+ const json = await response.json();
20
+ return json.data.map((model) => ({
21
+ id: model.id,
22
+ name: Capabilities.formatDisplayName(model.id),
23
+ provider: "openai",
24
+ family: Capabilities.getFamily(model.id),
25
+ context_window: Capabilities.getContextWindow(model.id),
26
+ max_output_tokens: Capabilities.getMaxOutputTokens(model.id),
27
+ modalities: Capabilities.getModalities(model.id),
28
+ capabilities: Capabilities.getCapabilities(model.id),
29
+ pricing: Capabilities.getPricing(model.id),
30
+ metadata: {
31
+ owned_by: model.owned_by,
32
+ },
33
+ }));
34
+ }
35
+ }
@@ -0,0 +1,23 @@
1
+ import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk } from "../Provider.js";
2
+ export interface OpenAIProviderOptions {
3
+ apiKey: string;
4
+ baseUrl?: string;
5
+ }
6
+ export declare class OpenAIProvider implements Provider {
7
+ private readonly options;
8
+ private readonly baseUrl;
9
+ private readonly chatHandler;
10
+ private readonly streamingHandler;
11
+ private readonly modelsHandler;
12
+ capabilities: {
13
+ supportsVision: (model: string) => boolean;
14
+ supportsTools: (model: string) => boolean;
15
+ supportsStructuredOutput: (model: string) => boolean;
16
+ getContextWindow: (model: string) => number | null;
17
+ };
18
+ constructor(options: OpenAIProviderOptions);
19
+ chat(request: ChatRequest): Promise<ChatResponse>;
20
+ stream(request: ChatRequest): AsyncGenerator<ChatChunk>;
21
+ listModels(): Promise<ModelInfo[]>;
22
+ }
23
+ //# sourceMappingURL=OpenAIProvider.d.ts.map
@@ -0,0 +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,MAAM,gBAAgB,CAAC;AAM3F,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,QAAQ;IAajC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZpC,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;IAEtC,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;kCACd,MAAM;MAChC;gBAE2B,OAAO,EAAE,qBAAqB;IAOrD,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;CAGzC"}
@@ -0,0 +1,33 @@
1
+ import { Capabilities } from "./Capabilities.js";
2
+ import { OpenAIChat } from "./Chat.js";
3
+ import { OpenAIStreaming } from "./Streaming.js";
4
+ import { OpenAIModels } from "./Models.js";
5
+ export class OpenAIProvider {
6
+ options;
7
+ baseUrl;
8
+ chatHandler;
9
+ streamingHandler;
10
+ modelsHandler;
11
+ capabilities = {
12
+ supportsVision: (model) => Capabilities.supportsVision(model),
13
+ supportsTools: (model) => Capabilities.supportsTools(model),
14
+ supportsStructuredOutput: (model) => Capabilities.supportsStructuredOutput(model),
15
+ getContextWindow: (model) => Capabilities.getContextWindow(model),
16
+ };
17
+ constructor(options) {
18
+ this.options = options;
19
+ this.baseUrl = options.baseUrl ?? "https://api.openai.com/v1";
20
+ this.chatHandler = new OpenAIChat(this.baseUrl, options.apiKey);
21
+ this.streamingHandler = new OpenAIStreaming(this.baseUrl, options.apiKey);
22
+ this.modelsHandler = new OpenAIModels(this.baseUrl, options.apiKey);
23
+ }
24
+ async chat(request) {
25
+ return this.chatHandler.execute(request);
26
+ }
27
+ async *stream(request) {
28
+ yield* this.streamingHandler.execute(request);
29
+ }
30
+ async listModels() {
31
+ return this.modelsHandler.execute();
32
+ }
33
+ }
@@ -0,0 +1,8 @@
1
+ import { ChatRequest, ChatChunk } from "../Provider.js";
2
+ export declare class OpenAIStreaming {
3
+ private readonly baseUrl;
4
+ private readonly apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ execute(request: ChatRequest): AsyncGenerator<ChatChunk>;
7
+ }
8
+ //# sourceMappingURL=Streaming.d.ts.map
@@ -0,0 +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;AAGxD,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;CAsDhE"}
@@ -0,0 +1,55 @@
1
+ import { Capabilities } from "./Capabilities.js";
2
+ export class OpenAIStreaming {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl;
7
+ this.apiKey = apiKey;
8
+ }
9
+ async *execute(request) {
10
+ const temperature = Capabilities.normalizeTemperature(request.temperature, request.model);
11
+ const body = {
12
+ model: request.model,
13
+ messages: request.messages,
14
+ stream: true,
15
+ };
16
+ if (temperature !== undefined && temperature !== null) {
17
+ body.temperature = temperature;
18
+ }
19
+ if (request.max_tokens) {
20
+ body.max_tokens = request.max_tokens;
21
+ }
22
+ const response = await fetch(`${this.baseUrl}/chat/completions`, {
23
+ method: "POST",
24
+ headers: {
25
+ "Authorization": `Bearer ${this.apiKey}`,
26
+ "Content-Type": "application/json",
27
+ },
28
+ body: JSON.stringify(body),
29
+ });
30
+ if (!response.body) {
31
+ throw new Error("No response body for streaming");
32
+ }
33
+ const reader = response.body.getReader();
34
+ const decoder = new TextDecoder();
35
+ while (true) {
36
+ const { value, done } = await reader.read();
37
+ if (done)
38
+ break;
39
+ const chunk = decoder.decode(value);
40
+ const lines = chunk.split("\n");
41
+ for (const line of lines) {
42
+ if (!line.startsWith("data: "))
43
+ continue;
44
+ const data = line.replace("data: ", "").trim();
45
+ if (data === "[DONE]")
46
+ return;
47
+ const json = JSON.parse(data);
48
+ const delta = json.choices?.[0]?.delta?.content;
49
+ if (delta) {
50
+ yield { content: delta };
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,2 @@
1
+ export declare function registerOpenAIProvider(): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/index.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,SAUrC"}