@hebo-ai/gateway 0.1.2 → 0.2.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 (202) hide show
  1. package/README.md +172 -67
  2. package/dist/config.js +2 -12
  3. package/dist/endpoints/chat-completions/converters.d.ts +28 -24
  4. package/dist/endpoints/chat-completions/converters.js +99 -73
  5. package/dist/endpoints/chat-completions/handler.js +36 -30
  6. package/dist/endpoints/chat-completions/schema.d.ts +394 -272
  7. package/dist/endpoints/chat-completions/schema.js +124 -57
  8. package/dist/endpoints/embeddings/converters.d.ts +4 -4
  9. package/dist/endpoints/embeddings/converters.js +8 -9
  10. package/dist/endpoints/embeddings/handler.js +32 -26
  11. package/dist/endpoints/embeddings/schema.d.ts +28 -38
  12. package/dist/endpoints/embeddings/schema.js +10 -10
  13. package/dist/endpoints/models/converters.d.ts +2 -2
  14. package/dist/endpoints/models/converters.js +9 -12
  15. package/dist/endpoints/models/handler.js +8 -9
  16. package/dist/endpoints/models/schema.d.ts +37 -31
  17. package/dist/endpoints/models/schema.js +23 -12
  18. package/dist/gateway.d.ts +8 -9
  19. package/dist/gateway.js +7 -10
  20. package/dist/index.d.ts +2 -0
  21. package/dist/index.js +2 -0
  22. package/dist/lifecycle.d.ts +2 -0
  23. package/dist/{utils/hooks.js → lifecycle.js} +16 -8
  24. package/dist/middleware/common.d.ts +4 -0
  25. package/dist/middleware/common.js +44 -0
  26. package/dist/middleware/matcher.d.ts +18 -0
  27. package/dist/middleware/matcher.js +83 -0
  28. package/dist/models/amazon/index.d.ts +2 -0
  29. package/dist/models/amazon/index.js +2 -0
  30. package/dist/models/amazon/middleware.d.ts +2 -0
  31. package/dist/models/amazon/middleware.js +20 -0
  32. package/dist/models/amazon/presets.d.ts +2390 -0
  33. package/dist/models/amazon/presets.js +80 -0
  34. package/dist/models/anthropic/index.d.ts +2 -0
  35. package/dist/models/anthropic/index.js +2 -0
  36. package/dist/models/anthropic/middleware.d.ts +5 -0
  37. package/dist/models/anthropic/middleware.js +67 -0
  38. package/dist/models/anthropic/presets.d.ts +4106 -0
  39. package/dist/models/anthropic/presets.js +113 -0
  40. package/dist/models/catalog.d.ts +3 -1
  41. package/dist/models/catalog.js +3 -2
  42. package/dist/models/cohere/index.d.ts +2 -0
  43. package/dist/models/cohere/index.js +2 -0
  44. package/dist/models/cohere/middleware.d.ts +2 -0
  45. package/dist/models/cohere/middleware.js +18 -0
  46. package/dist/models/cohere/presets.d.ts +2918 -0
  47. package/dist/models/cohere/presets.js +129 -0
  48. package/dist/models/google/index.d.ts +2 -0
  49. package/dist/models/google/index.js +2 -0
  50. package/dist/models/google/middleware.d.ts +2 -0
  51. package/dist/models/google/middleware.js +20 -0
  52. package/dist/models/{presets/gemini.d.ts → google/presets.d.ts} +400 -174
  53. package/dist/models/{presets/gemini.js → google/presets.js} +20 -5
  54. package/dist/models/meta/index.d.ts +1 -0
  55. package/dist/models/meta/index.js +1 -0
  56. package/dist/models/meta/presets.d.ts +3254 -0
  57. package/dist/models/{presets/llama.js → meta/presets.js} +44 -7
  58. package/dist/models/openai/index.d.ts +2 -0
  59. package/dist/models/openai/index.js +2 -0
  60. package/dist/models/openai/middleware.d.ts +2 -0
  61. package/dist/models/openai/middleware.js +20 -0
  62. package/dist/models/openai/presets.d.ts +6252 -0
  63. package/dist/models/openai/presets.js +206 -0
  64. package/dist/models/types.d.ts +3 -3
  65. package/dist/models/types.js +27 -0
  66. package/dist/models/voyage/index.d.ts +2 -0
  67. package/dist/models/voyage/index.js +2 -0
  68. package/dist/models/voyage/middleware.d.ts +2 -0
  69. package/dist/models/voyage/middleware.js +18 -0
  70. package/dist/models/{presets/voyage.d.ts → voyage/presets.d.ts} +322 -323
  71. package/dist/providers/anthropic/canonical.d.ts +3 -0
  72. package/dist/providers/anthropic/canonical.js +9 -0
  73. package/dist/providers/anthropic/index.d.ts +1 -0
  74. package/dist/providers/anthropic/index.js +1 -0
  75. package/dist/providers/bedrock/canonical.d.ts +15 -0
  76. package/dist/providers/{canonical/bedrock.js → bedrock/canonical.js} +13 -15
  77. package/dist/providers/bedrock/index.d.ts +1 -0
  78. package/dist/providers/bedrock/index.js +1 -0
  79. package/dist/providers/cohere/canonical.d.ts +3 -0
  80. package/dist/providers/{canonical/cohere.js → cohere/canonical.js} +6 -6
  81. package/dist/providers/cohere/index.d.ts +1 -0
  82. package/dist/providers/cohere/index.js +1 -0
  83. package/dist/providers/groq/canonical.d.ts +3 -0
  84. package/dist/providers/groq/canonical.js +12 -0
  85. package/dist/providers/groq/index.d.ts +1 -0
  86. package/dist/providers/groq/index.js +1 -0
  87. package/dist/providers/openai/canonical.d.ts +3 -0
  88. package/dist/providers/openai/canonical.js +8 -0
  89. package/dist/providers/openai/index.d.ts +1 -0
  90. package/dist/providers/openai/index.js +1 -0
  91. package/dist/providers/registry.d.ts +16 -26
  92. package/dist/providers/registry.js +19 -26
  93. package/dist/providers/types.d.ts +1 -1
  94. package/dist/providers/types.js +1 -0
  95. package/dist/providers/vertex/canonical.d.ts +3 -0
  96. package/dist/providers/vertex/canonical.js +8 -0
  97. package/dist/providers/vertex/index.d.ts +1 -0
  98. package/dist/providers/vertex/index.js +1 -0
  99. package/dist/providers/voyage/canonical.d.ts +3 -0
  100. package/dist/providers/voyage/canonical.js +7 -0
  101. package/dist/providers/voyage/index.d.ts +1 -0
  102. package/dist/providers/voyage/index.js +1 -0
  103. package/dist/types.d.ts +60 -30
  104. package/dist/utils/errors.js +2 -0
  105. package/dist/utils/preset.d.ts +1 -7
  106. package/dist/utils/preset.js +1 -1
  107. package/dist/utils/response.d.ts +1 -0
  108. package/dist/utils/response.js +10 -0
  109. package/package.json +79 -70
  110. package/src/config.ts +2 -18
  111. package/src/endpoints/chat-completions/converters.test.ts +39 -0
  112. package/src/endpoints/chat-completions/converters.ts +191 -112
  113. package/src/endpoints/chat-completions/handler.test.ts +47 -18
  114. package/src/endpoints/chat-completions/handler.ts +40 -34
  115. package/src/endpoints/chat-completions/schema.ts +161 -88
  116. package/src/endpoints/embeddings/converters.ts +15 -11
  117. package/src/endpoints/embeddings/handler.test.ts +27 -30
  118. package/src/endpoints/embeddings/handler.ts +34 -28
  119. package/src/endpoints/embeddings/schema.ts +10 -10
  120. package/src/endpoints/models/converters.ts +22 -14
  121. package/src/endpoints/models/handler.test.ts +26 -29
  122. package/src/endpoints/models/handler.ts +10 -12
  123. package/src/endpoints/models/schema.ts +26 -20
  124. package/src/gateway.ts +10 -24
  125. package/src/index.ts +3 -0
  126. package/src/{utils/hooks.ts → lifecycle.ts} +21 -11
  127. package/src/middleware/common.ts +68 -0
  128. package/src/middleware/matcher.ts +117 -0
  129. package/src/models/amazon/index.ts +2 -0
  130. package/src/models/amazon/middleware.ts +25 -0
  131. package/src/models/amazon/presets.ts +104 -0
  132. package/src/models/anthropic/index.ts +2 -0
  133. package/src/models/anthropic/middleware.test.ts +184 -0
  134. package/src/models/anthropic/middleware.ts +75 -0
  135. package/src/models/anthropic/presets.ts +161 -0
  136. package/src/models/catalog.ts +10 -2
  137. package/src/models/cohere/index.ts +2 -0
  138. package/src/models/cohere/middleware.ts +23 -0
  139. package/src/models/cohere/presets.ts +181 -0
  140. package/src/models/google/index.ts +2 -0
  141. package/src/models/google/middleware.ts +25 -0
  142. package/src/models/{presets/gemini.ts → google/presets.ts} +25 -5
  143. package/src/models/meta/index.ts +1 -0
  144. package/src/models/{presets/llama.ts → meta/presets.ts} +68 -7
  145. package/src/models/openai/index.ts +2 -0
  146. package/src/models/openai/middleware.ts +25 -0
  147. package/src/models/openai/presets.ts +269 -0
  148. package/src/models/types.ts +29 -2
  149. package/src/models/voyage/index.ts +2 -0
  150. package/src/models/voyage/middleware.ts +23 -0
  151. package/src/providers/anthropic/canonical.ts +17 -0
  152. package/src/providers/anthropic/index.ts +1 -0
  153. package/src/providers/{canonical/bedrock.ts → bedrock/canonical.ts} +22 -32
  154. package/src/providers/bedrock/index.ts +1 -0
  155. package/src/providers/cohere/canonical.ts +26 -0
  156. package/src/providers/cohere/index.ts +1 -0
  157. package/src/providers/groq/canonical.ts +21 -0
  158. package/src/providers/groq/index.ts +1 -0
  159. package/src/providers/openai/canonical.ts +16 -0
  160. package/src/providers/openai/index.ts +1 -0
  161. package/src/providers/registry.test.ts +12 -10
  162. package/src/providers/registry.ts +43 -43
  163. package/src/providers/types.ts +1 -0
  164. package/src/providers/vertex/canonical.ts +17 -0
  165. package/src/providers/vertex/index.ts +1 -0
  166. package/src/providers/voyage/canonical.ts +16 -0
  167. package/src/providers/voyage/index.ts +1 -0
  168. package/src/types.ts +64 -28
  169. package/src/utils/errors.ts +2 -0
  170. package/src/utils/preset.ts +2 -6
  171. package/src/utils/response.ts +15 -0
  172. package/dist/models/presets/claude.d.ts +0 -1165
  173. package/dist/models/presets/claude.js +0 -40
  174. package/dist/models/presets/cohere.d.ts +0 -383
  175. package/dist/models/presets/cohere.js +0 -26
  176. package/dist/models/presets/gpt-oss.d.ts +0 -779
  177. package/dist/models/presets/gpt-oss.js +0 -40
  178. package/dist/models/presets/llama.d.ts +0 -1400
  179. package/dist/providers/canonical/anthropic.d.ts +0 -25
  180. package/dist/providers/canonical/anthropic.js +0 -14
  181. package/dist/providers/canonical/bedrock.d.ts +0 -26
  182. package/dist/providers/canonical/cohere.d.ts +0 -17
  183. package/dist/providers/canonical/groq.d.ts +0 -17
  184. package/dist/providers/canonical/groq.js +0 -10
  185. package/dist/providers/canonical/openai.d.ts +0 -17
  186. package/dist/providers/canonical/openai.js +0 -8
  187. package/dist/providers/canonical/vertex.d.ts +0 -17
  188. package/dist/providers/canonical/vertex.js +0 -10
  189. package/dist/providers/canonical/voyage.d.ts +0 -17
  190. package/dist/providers/canonical/voyage.js +0 -8
  191. package/dist/utils/hooks.d.ts +0 -2
  192. package/src/models/presets/claude.ts +0 -59
  193. package/src/models/presets/cohere.ts +0 -37
  194. package/src/models/presets/gpt-oss.ts +0 -55
  195. package/src/providers/canonical/anthropic.ts +0 -32
  196. package/src/providers/canonical/cohere.ts +0 -36
  197. package/src/providers/canonical/groq.ts +0 -25
  198. package/src/providers/canonical/openai.ts +0 -16
  199. package/src/providers/canonical/vertex.ts +0 -18
  200. package/src/providers/canonical/voyage.ts +0 -16
  201. package/dist/models/{presets/voyage.js → voyage/presets.js} +10 -10
  202. package/src/models/{presets/voyage.ts → voyage/presets.ts} +10 -10
