@ank1015/providers 0.0.1 → 0.0.2

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 (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -383
  3. package/dist/agent/conversation.d.ts +97 -0
  4. package/dist/agent/conversation.d.ts.map +1 -0
  5. package/dist/agent/conversation.js +328 -0
  6. package/dist/agent/conversation.js.map +1 -0
  7. package/dist/agent/runner.d.ts +37 -0
  8. package/dist/agent/runner.d.ts.map +1 -0
  9. package/dist/agent/runner.js +169 -0
  10. package/dist/agent/runner.js.map +1 -0
  11. package/dist/agent/tools/calculate.d.ts +15 -0
  12. package/dist/agent/tools/calculate.d.ts.map +1 -0
  13. package/dist/agent/tools/calculate.js +23 -0
  14. package/dist/agent/tools/calculate.js.map +1 -0
  15. package/dist/agent/tools/get-current-time.d.ts +15 -0
  16. package/dist/agent/tools/get-current-time.d.ts.map +1 -0
  17. package/dist/agent/tools/get-current-time.js +38 -0
  18. package/dist/agent/tools/get-current-time.js.map +1 -0
  19. package/dist/agent/tools/index.d.ts +3 -0
  20. package/dist/agent/tools/index.d.ts.map +1 -0
  21. package/dist/agent/tools/index.js +3 -0
  22. package/dist/agent/tools/index.js.map +1 -0
  23. package/dist/agent/types.d.ts +53 -31
  24. package/dist/agent/types.d.ts.map +1 -1
  25. package/dist/agent/types.js +1 -2
  26. package/dist/agent/utils.d.ts +14 -0
  27. package/dist/agent/utils.d.ts.map +1 -0
  28. package/dist/agent/utils.js +59 -0
  29. package/dist/agent/utils.js.map +1 -0
  30. package/dist/index.d.ts +16 -9
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +16 -28
  33. package/dist/index.js.map +1 -1
  34. package/dist/llm.d.ts +15 -0
  35. package/dist/llm.d.ts.map +1 -0
  36. package/dist/llm.js +92 -0
  37. package/dist/llm.js.map +1 -0
  38. package/dist/models.d.ts +8 -1
  39. package/dist/models.d.ts.map +1 -1
  40. package/dist/models.generated.d.ts +25 -112
  41. package/dist/models.generated.d.ts.map +1 -1
  42. package/dist/models.generated.js +72 -227
  43. package/dist/models.generated.js.map +1 -1
  44. package/dist/models.js +30 -32
  45. package/dist/models.js.map +1 -1
  46. package/dist/providers/google/complete.d.ts +3 -0
  47. package/dist/providers/google/complete.d.ts.map +1 -0
  48. package/dist/providers/google/complete.js +53 -0
  49. package/dist/providers/google/complete.js.map +1 -0
  50. package/dist/providers/google/index.d.ts +6 -0
  51. package/dist/providers/google/index.d.ts.map +1 -0
  52. package/dist/providers/google/index.js +6 -0
  53. package/dist/providers/google/index.js.map +1 -0
  54. package/dist/providers/google/stream.d.ts +3 -0
  55. package/dist/providers/google/stream.d.ts.map +1 -0
  56. package/dist/providers/{google.js → google/stream.js} +67 -231
  57. package/dist/providers/google/stream.js.map +1 -0
  58. package/dist/providers/google/types.d.ts +8 -0
  59. package/dist/providers/google/types.d.ts.map +1 -0
  60. package/dist/providers/google/types.js +2 -0
  61. package/dist/providers/google/types.js.map +1 -0
  62. package/dist/providers/google/utils.d.ts +30 -0
  63. package/dist/providers/google/utils.d.ts.map +1 -0
  64. package/dist/providers/google/utils.js +354 -0
  65. package/dist/providers/google/utils.js.map +1 -0
  66. package/dist/providers/openai/complete.d.ts +3 -0
  67. package/dist/providers/openai/complete.d.ts.map +1 -0
  68. package/dist/providers/openai/complete.js +57 -0
  69. package/dist/providers/openai/complete.js.map +1 -0
  70. package/dist/providers/openai/index.d.ts +4 -0
  71. package/dist/providers/openai/index.d.ts.map +1 -0
  72. package/dist/providers/openai/index.js +4 -0
  73. package/dist/providers/openai/index.js.map +1 -0
  74. package/dist/providers/openai/stream.d.ts +3 -0
  75. package/dist/providers/openai/stream.d.ts.map +1 -0
  76. package/dist/providers/{openai.js → openai/stream.js} +74 -152
  77. package/dist/providers/openai/stream.js.map +1 -0
  78. package/dist/providers/openai/types.d.ts +8 -0
  79. package/dist/providers/openai/types.d.ts.map +1 -0
  80. package/dist/providers/openai/types.js +2 -0
  81. package/dist/providers/openai/types.js.map +1 -0
  82. package/dist/providers/openai/utils.d.ts +13 -0
  83. package/dist/providers/openai/utils.d.ts.map +1 -0
  84. package/dist/providers/openai/utils.js +285 -0
  85. package/dist/providers/openai/utils.js.map +1 -0
  86. package/dist/types.d.ts +95 -87
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js +1 -9
  89. package/dist/types.js.map +1 -1
  90. package/dist/utils/event-stream.d.ts +2 -2
  91. package/dist/utils/event-stream.d.ts.map +1 -1
  92. package/dist/utils/event-stream.js +2 -7
  93. package/dist/utils/event-stream.js.map +1 -1
  94. package/dist/utils/json-parse.js +3 -6
  95. package/dist/utils/json-parse.js.map +1 -1
  96. package/dist/utils/overflow.d.ts +51 -0
  97. package/dist/utils/overflow.d.ts.map +1 -0
  98. package/dist/utils/overflow.js +106 -0
  99. package/dist/utils/overflow.js.map +1 -0
  100. package/dist/utils/sanitize-unicode.js +1 -4
  101. package/dist/utils/sanitize-unicode.js.map +1 -1
  102. package/dist/utils/uuid.d.ts +6 -0
  103. package/dist/utils/uuid.d.ts.map +1 -0
  104. package/dist/utils/uuid.js +9 -0
  105. package/dist/utils/uuid.js.map +1 -0
  106. package/dist/utils/validation.d.ts +10 -3
  107. package/dist/utils/validation.d.ts.map +1 -1
  108. package/dist/utils/validation.js +20 -12
  109. package/dist/utils/validation.js.map +1 -1
  110. package/package.json +45 -8
  111. package/biome.json +0 -43
  112. package/dist/agent/agent-loop.d.ts +0 -5
  113. package/dist/agent/agent-loop.d.ts.map +0 -1
  114. package/dist/agent/agent-loop.js +0 -219
  115. package/dist/agent/agent-loop.js.map +0 -1
  116. package/dist/providers/convert.d.ts +0 -6
  117. package/dist/providers/convert.d.ts.map +0 -1
  118. package/dist/providers/convert.js +0 -207
  119. package/dist/providers/convert.js.map +0 -1
  120. package/dist/providers/google.d.ts +0 -26
  121. package/dist/providers/google.d.ts.map +0 -1
  122. package/dist/providers/google.js.map +0 -1
  123. package/dist/providers/openai.d.ts +0 -17
  124. package/dist/providers/openai.d.ts.map +0 -1
  125. package/dist/providers/openai.js.map +0 -1
  126. package/dist/stream.d.ts +0 -4
  127. package/dist/stream.d.ts.map +0 -1
  128. package/dist/stream.js +0 -40
  129. package/dist/stream.js.map +0 -1
  130. package/dist/test-google-agent-loop.d.ts +0 -2
  131. package/dist/test-google-agent-loop.d.ts.map +0 -1
  132. package/dist/test-google-agent-loop.js +0 -186
  133. package/dist/test-google-agent-loop.js.map +0 -1
  134. package/dist/test-google.d.ts +0 -2
  135. package/dist/test-google.d.ts.map +0 -1
  136. package/dist/test-google.js +0 -41
  137. package/dist/test-google.js.map +0 -1
  138. package/src/agent/agent-loop.ts +0 -275
  139. package/src/agent/types.ts +0 -80
  140. package/src/index.ts +0 -72
  141. package/src/models.generated.ts +0 -314
  142. package/src/models.ts +0 -45
  143. package/src/providers/convert.ts +0 -222
  144. package/src/providers/google.ts +0 -496
  145. package/src/providers/openai.ts +0 -437
  146. package/src/stream.ts +0 -60
  147. package/src/types.ts +0 -198
  148. package/src/utils/event-stream.ts +0 -60
  149. package/src/utils/json-parse.ts +0 -28
  150. package/src/utils/sanitize-unicode.ts +0 -25
  151. package/src/utils/validation.ts +0 -69
  152. package/test/core/agent-loop.test.ts +0 -958
  153. package/test/core/stream.test.ts +0 -409
  154. package/test/data/red-circle.png +0 -0
  155. package/test/data/superintelligentwill.pdf +0 -0
  156. package/test/edge-cases/general.test.ts +0 -565
  157. package/test/integration/e2e.test.ts +0 -530
  158. package/test/models/cost.test.ts +0 -499
  159. package/test/models/registry.test.ts +0 -298
  160. package/test/providers/convert.test.ts +0 -846
  161. package/test/providers/google-schema.test.ts +0 -666
  162. package/test/providers/google-stream.test.ts +0 -369
  163. package/test/providers/openai-stream.test.ts +0 -251
  164. package/test/utils/event-stream.test.ts +0 -289
  165. package/test/utils/json-parse.test.ts +0 -344
  166. package/test/utils/sanitize-unicode.test.ts +0 -329
  167. package/test/utils/validation.test.ts +0 -614
  168. package/tsconfig.json +0 -21
  169. package/vitest.config.ts +0 -9
package/src/index.ts DELETED
@@ -1,72 +0,0 @@
1
- // ============================================================================
2
- // Main Functions
3
- // ============================================================================
4
- export { stream } from "./stream";
5
- export { agentLoop } from "./agent/agent-loop";
6
-
7
- // ============================================================================
8
- // Core Types
9
- // ============================================================================
10
- export type {
11
- // Message types
12
- Message,
13
- UserMessage,
14
- ToolResultMessage,
15
- NativeAssistantMessage,
16
- NativeOpenAIMessage,
17
-
18
- // Content types
19
- UserTextContent,
20
- UserImageContent,
21
- UserFileContent,
22
- AssistantTextContent,
23
- AssistantThinkingContent,
24
- AssistantToolCall,
25
- AbstractedImageContent,
26
-
27
- // Context and Configuration
28
- Context,
29
- Tool,
30
- Api,
31
- Model,
32
-
33
- // Streaming types
34
- AssistantMessage,
35
- AssistantMessageEvent,
36
- Usage,
37
- StopReason,
38
-
39
- // Provider options
40
- OptionsForApi,
41
- StreamFunction,
42
- } from "./types";
43
-
44
- // ============================================================================
45
- // Agent Types
46
- // ============================================================================
47
- export type {
48
- // Agent-specific types
49
- AgentContext,
50
- AgentTool,
51
- AgentToolResult,
52
- AgentEvent,
53
- AgentLoopConfig,
54
- QueuedMessage,
55
- } from "./agent/types";
56
-
57
- // ============================================================================
58
- // Models and Registry
59
- // ============================================================================
60
- export { MODELS } from "./models.generated";
61
- export { calculateCost } from "./models";
62
-
63
- // ============================================================================
64
- // Utilities
65
- // ============================================================================
66
- export { defineTool } from "./types";
67
- export type { ToolName, ToolNames } from "./types";
68
-
69
- // ============================================================================
70
- // Event Streams
71
- // ============================================================================
72
- export { EventStream, AssistantMessageEventStream } from "./utils/event-stream";
@@ -1,314 +0,0 @@
1
- // This file is auto-generated by scripts/generate-models.ts
2
- // Do not edit manually - run 'npm run generate-models' to update
3
-
4
- import type { Model } from "./types.js";
5
-
6
- export const MODELS = {
7
- // anthropic: {
8
- // "claude-haiku-4-5": {
9
- // id: "claude-haiku-4-5",
10
- // name: "Claude Haiku 4.5 (latest)",
11
- // api: "anthropic-messages",
12
- // provider: "anthropic",
13
- // baseUrl: "https://api.anthropic.com",
14
- // reasoning: true,
15
- // input: ["text", "image"],
16
- // cost: {
17
- // input: 1,
18
- // output: 5,
19
- // cacheRead: 0.1,
20
- // cacheWrite: 1.25,
21
- // },
22
- // contextWindow: 200000,
23
- // maxTokens: 64000,
24
- // } satisfies Model<"anthropic-messages">,
25
- // "claude-opus-4-5": {
26
- // id: "claude-opus-4-5",
27
- // name: "Claude Opus 4.5 (latest)",
28
- // api: "anthropic-messages",
29
- // provider: "anthropic",
30
- // baseUrl: "https://api.anthropic.com",
31
- // reasoning: true,
32
- // input: ["text", "image"],
33
- // cost: {
34
- // input: 5,
35
- // output: 25,
36
- // cacheRead: 0.5,
37
- // cacheWrite: 6.25,
38
- // },
39
- // contextWindow: 200000,
40
- // maxTokens: 64000,
41
- // } satisfies Model<"anthropic-messages">,
42
- // "claude-sonnet-4-5": {
43
- // id: "claude-sonnet-4-5",
44
- // name: "Claude Sonnet 4.5 (latest)",
45
- // api: "anthropic-messages",
46
- // provider: "anthropic",
47
- // baseUrl: "https://api.anthropic.com",
48
- // reasoning: true,
49
- // input: ["text", "image"],
50
- // cost: {
51
- // input: 3,
52
- // output: 15,
53
- // cacheRead: 0.3,
54
- // cacheWrite: 3.75,
55
- // },
56
- // contextWindow: 200000,
57
- // maxTokens: 64000,
58
- // } satisfies Model<"anthropic-messages">,
59
- // },
60
- google: {
61
- "gemini-2.5-flash-preview-05-20": {
62
- id: "gemini-2.5-flash-preview-05-20",
63
- name: "Gemini 2.5 Flash Preview 05-20",
64
- api: "google",
65
- baseUrl: "https://generativelanguage.googleapis.com/v1beta",
66
- reasoning: true,
67
- input: ["text", "image"],
68
- cost: {
69
- input: 0.15,
70
- output: 0.6,
71
- cacheRead: 0.0375,
72
- cacheWrite: 0,
73
- },
74
- contextWindow: 1048576,
75
- maxTokens: 65536,
76
- } satisfies Model<"google">,
77
- "gemini-flash-lite-latest": {
78
- id: "gemini-flash-lite-latest",
79
- name: "Gemini Flash-Lite Latest",
80
- api: "google",
81
- baseUrl: "https://generativelanguage.googleapis.com/v1beta",
82
- reasoning: true,
83
- input: ["text", "image", "file"],
84
- cost: {
85
- input: 0.1,
86
- output: 0.4,
87
- cacheRead: 0.025,
88
- cacheWrite: 0,
89
- },
90
- contextWindow: 1048576,
91
- maxTokens: 65536,
92
- } satisfies Model<"google">,
93
- "gemini-3-pro-preview": {
94
- id: "gemini-3-pro-preview",
95
- name: "Gemini 3 Pro Preview",
96
- api: "google",
97
- baseUrl: "https://generativelanguage.googleapis.com/v1beta",
98
- reasoning: true,
99
- input: ["text", "image", "file"],
100
- cost: {
101
- input: 2,
102
- output: 12,
103
- cacheRead: 0.2,
104
- cacheWrite: 0,
105
- },
106
- contextWindow: 1000000,
107
- maxTokens: 64000,
108
- } satisfies Model<"google">,
109
- "gemini-2.5-flash": {
110
- id: "gemini-2.5-flash",
111
- name: "Gemini 2.5 Flash",
112
- api: "google",
113
- baseUrl: "https://generativelanguage.googleapis.com/v1beta",
114
- reasoning: true,
115
- input: ["text", "image", "file"],
116
- cost: {
117
- input: 0.3,
118
- output: 2.5,
119
- cacheRead: 0.075,
120
- cacheWrite: 0,
121
- },
122
- contextWindow: 1048576,
123
- maxTokens: 65536,
124
- } satisfies Model<"google">,
125
- },
126
- openai: {
127
- "gpt-5.1-codex": {
128
- id: "gpt-5.1-codex",
129
- name: "GPT-5.1 Codex",
130
- api: "openai",
131
- baseUrl: "https://api.openai.com/v1",
132
- reasoning: true,
133
- input: ["text", "image", "file"],
134
- cost: {
135
- input: 1.25,
136
- output: 10,
137
- cacheRead: 0.125,
138
- cacheWrite: 0,
139
- },
140
- contextWindow: 400000,
141
- maxTokens: 128000,
142
- } satisfies Model<"openai">,
143
- "gpt-5.1-codex-mini": {
144
- id: "gpt-5.1-codex-mini",
145
- name: "GPT-5.1 Codex mini",
146
- api: "openai",
147
- baseUrl: "https://api.openai.com/v1",
148
- reasoning: true,
149
- input: ["text", "image", "file"],
150
- cost: {
151
- input: 0.25,
152
- output: 2,
153
- cacheRead: 0.025,
154
- cacheWrite: 0,
155
- },
156
- contextWindow: 400000,
157
- maxTokens: 128000,
158
- } satisfies Model<"openai">,
159
- "gpt-5.1": {
160
- id: "gpt-5.1",
161
- name: "GPT-5.1",
162
- api: "openai",
163
- baseUrl: "https://api.openai.com/v1",
164
- reasoning: true,
165
- input: ["text", "image", "file"],
166
- cost: {
167
- input: 1.25,
168
- output: 10,
169
- cacheRead: 0.13,
170
- cacheWrite: 0,
171
- },
172
- contextWindow: 400000,
173
- maxTokens: 128000,
174
- } satisfies Model<"openai">,
175
- "codex-mini-latest": {
176
- id: "codex-mini-latest",
177
- name: "Codex Mini",
178
- api: "openai",
179
- baseUrl: "https://api.openai.com/v1",
180
- reasoning: true,
181
- input: ["text"],
182
- cost: {
183
- input: 1.5,
184
- output: 6,
185
- cacheRead: 0.375,
186
- cacheWrite: 0,
187
- },
188
- contextWindow: 200000,
189
- maxTokens: 100000,
190
- } satisfies Model<"openai">,
191
- "gpt-5-nano": {
192
- id: "gpt-5-nano",
193
- name: "GPT-5 Nano",
194
- api: "openai",
195
- baseUrl: "https://api.openai.com/v1",
196
- reasoning: true,
197
- input: ["text", "image", "file"],
198
- cost: {
199
- input: 0.05,
200
- output: 0.4,
201
- cacheRead: 0.01,
202
- cacheWrite: 0,
203
- },
204
- contextWindow: 400000,
205
- maxTokens: 128000,
206
- } satisfies Model<"openai">,
207
- "gpt-5-codex": {
208
- id: "gpt-5-codex",
209
- name: "GPT-5-Codex",
210
- api: "openai",
211
- baseUrl: "https://api.openai.com/v1",
212
- reasoning: true,
213
- input: ["text", "image", "file"],
214
- cost: {
215
- input: 1.25,
216
- output: 10,
217
- cacheRead: 0.125,
218
- cacheWrite: 0,
219
- },
220
- contextWindow: 400000,
221
- maxTokens: 128000,
222
- } satisfies Model<"openai">,
223
- "gpt-5-mini": {
224
- id: "gpt-5-mini",
225
- name: "GPT-5 Mini",
226
- api: "openai",
227
- baseUrl: "https://api.openai.com/v1",
228
- reasoning: true,
229
- input: ["text", "image", "file"],
230
- cost: {
231
- input: 0.25,
232
- output: 2,
233
- cacheRead: 0.03,
234
- cacheWrite: 0,
235
- },
236
- contextWindow: 400000,
237
- maxTokens: 128000,
238
- } satisfies Model<"openai">,
239
- "gpt-5.1-codex-max": {
240
- id: "gpt-5.1-codex-max",
241
- name: "GPT-5.1 Codex Max",
242
- api: "openai",
243
- baseUrl: "https://api.openai.com/v1",
244
- reasoning: true,
245
- input: ["text", "image", "file"],
246
- cost: {
247
- input: 1.25,
248
- output: 10,
249
- cacheRead: 0.125,
250
- cacheWrite: 0,
251
- },
252
- contextWindow: 400000,
253
- maxTokens: 128000,
254
- } satisfies Model<"openai">,
255
- "gpt-5": {
256
- id: "gpt-5",
257
- name: "GPT-5",
258
- api: "openai",
259
- baseUrl: "https://api.openai.com/v1",
260
- reasoning: true,
261
- input: ["text", "image", "file"],
262
- cost: {
263
- input: 1.25,
264
- output: 10,
265
- cacheRead: 0.13,
266
- cacheWrite: 0,
267
- },
268
- contextWindow: 400000,
269
- maxTokens: 128000,
270
- } satisfies Model<"openai">,
271
- "gpt-5-pro": {
272
- id: "gpt-5-pro",
273
- name: "GPT-5 Pro",
274
- api: "openai",
275
- baseUrl: "https://api.openai.com/v1",
276
- reasoning: true,
277
- input: ["text", "image", "file"],
278
- cost: {
279
- input: 15,
280
- output: 120,
281
- cacheRead: 0,
282
- cacheWrite: 0,
283
- },
284
- contextWindow: 400000,
285
- maxTokens: 272000,
286
- } satisfies Model<"openai">,
287
- "gpt-5.1-chat-latest": {
288
- id: "gpt-5.1-chat-latest",
289
- name: "GPT-5.1 Chat",
290
- api: "openai",
291
- baseUrl: "https://api.openai.com/v1",
292
- reasoning: true,
293
- input: ["text", "image", "file"],
294
- cost: {
295
- input: 1.25,
296
- output: 10,
297
- cacheRead: 0.125,
298
- cacheWrite: 0,
299
- },
300
- contextWindow: 128000,
301
- maxTokens: 16384,
302
- } satisfies Model<"openai">,
303
- },
304
- // groq: {
305
- // },
306
- // cerebras: {
307
- // },
308
- // xai: {
309
- // },
310
- // zai: {
311
- // },
312
- // openrouter: {
313
- // }
314
- } as const;
package/src/models.ts DELETED
@@ -1,45 +0,0 @@
1
- import { MODELS } from "./models.generated.js";
2
- import type { Api, Model, Usage } from "./types.js";
3
-
4
- const modelRegistry: Map<string, Map<string, Model<Api>>> = new Map();
5
-
6
- // Initialize registry from MODELS on module load
7
- for (const [provider, models] of Object.entries(MODELS)) {
8
- const providerModels = new Map<string, Model<Api>>();
9
- for (const [id, model] of Object.entries(models)) {
10
- providerModels.set(id, model as Model<Api>);
11
- }
12
- modelRegistry.set(provider, providerModels);
13
- }
14
-
15
- // type ModelApi<
16
- // TProvider extends KnownProvider,
17
- // TModelId extends keyof (typeof MODELS)[TProvider],
18
- // > = (typeof MODELS)[TProvider][TModelId] extends { api: infer TApi } ? (TApi extends Api ? TApi : never) : never;
19
-
20
- // export function getModel<TProvider extends KnownProvider, TModelId extends keyof (typeof MODELS)[TProvider]>(
21
- // provider: TProvider,
22
- // modelId: TModelId,
23
- // ): Model<ModelApi<TProvider, TModelId>> {
24
- // return modelRegistry.get(provider)?.get(modelId as string) as Model<ModelApi<TProvider, TModelId>>;
25
- // }
26
-
27
- // export function getProviders(): KnownProvider[] {
28
- // return Array.from(modelRegistry.keys()) as KnownProvider[];
29
- // }
30
-
31
- // export function getModels<TProvider extends KnownProvider>(
32
- // provider: TProvider,
33
- // ): Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[] {
34
- // const models = modelRegistry.get(provider);
35
- // return models ? (Array.from(models.values()) as Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[]) : [];
36
- // }
37
-
38
- export function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): Usage["cost"] {
39
- usage.cost.input = (model.cost.input / 1000000) * usage.input;
40
- usage.cost.output = (model.cost.output / 1000000) * usage.output;
41
- usage.cost.cacheRead = (model.cost.cacheRead / 1000000) * usage.cacheRead;
42
- usage.cost.cacheWrite = (model.cost.cacheWrite / 1000000) * usage.cacheWrite;
43
- usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
44
- return usage.cost;
45
- }
@@ -1,222 +0,0 @@
1
- import { Context, Model, Tool } from "../types";
2
- import { ResponseInput, ResponseInputItem, ResponseInputMessageContentList, ResponseInputImage, ResponseInputFile, ResponseInputText, ResponseFunctionCallOutputItemList } from "openai/resources/responses/responses.js";
3
- import { sanitizeSurrogates } from "../utils/sanitize-unicode";
4
- import { ContentListUnion, Part } from "@google/genai";
5
-
6
- export function buildOpenAIMessages(model: Model<'openai'> ,context: Context): ResponseInput {
7
-
8
- const openAIMessages: ResponseInput = [];
9
- if(context.systemPrompt){
10
- openAIMessages.push({
11
- role: 'developer',
12
- content: sanitizeSurrogates(context.systemPrompt)
13
- })
14
- };
15
-
16
- for(let i=0; i<context.messages.length; i++){
17
- const message = context.messages[i];
18
- // normalize for user message
19
- if(message.role === 'user'){
20
- const contents: ResponseInputMessageContentList = [];
21
- for (let p=0; p< message.content.length; p++){
22
- const content = message.content[p];
23
- if(content.type === 'text'){
24
- contents.push({
25
- type: 'input_text',
26
- text: content.content
27
- })
28
- }
29
- if(content.type === 'image' && model.input.includes("image")){
30
- contents.push({
31
- type: 'input_image',
32
- detail: 'auto',
33
- image_url: `data:${content.mimeType};base64,${content.data}`
34
- })
35
- }
36
- if(content.type === 'file' && model.input.includes("file")){
37
- contents.push({
38
- type: 'input_file',
39
- file_data: `data:${content.mimeType};base64,${content.data}`
40
- })
41
- }
42
- }
43
- openAIMessages.push({
44
- role: 'user',
45
- content: contents
46
- })
47
- }
48
-
49
- // normalize for tool results
50
- if(message.role === 'toolResult'){
51
- const toolOutputs: ResponseFunctionCallOutputItemList = []
52
- let hasText = false;
53
- let hasImg = false;
54
- let hasFile = false;
55
- for (let p=0; p< message.content.length; p++){
56
- const content = message.content[p];
57
- if(content.type === 'text'){
58
- toolOutputs.push({
59
- type: 'input_text',
60
- text: content.content
61
- })
62
- hasText = true;
63
- }
64
- if(content.type === 'image' && model.input.includes("image")){
65
- toolOutputs.push({
66
- type: 'input_image',
67
- detail: 'auto',
68
- image_url: `data:${content.mimeType};base64,${content.data}`
69
- })
70
- hasImg = true
71
- }
72
- if(content.type === 'file' && model.input.includes("file")){
73
- toolOutputs.push({
74
- type: 'input_file',
75
- file_data: `data:${content.mimeType};base64,${content.data}`
76
- })
77
- hasFile = true
78
- }
79
- }
80
- if(!hasText && (hasImg || hasFile)){
81
- toolOutputs.push({
82
- type: 'input_text',
83
- text: '(see attached)'
84
- })
85
- }
86
- const toolResultInput: ResponseInputItem.FunctionCallOutput = {
87
- call_id: message.toolCallId!,
88
- output: toolOutputs,
89
- type: 'function_call_output',
90
- }
91
- openAIMessages.push(toolResultInput)
92
- }
93
-
94
- // normalize for Assistant message
95
- if(message.role === 'assistant'){
96
- if(message._provider === 'openai'){
97
- for(let p=0; p<message.message.output.length; p++){
98
- const outputPart = message.message.output[p];
99
- if(outputPart.type === 'function_call' || outputPart.type === 'message' || outputPart.type === 'reasoning' ){
100
- openAIMessages.push(outputPart);
101
- }
102
- }
103
- }
104
- // TODO Implement other provider conversions
105
- else{
106
- throw new Error(
107
- `Cannot convert ${message._provider} assistant message to ${model.api} format. ` +
108
- `Cross-provider conversion for ${message._provider} → ${model.api} is not yet implemented.`
109
- );
110
- }
111
- }
112
-
113
- }
114
-
115
- return openAIMessages;
116
- }
117
-
118
-
119
- export function buildGoogleMessages(model: Model<'google'> ,context: Context): ContentListUnion {
120
- const contents: ContentListUnion = []
121
-
122
- for (let i=0; i< context.messages.length; i++){
123
- const message = context.messages[i];
124
-
125
- if(message.role === 'user'){
126
- const parts: Part[] = [];
127
- for(let p=0; p<message.content.length; p++){
128
- const messageContent = message.content[p];
129
- if(messageContent.type === 'text'){
130
- parts.push({
131
- text: messageContent.content
132
- })
133
- }
134
- if(messageContent.type === 'image' && model.input.includes("image")){
135
- parts.push({
136
- inlineData: {
137
- mimeType: messageContent.mimeType,
138
- data: messageContent.data
139
- }
140
- })
141
- }
142
- if(messageContent.type === 'file' && model.input.includes("file")){
143
- parts.push({
144
- inlineData: {
145
- mimeType: messageContent.mimeType,
146
- data: messageContent.data
147
- }
148
- })
149
- }
150
- }
151
- contents.push({
152
- role: 'user',
153
- parts
154
- })
155
- }
156
-
157
- if(message.role === 'toolResult'){
158
- const parts : Part[] = [];
159
- let textRes = '(see attached:)';
160
- for(let p=0; p<message.content.length; p++){
161
- const messageContent = message.content[p];
162
- if(messageContent.type === 'text'){
163
- textRes = messageContent.content
164
- }
165
- if(messageContent.type === 'image' && model.input.includes("image")){
166
- parts.push({
167
- inlineData: {
168
- mimeType: messageContent.mimeType,
169
- data: messageContent.data
170
- }
171
- })
172
- }
173
- if(messageContent.type === 'file' && model.input.includes("file")){
174
- parts.push({
175
- inlineData: {
176
- mimeType: messageContent.mimeType,
177
- data: messageContent.data
178
- }
179
- })
180
- }
181
- }
182
- contents.push({
183
- role: 'user',
184
- parts: [
185
- {
186
- functionResponse: {
187
- id: message.toolCallId,
188
- name: message.toolName,
189
- parts,
190
- response: {
191
- result: textRes,
192
- isError: message.isError
193
- }
194
- }
195
- }
196
- ]
197
- })
198
- }
199
-
200
- if(message.role === 'assistant'){
201
- if(message._provider === 'google'){
202
- if(message.message.candidates){
203
- for(let p=0; p< message.message.candidates?.length; p++){
204
- const candidate = message.message.candidates[p];
205
- if(candidate.content){
206
- contents.push(candidate.content)
207
- }
208
- }
209
- }
210
- }
211
- // TODO Implement other provider conversions
212
- else{
213
- throw new Error(
214
- `Cannot convert ${message._provider} assistant message to ${model.api} format. ` +
215
- `Cross-provider conversion for ${message._provider} → ${model.api} is not yet implemented.`
216
- );
217
- }
218
- }
219
-
220
- }
221
- return contents;
222
- }