@@ -1,24 +1,24 @@
1
- import * as z from "zod/mini";
2
- export const CompletionsContentPartTextSchema = z.object({
1
+ import * as z from "zod";
2
+ export const ChatCompletionsContentPartTextSchema = z.object({
3
3
  type: z.literal("text"),
4
4
  text: z.string(),
5
5
  });
6
- export const CompletionsContentPartImageSchema = z.object({
6
+ export const ChatCompletionsContentPartImageSchema = z.object({
7
7
  type: z.literal("image_url"),
8
8
  image_url: z.object({
9
9
  url: z.string(),
10
- detail: z.optional(z.union([z.literal("low"), z.literal("high"), z.literal("auto")])),
10
+ detail: z.union([z.literal("low"), z.literal("high"), z.literal("auto")]).optional(),
11
11
  }),
12
12
  });
13
- export const CompletionsContentPartFileSchema = z.object({
13
+ export const ChatCompletionsContentPartFileSchema = z.object({
14
14
  type: z.literal("file"),
15
15
  file: z.object({
16
16
  data: z.string(),
17
17
  media_type: z.string(),
18
- filename: z.string(),
18
+ filename: z.string().optional(),
19
19
  }),
20
20
  });
21
- export const CompletionsToolCallSchema = z.object({
21
+ export const ChatCompletionsToolCallSchema = z.object({
22
22
  type: z.literal("function"),
23
23
  id: z.string(),
24
24
  function: z.object({
@@ -26,51 +26,59 @@ export const CompletionsToolCallSchema = z.object({
26
26
  name: z.string(),
27
27
  }),
28
28
  });
29
- export const CompletionsSystemMessageSchema = z.object({
29
+ export const ChatCompletionsSystemMessageSchema = z.object({
30
30
  role: z.literal("system"),
31
31
  content: z.string(),
32
+ name: z.string().optional(),
32
33
  });
33
- export const CompletionsUserMessageSchema = z.object({
34
+ export const ChatCompletionsUserMessageSchema = z.object({
34
35
  role: z.literal("user"),
35
36
  content: z.union([
36
37
  z.string(),
37
38
  z.array(z.union([
38
- CompletionsContentPartTextSchema,
39
- CompletionsContentPartImageSchema,
40
- CompletionsContentPartFileSchema,
39
+ ChatCompletionsContentPartTextSchema,
40
+ ChatCompletionsContentPartImageSchema,
41
+ ChatCompletionsContentPartFileSchema,
41
42
  ])),
42
43
  ]),
44
+ name: z.string().optional(),
43
45
  });
44
- export const CompletionsAssistantMessageSchema = z.object({
46
+ export const ChatCompletionsAssistantMessageSchema = z.object({
45
47
  role: z.literal("assistant"),
46
- content: z.union([z.string(), z.null()]),
47
- tool_calls: z.optional(z.array(CompletionsToolCallSchema)),
48
- reasoning: z.optional(z.string()),
49
- reasoning_content: z.optional(z.string()),
48
+ // FUTURE: this should support arrays of TextContentPart and RefusalContentPart
49
+ content: z.union([z.string(), z.null()]).optional(),
50
+ name: z.string().optional(),
51
+ // FUTURE: This should also support Custom Tool Calls
52
+ tool_calls: z.array(ChatCompletionsToolCallSchema).optional(),
53
+ // Extensions
54
+ reasoning_content: z.string().optional().meta({ extension: true }),
50
55
  });
51
- export const CompletionsToolMessageSchema = z.object({
56
+ export const ChatCompletionsToolMessageSchema = z.object({
52
57
  role: z.literal("tool"),
58
+ // FUTURE: this should also support arrays of TextContentParts
53
59
  content: z.string(),
54
60
  tool_call_id: z.string(),
55
61
  });
56
- export const CompletionsMessageSchema = z.union([
57
- CompletionsSystemMessageSchema,
58
- CompletionsUserMessageSchema,
59
- CompletionsAssistantMessageSchema,
60
- CompletionsToolMessageSchema,
62
+ export const ChatCompletionsMessageSchema = z.union([
63
+ ChatCompletionsSystemMessageSchema,
64
+ ChatCompletionsUserMessageSchema,
65
+ ChatCompletionsAssistantMessageSchema,
66
+ ChatCompletionsToolMessageSchema,
61
67
  ]);
62
- export const CompletionsToolSchema = z.object({
68
+ export const ChatCompletionsToolSchema = z.object({
63
69
  type: z.literal("function"),
64
70
  function: z.object({
65
71
  name: z.string(),
66
- description: z.optional(z.string()),
72
+ description: z.string().optional(),
67
73
  parameters: z.record(z.string(), z.any()),
74
+ // Missing strict parameter
68
75
  }),
69
76
  });
70
- export const CompletionsToolChoiceSchema = z.union([
77
+ export const ChatCompletionsToolChoiceSchema = z.union([
71
78
  z.literal("none"),
72
79
  z.literal("auto"),
73
80
  z.literal("required"),
81
+ // FUTURE: missing AllowedTools and CustomToolChoice
74
82
  z.object({
75
83
  type: z.literal("function"),
76
84
  function: z.object({
@@ -78,46 +86,105 @@ export const CompletionsToolChoiceSchema = z.union([
78
86
  }),
79
87
  }),
80
88
  ]);
81
- export const CompletionsInputsSchema = z.object({
82
- messages: z.array(CompletionsMessageSchema),
83
- tools: z.optional(z.array(CompletionsToolSchema)),
84
- tool_choice: z.optional(CompletionsToolChoiceSchema),
85
- temperature: z.optional(z.number()),
89
+ export const ChatCompletionsReasoningEffortSchema = z.union([
90
+ z.literal("none"),
91
+ z.literal("minimal"),
92
+ z.literal("low"),
93
+ z.literal("medium"),
94
+ z.literal("high"),
95
+ z.literal("xhigh"),
96
+ ]);
97
+ export const ChatCompletionsReasoningConfigSchema = z.object({
98
+ enabled: z.optional(z.boolean()),
99
+ effort: z.optional(ChatCompletionsReasoningEffortSchema),
100
+ max_tokens: z.optional(z.number()),
101
+ exclude: z.optional(z.boolean()),
102
+ });
103
+ const ChatCompletionsInputsSchema = z.object({
104
+ messages: z.array(ChatCompletionsMessageSchema),
105
+ tools: z
106
+ .array(
107
+ // FUTURE: Missing CustomTool
108
+ ChatCompletionsToolSchema)
109
+ .optional(),
110
+ tool_choice: ChatCompletionsToolChoiceSchema.optional(),
111
+ temperature: z.number().min(0).max(2).optional(),
112
+ max_tokens: z.int().nonnegative().optional(),
113
+ max_completion_tokens: z.int().nonnegative().optional(),
114
+ frequency_penalty: z.number().min(-2.0).max(2.0).optional(),
115
+ presence_penalty: z.number().min(-2.0).max(2.0).optional(),
116
+ seed: z.int().optional(),
117
+ stop: z.union([z.string(), z.array(z.string())]).optional(),
118
+ top_p: z.number().min(0).max(1.0).optional(),
119
+ reasoning_effort: ChatCompletionsReasoningEffortSchema.optional(),
120
+ // Extensions
121
+ reasoning: ChatCompletionsReasoningConfigSchema.optional().meta({ extension: true }),
86
122
  });
87
- export const CompletionsBodySchema = z.extend(CompletionsInputsSchema, {
123
+ export const ChatCompletionsBodySchema = z.looseObject({
88
124
  model: z.string(),
89
- stream: z.optional(z.boolean()),
125
+ stream: z.boolean().optional(),
126
+ ...ChatCompletionsInputsSchema.shape,
90
127
  });
91
- export const CompletionsFinishReasonSchema = z.union([
128
+ export const ChatCompletionsFinishReasonSchema = z.union([
92
129
  z.literal("stop"),
93
130
  z.literal("length"),
94
131
  z.literal("content_filter"),
95
132
  z.literal("tool_calls"),
96
133
  ]);
97
- export const CompletionsChoiceSchema = z.object({
98
- index: z.number(),
99
- message: CompletionsAssistantMessageSchema,
100
- finish_reason: CompletionsFinishReasonSchema,
101
- logprobs: z.optional(z.any()),
102
- });
103
- export const CompletionsUsageSchema = z.object({
104
- prompt_tokens: z.number(),
105
- completion_tokens: z.number(),
106
- total_tokens: z.number(),
107
- completion_tokens_details: z.optional(z.object({
108
- reasoning_tokens: z.optional(z.number()),
109
- })),
110
- prompt_tokens_details: z.optional(z.object({
111
- cached_tokens: z.optional(z.number()),
112
- })),
113
- });
114
- export const CompletionsSchema = z.object({
134
+ export const ChatCompletionsChoiceSchema = z.object({
135
+ index: z.int().nonnegative(),
136
+ message: ChatCompletionsAssistantMessageSchema,
137
+ finish_reason: ChatCompletionsFinishReasonSchema,
138
+ // FUTURE: model this out
139
+ logprobs: z.any().optional(),
140
+ });
141
+ export const ChatCompletionsUsageSchema = z.object({
142
+ prompt_tokens: z.int().nonnegative().optional(),
143
+ completion_tokens: z.int().nonnegative().optional(),
144
+ total_tokens: z.int().nonnegative().optional(),
145
+ completion_tokens_details: z
146
+ .object({
147
+ // FUTURE: add missing properties
148
+ reasoning_tokens: z.int().nonnegative().optional(),
149
+ })
150
+ .optional(),
151
+ prompt_tokens_details: z
152
+ .object({
153
+ // FUTURE: add missing properties
154
+ cached_tokens: z.int().nonnegative().optional(),
155
+ })
156
+ .optional(),
157
+ });
158
+ export const ChatCompletionsSchema = z.object({
115
159
  id: z.string(),
116
160
  object: z.literal("chat.completion"),
117
- created: z.number(),
161
+ created: z.int().nonnegative(),
162
+ model: z.string(),
163
+ choices: z.array(ChatCompletionsChoiceSchema),
164
+ usage: ChatCompletionsUsageSchema.nullable(),
165
+ // Extensions
166
+ provider_metadata: z.any().optional().meta({ extension: true }),
167
+ });
168
+ export const ChatCompletionsToolCallDeltaSchema = ChatCompletionsToolCallSchema.partial().extend({
169
+ index: z.int().nonnegative(),
170
+ });
171
+ export const ChatCompletionsAssistantMessageDeltaSchema = ChatCompletionsAssistantMessageSchema.partial().extend({
172
+ tool_calls: z.array(ChatCompletionsToolCallDeltaSchema).optional(),
173
+ });
174
+ export const ChatCompletionsChoiceDeltaSchema = z.object({
175
+ index: z.int().nonnegative(),
176
+ delta: ChatCompletionsAssistantMessageDeltaSchema,
177
+ finish_reason: ChatCompletionsFinishReasonSchema.nullable(),
178
+ // FUTURE: model this out
179
+ logprobs: z.any().optional(),
180
+ });
181
+ export const ChatCompletionsChunkSchema = z.object({
182
+ id: z.string(),
183
+ object: z.literal("chat.completion.chunk"),
184
+ created: z.int().nonnegative(),
118
185
  model: z.string(),
119
- choices: z.array(CompletionsChoiceSchema),
120
- usage: z.optional(CompletionsUsageSchema),
121
- system_fingerprint: z.optional(z.string()),
122
- providerMetadata: z.optional(z.any()),
186
+ choices: z.array(ChatCompletionsChoiceDeltaSchema),
187
+ usage: ChatCompletionsUsageSchema.nullable(),
188
+ // Extensions
189
+ provider_metadata: z.any().optional().meta({ extension: true }),
123
190
  });
@@ -1,10 +1,10 @@
1
- import type { ProviderOptions } from "@ai-sdk/provider-utils";
1
+ import type { SharedV3ProviderOptions } from "@ai-sdk/provider";
2
2
  import type { EmbedManyResult } from "ai";
3
3
  import type { EmbeddingsInputs, Embeddings } from "./schema";
4
4
  export type EmbedCallOptions = {
5
5
  values: string[];
6
- providerOptions: ProviderOptions;
6
+ providerOptions: SharedV3ProviderOptions;
7
7
  };
8
- export declare function transformEmbeddingsInputs(params: EmbeddingsInputs): EmbedCallOptions;
8
+ export declare function convertToEmbedCallOptions(params: EmbeddingsInputs): EmbedCallOptions;
9
9
  export declare function toEmbeddings(embedManyResult: EmbedManyResult, modelId: string): Embeddings;
10
- export declare function createEmbeddingsResponse(embedManyResult: EmbedManyResult, modelId: string): Response;
10
+ export declare function createEmbeddingsResponse(embedManyResult: EmbedManyResult, modelId: string, responseInit?: ResponseInit): Response;
@@ -1,9 +1,10 @@
1
- export function transformEmbeddingsInputs(params) {
1
+ import { mergeResponseInit } from "../../utils/response";
2
+ export function convertToEmbedCallOptions(params) {
2
3
  const { input, ...rest } = params;
3
4
  return {
4
5
  values: Array.isArray(input) ? input : [input],
5
6
  providerOptions: {
6
- openAICompat: rest,
7
+ unknown: rest,
7
8
  },
8
9
  };
9
10
  }
@@ -14,19 +15,17 @@ export function toEmbeddings(embedManyResult, modelId) {
14
15
  index,
15
16
  }));
16
17
  const usage = {
17
- prompt_tokens: embedManyResult.usage?.tokens || 0,
18
- total_tokens: embedManyResult.usage?.tokens || 0,
18
+ prompt_tokens: embedManyResult.usage.tokens,
19
+ total_tokens: embedManyResult.usage.tokens,
19
20
  };
20
21
  return {
21
22
  object: "list",
22
23
  data,
23
24
  model: modelId,
24
25
  usage,
25
- providerMetadata: embedManyResult.providerMetadata,
26
+ provider_metadata: embedManyResult.providerMetadata,
26
27
  };
27
28
  }
28
- export function createEmbeddingsResponse(embedManyResult, modelId) {
29
- return new Response(JSON.stringify(toEmbeddings(embedManyResult, modelId)), {
30
- headers: { "Content-Type": "application/json" },
31
- });
29
+ export function createEmbeddingsResponse(embedManyResult, modelId, responseInit) {
30
+ return new Response(JSON.stringify(toEmbeddings(embedManyResult, modelId)), mergeResponseInit({ "Content-Type": "application/json" }, responseInit));
32
31
  }
@@ -1,20 +1,20 @@
1
- import { embedMany } from "ai";
1
+ import { embedMany, wrapEmbeddingModel } from "ai";
2
2
  import * as z from "zod/mini";
3
- import { parseConfig } from "../../config";
3
+ import { withLifecycle } from "../../lifecycle";
4
+ import { modelMiddlewareMatcher } from "../../middleware/matcher";
4
5
  import { resolveProvider } from "../../providers/registry";
5
6
  import { createErrorResponse } from "../../utils/errors";
6
- import { withHooks } from "../../utils/hooks";
7
- import { transformEmbeddingsInputs, createEmbeddingsResponse } from "./converters";
7
+ import { convertToEmbedCallOptions, createEmbeddingsResponse } from "./converters";
8
8
  import { EmbeddingsBodySchema } from "./schema";
9
9
  export const embeddings = (config) => {
10
- const { providers, models, hooks } = parseConfig(config);
11
- const handler = async (req) => {
12
- if (req.method !== "POST") {
10
+ const hooks = config.hooks;
11
+ const handler = async (ctx) => {
12
+ if (!ctx.request || ctx.request.method !== "POST") {
13
13
  return createErrorResponse("METHOD_NOT_ALLOWED", "Method Not Allowed", 405);
14
14
  }
15
15
  let body;
16
16
  try {
17
- body = await req.json();
17
+ body = await ctx.request.json();
18
18
  }
19
19
  catch {
20
20
  return createErrorResponse("BAD_REQUEST", "Invalid JSON", 400);
@@ -23,47 +23,53 @@ export const embeddings = (config) => {
23
23
  if (!parsed.success) {
24
24
  return createErrorResponse("UNPROCESSABLE_ENTITY", "Validation error", 422, z.prettifyError(parsed.error));
25
25
  }
26
- const { model: modelId, ...inputs } = parsed.data;
27
- let resolvedModelId;
26
+ ctx.body = parsed.data;
27
+ let inputs;
28
+ ({ model: ctx.modelId, ...inputs } = parsed.data);
28
29
  try {
29
- resolvedModelId = (await hooks?.resolveModelId?.({ modelId })) ?? modelId;
30
+ ctx.resolvedModelId = (await hooks?.resolveModelId?.(ctx)) ?? ctx.modelId;
30
31
  }
31
32
  catch (error) {
32
33
  return createErrorResponse("BAD_REQUEST", error, 400);
33
34
  }
34
- let embedOptions;
35
+ ctx.operation = "embeddings";
35
36
  try {
36
- embedOptions = transformEmbeddingsInputs(inputs);
37
+ const override = await hooks?.resolveProvider?.(ctx);
38
+ ctx.provider =
39
+ override ??
40
+ resolveProvider({
41
+ providers: ctx.providers,
42
+ models: ctx.models,
43
+ modelId: ctx.resolvedModelId,
44
+ operation: ctx.operation,
45
+ });
37
46
  }
38
47
  catch (error) {
39
48
  return createErrorResponse("BAD_REQUEST", error, 400);
40
49
  }
41
- let provider;
50
+ const embeddingModel = ctx.provider.embeddingModel(ctx.resolvedModelId);
51
+ let embedOptions;
42
52
  try {
43
- const args = {
44
- providers,
45
- models,
46
- modelId: resolvedModelId,
47
- operation: "embeddings",
48
- };
49
- const override = await hooks?.resolveProvider?.(args);
50
- provider = override ?? resolveProvider(args);
53
+ embedOptions = convertToEmbedCallOptions(inputs);
51
54
  }
52
55
  catch (error) {
53
56
  return createErrorResponse("BAD_REQUEST", error, 400);
54
57
  }
55
- const embeddingModel = provider.embeddingModel(resolvedModelId);
58
+ const embeddingModelWithMiddleware = wrapEmbeddingModel({
59
+ model: embeddingModel,
60
+ middleware: modelMiddlewareMatcher.forEmbedding(ctx.resolvedModelId, embeddingModel.provider),
61
+ });
56
62
  let result;
57
63
  try {
58
64
  result = await embedMany({
59
- model: embeddingModel,
65
+ model: embeddingModelWithMiddleware,
60
66
  ...embedOptions,
61
67
  });
62
68
  }
63
69
  catch (error) {
64
70
  return createErrorResponse("INTERNAL_SERVER_ERROR", error, 500);
65
71
  }
66
- return createEmbeddingsResponse(result, modelId);
72
+ return createEmbeddingsResponse(result, ctx.modelId);
67
73
  };
68
- return { handler: withHooks(hooks, handler) };
74
+ return { handler: withLifecycle(handler, config) };
69
75
  };
@@ -1,48 +1,38 @@
1
- import * as z from "zod/mini";
2
- export declare const EmbeddingsInputsSchema: z.ZodMiniObject<{
3
- input: z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>;
4
- encoding_format: z.ZodMiniOptional<z.ZodMiniEnum<{
5
- base64: "base64";
6
- float: "float";
7
- }>>;
8
- dimensions: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
9
- user: z.ZodMiniOptional<z.ZodMiniString<string>>;
1
+ import * as z from "zod";
2
+ export declare const EmbeddingsInputsSchema: z.ZodObject<{
3
+ input: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
4
+ dimensions: z.ZodOptional<z.ZodInt>;
10
5
  }, z.core.$strip>;
11
6
  export type EmbeddingsInputs = z.infer<typeof EmbeddingsInputsSchema>;
12
- export declare const EmbeddingsBodySchema: z.ZodMiniObject<{
13
- input: z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>;
14
- encoding_format: z.ZodMiniOptional<z.ZodMiniEnum<{
15
- base64: "base64";
16
- float: "float";
17
- }>>;
18
- dimensions: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
19
- user: z.ZodMiniOptional<z.ZodMiniString<string>>;
20
- model: z.ZodMiniString<string>;
21
- }, z.core.$strip>;
7
+ export declare const EmbeddingsBodySchema: z.ZodObject<{
8
+ input: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
9
+ dimensions: z.ZodOptional<z.ZodInt>;
10
+ model: z.ZodString;
11
+ }, z.core.$loose>;
22
12
  export type EmbeddingsBody = z.infer<typeof EmbeddingsBodySchema>;
23
- export declare const EmbeddingsDataSchema: z.ZodMiniObject<{
24
- object: z.ZodMiniLiteral<"embedding">;
25
- embedding: z.ZodMiniArray<z.ZodMiniNumber<number>>;
26
- index: z.ZodMiniNumber<number>;
13
+ export declare const EmbeddingsDataSchema: z.ZodObject<{
14
+ object: z.ZodLiteral<"embedding">;
15
+ embedding: z.ZodArray<z.ZodNumber>;
16
+ index: z.ZodInt;
27
17
  }, z.core.$strip>;
28
18
  export type EmbeddingsData = z.infer<typeof EmbeddingsDataSchema>;
29
- export declare const EmbeddingsUsageSchema: z.ZodMiniObject<{
30
- prompt_tokens: z.ZodMiniNumber<number>;
31
- total_tokens: z.ZodMiniNumber<number>;
19
+ export declare const EmbeddingsUsageSchema: z.ZodObject<{
20
+ prompt_tokens: z.ZodOptional<z.ZodInt>;
21
+ total_tokens: z.ZodOptional<z.ZodInt>;
32
22
  }, z.core.$strip>;
33
23
  export type EmbeddingsUsage = z.infer<typeof EmbeddingsUsageSchema>;
34
- export declare const EmbeddingsSchema: z.ZodMiniObject<{
35
- object: z.ZodMiniLiteral<"list">;
36
- data: z.ZodMiniArray<z.ZodMiniObject<{
37
- object: z.ZodMiniLiteral<"embedding">;
38
- embedding: z.ZodMiniArray<z.ZodMiniNumber<number>>;
39
- index: z.ZodMiniNumber<number>;
24
+ export declare const EmbeddingsSchema: z.ZodObject<{
25
+ object: z.ZodLiteral<"list">;
26
+ data: z.ZodArray<z.ZodObject<{
27
+ object: z.ZodLiteral<"embedding">;
28
+ embedding: z.ZodArray<z.ZodNumber>;
29
+ index: z.ZodInt;
30
+ }, z.core.$strip>>;
31
+ model: z.ZodString;
32
+ usage: z.ZodNullable<z.ZodObject<{
33
+ prompt_tokens: z.ZodOptional<z.ZodInt>;
34
+ total_tokens: z.ZodOptional<z.ZodInt>;
40
35
  }, z.core.$strip>>;
41
- model: z.ZodMiniString<string>;
42
- usage: z.ZodMiniObject<{
43
- prompt_tokens: z.ZodMiniNumber<number>;
44
- total_tokens: z.ZodMiniNumber<number>;
45
- }, z.core.$strip>;
46
- providerMetadata: z.ZodMiniOptional<z.ZodMiniAny>;
36
+ provider_metadata: z.ZodOptional<z.ZodAny>;
47
37
  }, z.core.$strip>;
48
38
  export type Embeddings = z.infer<typeof EmbeddingsSchema>;
@@ -1,26 +1,26 @@
1
- import * as z from "zod/mini";
1
+ import * as z from "zod";
2
2
  export const EmbeddingsInputsSchema = z.object({
3
3
  input: z.union([z.string(), z.array(z.string())]),
4
- encoding_format: z.optional(z.enum(["float", "base64"])),
5
- dimensions: z.optional(z.number()),
6
- user: z.optional(z.string()),
4
+ dimensions: z.int().nonnegative().max(65536).optional(),
7
5
  });
8
- export const EmbeddingsBodySchema = z.extend(EmbeddingsInputsSchema, {
6
+ export const EmbeddingsBodySchema = z.looseObject({
9
7
  model: z.string(),
8
+ ...EmbeddingsInputsSchema.shape,
10
9
  });
11
10
  export const EmbeddingsDataSchema = z.object({
12
11
  object: z.literal("embedding"),
13
12
  embedding: z.array(z.number()),
14
- index: z.number(),
13
+ index: z.int().nonnegative(),
15
14
  });
16
15
  export const EmbeddingsUsageSchema = z.object({
17
- prompt_tokens: z.number(),
18
- total_tokens: z.number(),
16
+ prompt_tokens: z.int().nonnegative().optional(),
17
+ total_tokens: z.int().nonnegative().optional(),
19
18
  });
20
19
  export const EmbeddingsSchema = z.object({
21
20
  object: z.literal("list"),
22
21
  data: z.array(EmbeddingsDataSchema),
23
22
  model: z.string(),
24
- usage: EmbeddingsUsageSchema,
25
- providerMetadata: z.optional(z.any()),
23
+ usage: EmbeddingsUsageSchema.nullable(),
24
+ // Extensions
25
+ provider_metadata: z.optional(z.any()).meta({ extension: true }),
26
26
  });
@@ -2,5 +2,5 @@ import type { ModelCatalog, CatalogModel } from "../../models/types";
2
2
  import type { ModelList, Model } from "./schema";
3
3
  export declare function toModel(id: string, catalogModel: CatalogModel): Model;
4
4
  export declare function toModels(models: ModelCatalog): ModelList;
5
- export declare function createModelsResponse(models: ModelCatalog): Response;
6
- export declare function createModelResponse(id: string, catalogModel: CatalogModel): Response;
5
+ export declare function createModelsResponse(models: ModelCatalog, responseInit?: ResponseInit): Response;
6
+ export declare function createModelResponse(id: string, catalogModel: CatalogModel, responseInit?: ResponseInit): Response;
@@ -1,3 +1,4 @@
1
+ import { mergeResponseInit } from "../../utils/response";
1
2
  export function toModel(id, catalogModel) {
2
3
  const { created, providers, modalities, additionalProperties, ...rest } = catalogModel;
3
4
  let createdTimestamp = Math.floor(Date.now() / 1000);
@@ -13,11 +14,11 @@ export function toModel(id, catalogModel) {
13
14
  created: createdTimestamp,
14
15
  owned_by: providers?.[0] || "system",
15
16
  architecture: {
16
- input_modalities: modalities.input || [],
17
- modality: modalities.input &&
18
- modalities.output &&
17
+ input_modalities: modalities?.input || [],
18
+ modality: modalities?.input &&
19
+ modalities?.output &&
19
20
  `${modalities.input?.[0]}->${modalities.output?.[0]}`,
20
- output_modalities: modalities.output || [],
21
+ output_modalities: modalities?.output || [],
21
22
  },
22
23
  endpoints: providers?.map((provider) => ({
23
24
  tag: provider,
@@ -33,13 +34,9 @@ export function toModels(models) {
33
34
  data: Object.entries(models).map(([id, catalogModel]) => toModel(id, catalogModel)),
34
35
  };
35
36
  }
36
- export function createModelsResponse(models) {
37
- return new Response(JSON.stringify(toModels(models)), {
38
- headers: { "Content-Type": "application/json" },
39
- });
37
+ export function createModelsResponse(models, responseInit) {
38
+ return new Response(JSON.stringify(toModels(models)), mergeResponseInit({ "Content-Type": "application/json" }, responseInit));
40
39
  }
41
- export function createModelResponse(id, catalogModel) {
42
- return new Response(JSON.stringify(toModel(id, catalogModel)), {
43
- headers: { "Content-Type": "application/json" },
44
- });
40
+ export function createModelResponse(id, catalogModel, responseInit) {
41
+ return new Response(JSON.stringify(toModel(id, catalogModel)), mergeResponseInit({ "Content-Type": "application/json" }, responseInit));
45
42
  }
@@ -1,17 +1,16 @@
1
- import { parseConfig } from "../../config";
1
+ import { withLifecycle } from "../../lifecycle";
2
2
  import { createErrorResponse } from "../../utils/errors";
3
- import { withHooks } from "../../utils/hooks";
4
3
  import { createModelsResponse, createModelResponse } from "./converters";
5
4
  export const models = (config) => {
6
- const { models, hooks } = parseConfig(config);
7
5
  // eslint-disable-next-line require-await
8
- const handler = async (req) => {
9
- if (req.method !== "GET") {
6
+ const handler = async (ctx) => {
7
+ const request = ctx.request;
8
+ if (!request || request.method !== "GET") {
10
9
  return createErrorResponse("METHOD_NOT_ALLOWED", "Method Not Allowed", 405);
11
10
  }
12
- const rawId = req.url.split("/models/", 2)[1]?.split("?", 1)[0];
11
+ const rawId = request.url.split("/models/", 2)[1]?.split("?", 1)[0];
13
12
  if (!rawId) {
14
- return createModelsResponse(models);
13
+ return createModelsResponse(ctx.models);
15
14
  }
16
15
  let modelId = rawId;
17
16
  try {
@@ -20,11 +19,11 @@ export const models = (config) => {
20
19
  catch {
21
20
  return createErrorResponse("BAD_REQUEST", "Invalid model ID", 400);
22
21
  }
23
- const model = models[modelId];
22
+ const model = ctx.models[modelId];
24
23
  if (!model) {
25
24
  return createErrorResponse("NOT_FOUND", `Model '${modelId}' not found`, 404);
26
25
  }
27
26
  return createModelResponse(modelId, model);
28
27
  };
29
- return { handler: withHooks(hooks, handler) };
28
+ return { handler: withLifecycle(handler, config) };
30
29
  };