@alumnium/codex 0.0.0-stage → 0.24.0-alpha.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.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Alexey Rodionov, Tatiana Shepeleva
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # Temporary Holding Version
1
+ # @alumnium/codex
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Alumnium Codex LLM provider. See [the main `alumnium` package page](https://www.npmjs.com/package/alumnium) for more details.
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "@alumnium/codex",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.24.0-alpha.2",
4
+ "description": "Alumnium Codex LLM provider",
5
+ "license": "MIT",
6
+ "author": "Alex Rodionov <p0deje@gmail.com>",
7
+ "contributors": [
8
+ "Alex Rodionov <p0deje@gmail.com>",
9
+ "Sasha Koss <koss@nocorp.me>",
10
+ "Tatiana Shepeleva <tati.shep@gmail.com>"
11
+ ],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/alumnium-hq/alumnium.git"
15
+ },
16
+ "files": [
17
+ "src",
18
+ "README.md",
19
+ "LICENSE.md"
20
+ ],
21
+ "type": "module",
22
+ "exports": {
23
+ ".": {
24
+ "import": {
25
+ "types": "./src/index.d.ts",
26
+ "default": "./src/index.js"
27
+ },
28
+ "require": {
29
+ "types": "./src/index.d.ts",
30
+ "default": "./src/index.cjs"
31
+ }
32
+ }
33
+ },
34
+ "dependencies": {
35
+ "@ai-sdk/openai": "^4.0.46",
36
+ "@ai-sdk/provider": "^4.0.7",
37
+ "@alumnium/core": "0.24.0-alpha.2",
38
+ "ai": "^7.0.78",
39
+ "openai-oauth": "1.0.2"
40
+ }
41
+ }
package/src/index.cjs ADDED
@@ -0,0 +1,341 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
8
+ var __toCommonJS = (from) => {
9
+ var entry = (__moduleCache ??= new WeakMap()).get(from),
10
+ desc;
11
+ if (entry) return entry;
12
+ entry = __defProp({}, "__esModule", { value: true });
13
+ if ((from && typeof from === "object") || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
19
+ });
20
+ }
21
+ __moduleCache.set(from, entry);
22
+ return entry;
23
+ };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
29
+ var __export = (target, all) => {
30
+ for (var name in all)
31
+ __defProp(target, name, {
32
+ get: all[name],
33
+ enumerable: true,
34
+ configurable: true,
35
+ set: __exportSetter.bind(all, name),
36
+ });
37
+ };
38
+
39
+ // codex/src/index.ts
40
+ var exports_src = {};
41
+ __export(exports_src, {
42
+ CodexLanguageModel: () => CodexLanguageModel,
43
+ codexProviders: () => codexProviders,
44
+ });
45
+ module.exports = __toCommonJS(exports_src);
46
+
47
+ // codex/src/llm/CodexLanguageModel.ts
48
+ var import_openai = require("@ai-sdk/openai");
49
+ var import_openai_oauth = require("openai-oauth");
50
+ var import_internal = require("@alumnium/core/internal");
51
+ var DUMMY_API_KEY = "codex-oauth";
52
+ var LITTERBOX_URL = "https://litterbox.catbox.moe/resources/internals/api.php";
53
+ var STRUCTURED_OUTPUT_TOOL = "__alumnium_structured_output";
54
+
55
+ class CodexLanguageModel {
56
+ specificationVersion = "v4";
57
+ provider = "codex";
58
+ modelId;
59
+ supportedUrls = {};
60
+ #server;
61
+ #serverPromise;
62
+ #delegate;
63
+ #options;
64
+ #uploader;
65
+ #litterboxUpload;
66
+ constructor(options) {
67
+ this.modelId = options.modelId;
68
+ this.#options = options;
69
+ this.#litterboxUpload =
70
+ options.litterboxUpload ??
71
+ import_internal.Env.LANGCHAIN_CODEX_LITTERBOX_UPLOAD;
72
+ this.#uploader = new LitterboxUploader(
73
+ options.litterboxTtl ?? "1h",
74
+ options.fetch ?? globalThis.fetch,
75
+ );
76
+ }
77
+ async doGenerate(options) {
78
+ const structuredTool = structuredOutputToolName(options);
79
+ const delegate = await this.#ensureDelegate();
80
+ const result = await delegate.doGenerate(
81
+ await this.#prepareOptions(options, structuredTool),
82
+ );
83
+ return structuredTool
84
+ ? translateStructuredResult(result, structuredTool)
85
+ : result;
86
+ }
87
+ async doStream(options) {
88
+ const structuredTool = structuredOutputToolName(options);
89
+ const delegate = await this.#ensureDelegate();
90
+ const result = await delegate.doStream(
91
+ await this.#prepareOptions(options, structuredTool),
92
+ );
93
+ if (!structuredTool) return result;
94
+ return {
95
+ ...result,
96
+ stream: result.stream.pipeThrough(structuredOutputStream(structuredTool)),
97
+ };
98
+ }
99
+ async close() {
100
+ if (!this.#serverPromise) return;
101
+ const server = await this.#serverPromise;
102
+ await server.close();
103
+ this.#server = undefined;
104
+ this.#serverPromise = undefined;
105
+ this.#delegate = undefined;
106
+ }
107
+ async #prepareOptions(options, structuredTool) {
108
+ const prompt = await replaceBase64Images(
109
+ options.prompt,
110
+ this.#litterboxUpload,
111
+ this.#uploader,
112
+ );
113
+ if (!structuredTool || options.responseFormat?.type !== "json") {
114
+ return { ...options, prompt };
115
+ }
116
+ return {
117
+ ...options,
118
+ prompt,
119
+ responseFormat: { type: "text" },
120
+ tools: [
121
+ ...(options.tools ?? []),
122
+ {
123
+ type: "function",
124
+ name: structuredTool,
125
+ description:
126
+ options.responseFormat.description ??
127
+ "Return the response in the required structured format.",
128
+ inputSchema: options.responseFormat.schema ?? { type: "object" },
129
+ strict: true,
130
+ },
131
+ ],
132
+ toolChoice: { type: "tool", toolName: structuredTool },
133
+ };
134
+ }
135
+ async #ensureDelegate() {
136
+ if (this.#delegate) return this.#delegate;
137
+ const server = await this.#ensureServer();
138
+ const createDelegate =
139
+ this.#options.createDelegate ?? defaultCreateDelegate;
140
+ this.#delegate = createDelegate(server.url, this.modelId);
141
+ return this.#delegate;
142
+ }
143
+ #ensureServer() {
144
+ if (this.#server) return Promise.resolve(this.#server);
145
+ if (!this.#serverPromise) {
146
+ const startServer =
147
+ this.#options.startServer ?? import_openai_oauth.startOpenAIOAuthServer;
148
+ this.#serverPromise = startServer({
149
+ host: "127.0.0.1",
150
+ port: 0,
151
+ ...this.#options.oauthServerOptions,
152
+ }).then((server) => {
153
+ this.#server = server;
154
+ server.server.unref();
155
+ return server;
156
+ });
157
+ }
158
+ return this.#serverPromise;
159
+ }
160
+ }
161
+ function defaultCreateDelegate(baseURL, modelId) {
162
+ return import_openai
163
+ .createOpenAI({ baseURL, apiKey: DUMMY_API_KEY, name: "codex" })
164
+ .chat(modelId);
165
+ }
166
+ function structuredOutputToolName(options) {
167
+ if (options.responseFormat?.type !== "json") return;
168
+ let name = STRUCTURED_OUTPUT_TOOL;
169
+ const toolNames = new Set(
170
+ options.tools?.map((tool) =>
171
+ tool.type === "function" ? tool.name : tool.name,
172
+ ),
173
+ );
174
+ while (toolNames.has(name)) name += "_";
175
+ return name;
176
+ }
177
+ function translateStructuredResult(result, toolName) {
178
+ const content = result.content.flatMap((part) =>
179
+ part.type === "tool-call" && part.toolName === toolName
180
+ ? [{ type: "text", text: part.input }]
181
+ : [part],
182
+ );
183
+ const hasText = content.some(
184
+ (part) => part.type === "text" && part.text.trim(),
185
+ );
186
+ return {
187
+ ...result,
188
+ content,
189
+ finishReason:
190
+ result.finishReason.unified === "tool-calls" ||
191
+ (result.finishReason.unified === "other" && hasText)
192
+ ? { unified: "stop", raw: result.finishReason.raw }
193
+ : result.finishReason,
194
+ };
195
+ }
196
+ function structuredOutputStream(toolName) {
197
+ let isStructuredTool = false;
198
+ return new TransformStream({
199
+ transform(part, controller) {
200
+ if (part.type === "tool-input-start" && part.toolName === toolName) {
201
+ isStructuredTool = true;
202
+ controller.enqueue({ type: "text-start", id: part.id });
203
+ } else if (part.type === "tool-input-delta" && isStructuredTool) {
204
+ controller.enqueue({
205
+ type: "text-delta",
206
+ id: part.id,
207
+ delta: part.delta,
208
+ });
209
+ } else if (part.type === "tool-input-end" && isStructuredTool) {
210
+ controller.enqueue({ type: "text-end", id: part.id });
211
+ isStructuredTool = false;
212
+ } else if (part.type === "tool-call" && part.toolName === toolName) {
213
+ } else if (
214
+ part.type === "finish" &&
215
+ part.finishReason.unified === "tool-calls"
216
+ ) {
217
+ controller.enqueue({
218
+ ...part,
219
+ finishReason: { unified: "stop", raw: part.finishReason.raw },
220
+ });
221
+ } else {
222
+ controller.enqueue(part);
223
+ }
224
+ },
225
+ });
226
+ }
227
+ async function replaceBase64Images(prompt, enabled, uploader) {
228
+ return Promise.all(
229
+ prompt.map(async (message) => {
230
+ if (message.role === "user") {
231
+ const content = await Promise.all(
232
+ message.content.map((part) =>
233
+ replaceBase64Image(part, enabled, uploader),
234
+ ),
235
+ );
236
+ return { ...message, content };
237
+ }
238
+ if (message.role === "assistant") {
239
+ const content = await Promise.all(
240
+ message.content.map((part) =>
241
+ replaceBase64Image(part, enabled, uploader),
242
+ ),
243
+ );
244
+ return { ...message, content };
245
+ }
246
+ return message;
247
+ }),
248
+ );
249
+ }
250
+ async function replaceBase64Image(part, enabled, uploader) {
251
+ if (
252
+ !part ||
253
+ typeof part !== "object" ||
254
+ !("type" in part) ||
255
+ part.type !== "file" ||
256
+ !("mediaType" in part) ||
257
+ typeof part.mediaType !== "string" ||
258
+ !part.mediaType.startsWith("image/") ||
259
+ !("data" in part) ||
260
+ !part.data ||
261
+ typeof part.data !== "object" ||
262
+ !("type" in part.data) ||
263
+ part.data.type !== "data" ||
264
+ !("data" in part.data) ||
265
+ (typeof part.data.data !== "string" &&
266
+ !(part.data.data instanceof Uint8Array))
267
+ ) {
268
+ return part;
269
+ }
270
+ if (!enabled) {
271
+ throw new Error(
272
+ "Codex models do not support inline images. Enable litterboxUpload or set LANGCHAIN_CODEX_LITTERBOX_UPLOAD=true to upload images to Litterbox.",
273
+ );
274
+ }
275
+ const base64 = imageBase64(part.data.data);
276
+ const url = await uploader.upload(base64, part.mediaType);
277
+ return { ...part, data: { type: "url", url } };
278
+ }
279
+ function imageBase64(data) {
280
+ if (typeof data !== "string") return Buffer.from(data).toString("base64");
281
+ const match = data.match(/^data:image\/[^;]+;base64,(.+)$/s);
282
+ return match?.[1] ?? data;
283
+ }
284
+
285
+ class LitterboxUploader {
286
+ #cache = new Map();
287
+ #ttl;
288
+ #fetch;
289
+ constructor(ttl, fetch) {
290
+ this.#ttl = ttl;
291
+ this.#fetch = fetch;
292
+ }
293
+ async upload(base64, mediaType) {
294
+ const hash = fnv1aHash(base64);
295
+ const cached = this.#cache.get(hash);
296
+ if (cached) return cached;
297
+ const extension = mediaType.split("/")[1] ?? "png";
298
+ const form = new FormData();
299
+ form.set("reqtype", "fileupload");
300
+ form.set("time", this.#ttl);
301
+ form.set(
302
+ "fileToUpload",
303
+ new File([Buffer.from(base64, "base64")], `image.${extension}`, {
304
+ type: mediaType,
305
+ }),
306
+ );
307
+ const response = await this.#fetch(LITTERBOX_URL, {
308
+ method: "POST",
309
+ body: form,
310
+ });
311
+ const url = (await response.text()).trim();
312
+ if (!url.startsWith("https://")) {
313
+ throw new Error(`Litterbox upload failed: ${url}`);
314
+ }
315
+ this.#cache.set(hash, url);
316
+ return url;
317
+ }
318
+ }
319
+ function fnv1aHash(value) {
320
+ let hash = 0xcbf29ce484222325n;
321
+ for (let index = 0; index < value.length; index++) {
322
+ hash ^= BigInt(value.charCodeAt(index));
323
+ hash = (hash * 0x100000001b3n) & 0xffffffffffffffffn;
324
+ }
325
+ return hash.toString(16);
326
+ }
327
+ // codex/src/llm/codexProviders.ts
328
+ var import_internal2 = require("@alumnium/core/internal");
329
+ var logger = import_internal2.Logger.get(
330
+ "packages/typescript/codex/src/llm/codexProviders.ts",
331
+ );
332
+ var codexProviders = {
333
+ codex: (model) => {
334
+ logger.debug(`Creating Codex LLM with model ${model.name}`);
335
+ return new CodexLanguageModel({ modelId: model.name });
336
+ },
337
+ };
338
+ import_internal2.LlmFactory.register(codexProviders);
339
+
340
+ //# debugId=8827D8B09394EDF464756E2164756E21
341
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../codex/src/llm/CodexLanguageModel.ts", "../../codex/src/llm/codexProviders.ts"],
4
+ "sourcesContent": [
5
+ "import { createOpenAI } from \"@ai-sdk/openai\";\nimport type {\n LanguageModelV4,\n LanguageModelV4CallOptions,\n LanguageModelV4GenerateResult,\n LanguageModelV4StreamPart,\n LanguageModelV4StreamResult,\n} from \"@ai-sdk/provider\";\nimport {\n startOpenAIOAuthServer,\n type OpenAIOAuthServerOptions,\n type RunningOpenAIOAuthServer,\n} from \"openai-oauth\";\nimport { Env } from \"@alumnium/core/internal\";\n\nconst DUMMY_API_KEY = \"codex-oauth\";\nconst LITTERBOX_URL =\n \"https://litterbox.catbox.moe/resources/internals/api.php\";\nconst STRUCTURED_OUTPUT_TOOL = \"__alumnium_structured_output\";\n\ntype LitterboxTtl = \"1h\" | \"12h\" | \"24h\" | \"72h\";\ntype CodexFetch = (\n input: string | URL | Request,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport interface CodexLanguageModelOptions {\n modelId: string;\n oauthServerOptions?: Omit<OpenAIOAuthServerOptions, \"models\">;\n litterboxUpload?: boolean;\n litterboxTtl?: LitterboxTtl;\n fetch?: CodexFetch;\n startServer?: (\n options: OpenAIOAuthServerOptions,\n ) => Promise<RunningOpenAIOAuthServer>;\n createDelegate?: (baseURL: string, modelId: string) => LanguageModelV4;\n}\n\nexport class CodexLanguageModel implements LanguageModelV4 {\n readonly specificationVersion = \"v4\";\n readonly provider = \"codex\";\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {};\n\n #server: RunningOpenAIOAuthServer | undefined;\n #serverPromise: Promise<RunningOpenAIOAuthServer> | undefined;\n #delegate: LanguageModelV4 | undefined;\n #options: CodexLanguageModelOptions;\n #uploader: LitterboxUploader;\n #litterboxUpload: boolean;\n\n constructor(options: CodexLanguageModelOptions) {\n this.modelId = options.modelId;\n this.#options = options;\n this.#litterboxUpload =\n options.litterboxUpload ?? Env.LANGCHAIN_CODEX_LITTERBOX_UPLOAD;\n this.#uploader = new LitterboxUploader(\n options.litterboxTtl ?? \"1h\",\n options.fetch ?? globalThis.fetch,\n );\n }\n\n async doGenerate(\n options: LanguageModelV4CallOptions,\n ): Promise<LanguageModelV4GenerateResult> {\n const structuredTool = structuredOutputToolName(options);\n const delegate = await this.#ensureDelegate();\n const result = await delegate.doGenerate(\n await this.#prepareOptions(options, structuredTool),\n );\n return structuredTool\n ? translateStructuredResult(result, structuredTool)\n : result;\n }\n\n async doStream(\n options: LanguageModelV4CallOptions,\n ): Promise<LanguageModelV4StreamResult> {\n const structuredTool = structuredOutputToolName(options);\n const delegate = await this.#ensureDelegate();\n const result = await delegate.doStream(\n await this.#prepareOptions(options, structuredTool),\n );\n if (!structuredTool) return result;\n\n return {\n ...result,\n stream: result.stream.pipeThrough(structuredOutputStream(structuredTool)),\n };\n }\n\n async close(): Promise<void> {\n if (!this.#serverPromise) return;\n\n const server = await this.#serverPromise;\n await server.close();\n this.#server = undefined;\n this.#serverPromise = undefined;\n this.#delegate = undefined;\n }\n\n async #prepareOptions(\n options: LanguageModelV4CallOptions,\n structuredTool: string | undefined,\n ): Promise<LanguageModelV4CallOptions> {\n const prompt = await replaceBase64Images(\n options.prompt,\n this.#litterboxUpload,\n this.#uploader,\n );\n if (!structuredTool || options.responseFormat?.type !== \"json\") {\n return { ...options, prompt };\n }\n\n return {\n ...options,\n prompt,\n responseFormat: { type: \"text\" },\n tools: [\n ...(options.tools ?? []),\n {\n type: \"function\",\n name: structuredTool,\n description:\n options.responseFormat.description ??\n \"Return the response in the required structured format.\",\n inputSchema: options.responseFormat.schema ?? { type: \"object\" },\n strict: true,\n },\n ],\n toolChoice: { type: \"tool\", toolName: structuredTool },\n };\n }\n\n async #ensureDelegate(): Promise<LanguageModelV4> {\n if (this.#delegate) return this.#delegate;\n\n const server = await this.#ensureServer();\n const createDelegate =\n this.#options.createDelegate ?? defaultCreateDelegate;\n this.#delegate = createDelegate(server.url, this.modelId);\n return this.#delegate;\n }\n\n #ensureServer(): Promise<RunningOpenAIOAuthServer> {\n if (this.#server) return Promise.resolve(this.#server);\n if (!this.#serverPromise) {\n const startServer = this.#options.startServer ?? startOpenAIOAuthServer;\n this.#serverPromise = startServer({\n host: \"127.0.0.1\",\n port: 0,\n ...this.#options.oauthServerOptions,\n }).then((server) => {\n this.#server = server;\n server.server.unref();\n return server;\n });\n }\n return this.#serverPromise;\n }\n}\n\nfunction defaultCreateDelegate(\n baseURL: string,\n modelId: string,\n): LanguageModelV4 {\n return createOpenAI({ baseURL, apiKey: DUMMY_API_KEY, name: \"codex\" }).chat(\n modelId,\n );\n}\n\nfunction structuredOutputToolName(\n options: LanguageModelV4CallOptions,\n): string | undefined {\n if (options.responseFormat?.type !== \"json\") return undefined;\n\n let name = STRUCTURED_OUTPUT_TOOL;\n const toolNames = new Set(\n options.tools?.map((tool) =>\n tool.type === \"function\" ? tool.name : tool.name,\n ),\n );\n while (toolNames.has(name)) name += \"_\";\n return name;\n}\n\nfunction translateStructuredResult(\n result: LanguageModelV4GenerateResult,\n toolName: string,\n): LanguageModelV4GenerateResult {\n const content = result.content.flatMap((part) =>\n part.type === \"tool-call\" && part.toolName === toolName\n ? [{ type: \"text\" as const, text: part.input }]\n : [part],\n );\n const hasText = content.some(\n (part) => part.type === \"text\" && part.text.trim(),\n );\n\n return {\n ...result,\n content,\n finishReason:\n result.finishReason.unified === \"tool-calls\" ||\n (result.finishReason.unified === \"other\" && hasText)\n ? { unified: \"stop\", raw: result.finishReason.raw }\n : result.finishReason,\n };\n}\n\nfunction structuredOutputStream(\n toolName: string,\n): TransformStream<LanguageModelV4StreamPart, LanguageModelV4StreamPart> {\n let isStructuredTool = false;\n return new TransformStream({\n transform(part, controller) {\n if (part.type === \"tool-input-start\" && part.toolName === toolName) {\n isStructuredTool = true;\n controller.enqueue({ type: \"text-start\", id: part.id });\n } else if (part.type === \"tool-input-delta\" && isStructuredTool) {\n controller.enqueue({\n type: \"text-delta\",\n id: part.id,\n delta: part.delta,\n });\n } else if (part.type === \"tool-input-end\" && isStructuredTool) {\n controller.enqueue({ type: \"text-end\", id: part.id });\n isStructuredTool = false;\n } else if (part.type === \"tool-call\" && part.toolName === toolName) {\n // The streamed input deltas already became text deltas.\n } else if (\n part.type === \"finish\" &&\n part.finishReason.unified === \"tool-calls\"\n ) {\n controller.enqueue({\n ...part,\n finishReason: { unified: \"stop\", raw: part.finishReason.raw },\n });\n } else {\n controller.enqueue(part);\n }\n },\n });\n}\n\nasync function replaceBase64Images(\n prompt: LanguageModelV4CallOptions[\"prompt\"],\n enabled: boolean,\n uploader: LitterboxUploader,\n): Promise<LanguageModelV4CallOptions[\"prompt\"]> {\n return Promise.all(\n prompt.map(async (message) => {\n if (message.role === \"user\") {\n const content = await Promise.all(\n message.content.map((part) =>\n replaceBase64Image(part, enabled, uploader),\n ),\n );\n return { ...message, content };\n }\n if (message.role === \"assistant\") {\n const content = await Promise.all(\n message.content.map((part) =>\n replaceBase64Image(part, enabled, uploader),\n ),\n );\n return { ...message, content };\n }\n return message;\n }),\n );\n}\n\nasync function replaceBase64Image<Part>(\n part: Part,\n enabled: boolean,\n uploader: LitterboxUploader,\n): Promise<Part> {\n if (\n !part ||\n typeof part !== \"object\" ||\n !(\"type\" in part) ||\n part.type !== \"file\" ||\n !(\"mediaType\" in part) ||\n typeof part.mediaType !== \"string\" ||\n !part.mediaType.startsWith(\"image/\") ||\n !(\"data\" in part) ||\n !part.data ||\n typeof part.data !== \"object\" ||\n !(\"type\" in part.data) ||\n part.data.type !== \"data\" ||\n !(\"data\" in part.data) ||\n (typeof part.data.data !== \"string\" &&\n !(part.data.data instanceof Uint8Array))\n ) {\n return part;\n }\n if (!enabled) {\n throw new Error(\n \"Codex models do not support inline images. Enable litterboxUpload or set LANGCHAIN_CODEX_LITTERBOX_UPLOAD=true to upload images to Litterbox.\",\n );\n }\n\n const base64 = imageBase64(part.data.data);\n const url = await uploader.upload(base64, part.mediaType);\n return { ...part, data: { type: \"url\", url } };\n}\n\nfunction imageBase64(data: string | Uint8Array): string {\n if (typeof data !== \"string\") return Buffer.from(data).toString(\"base64\");\n const match = data.match(/^data:image\\/[^;]+;base64,(.+)$/s);\n return match?.[1] ?? data;\n}\n\nclass LitterboxUploader {\n #cache = new Map<string, string>();\n #ttl: LitterboxTtl;\n #fetch: CodexFetch;\n\n constructor(ttl: LitterboxTtl, fetch: CodexFetch) {\n this.#ttl = ttl;\n this.#fetch = fetch;\n }\n\n async upload(base64: string, mediaType: string): Promise<string> {\n const hash = fnv1aHash(base64);\n const cached = this.#cache.get(hash);\n if (cached) return cached;\n\n const extension = mediaType.split(\"/\")[1] ?? \"png\";\n const form = new FormData();\n form.set(\"reqtype\", \"fileupload\");\n form.set(\"time\", this.#ttl);\n form.set(\n \"fileToUpload\",\n new File([Buffer.from(base64, \"base64\")], `image.${extension}`, {\n type: mediaType,\n }),\n );\n const response = await this.#fetch(LITTERBOX_URL, {\n method: \"POST\",\n body: form,\n });\n const url = (await response.text()).trim();\n if (!url.startsWith(\"https://\")) {\n throw new Error(`Litterbox upload failed: ${url}`);\n }\n\n this.#cache.set(hash, url);\n return url;\n }\n}\n\nfunction fnv1aHash(value: string): string {\n let hash = 0xcbf29ce484222325n;\n for (let index = 0; index < value.length; index++) {\n hash ^= BigInt(value.charCodeAt(index));\n hash = (hash * 0x100000001b3n) & 0xffffffffffffffffn;\n }\n return hash.toString(16);\n}\n",
6
+ "import { LlmFactory, Logger } from \"@alumnium/core/internal\";\nimport { CodexLanguageModel } from \"./CodexLanguageModel.ts\";\n\nconst logger = Logger.get(\"packages/typescript/codex/src/llm/codexProviders.ts\");\n\nexport const codexProviders: LlmFactory.Providers = {\n codex: (model) => {\n logger.debug(`Creating Codex LLM with model ${model.name}`);\n return new CodexLanguageModel({ modelId: model.name });\n },\n};\n\nLlmFactory.register(codexProviders);\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "8827D8B09394EDF464756E2164756E21",
10
+ "names": []
11
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./llm/CodexLanguageModel.ts";
2
+ export * from "./llm/codexProviders.ts";
package/src/index.js ADDED
@@ -0,0 +1,292 @@
1
+ // codex/src/llm/CodexLanguageModel.ts
2
+ import { createOpenAI } from "@ai-sdk/openai";
3
+ import { startOpenAIOAuthServer } from "openai-oauth";
4
+ import { Env } from "@alumnium/core/internal";
5
+ var DUMMY_API_KEY = "codex-oauth";
6
+ var LITTERBOX_URL = "https://litterbox.catbox.moe/resources/internals/api.php";
7
+ var STRUCTURED_OUTPUT_TOOL = "__alumnium_structured_output";
8
+
9
+ class CodexLanguageModel {
10
+ specificationVersion = "v4";
11
+ provider = "codex";
12
+ modelId;
13
+ supportedUrls = {};
14
+ #server;
15
+ #serverPromise;
16
+ #delegate;
17
+ #options;
18
+ #uploader;
19
+ #litterboxUpload;
20
+ constructor(options) {
21
+ this.modelId = options.modelId;
22
+ this.#options = options;
23
+ this.#litterboxUpload =
24
+ options.litterboxUpload ?? Env.LANGCHAIN_CODEX_LITTERBOX_UPLOAD;
25
+ this.#uploader = new LitterboxUploader(
26
+ options.litterboxTtl ?? "1h",
27
+ options.fetch ?? globalThis.fetch,
28
+ );
29
+ }
30
+ async doGenerate(options) {
31
+ const structuredTool = structuredOutputToolName(options);
32
+ const delegate = await this.#ensureDelegate();
33
+ const result = await delegate.doGenerate(
34
+ await this.#prepareOptions(options, structuredTool),
35
+ );
36
+ return structuredTool
37
+ ? translateStructuredResult(result, structuredTool)
38
+ : result;
39
+ }
40
+ async doStream(options) {
41
+ const structuredTool = structuredOutputToolName(options);
42
+ const delegate = await this.#ensureDelegate();
43
+ const result = await delegate.doStream(
44
+ await this.#prepareOptions(options, structuredTool),
45
+ );
46
+ if (!structuredTool) return result;
47
+ return {
48
+ ...result,
49
+ stream: result.stream.pipeThrough(structuredOutputStream(structuredTool)),
50
+ };
51
+ }
52
+ async close() {
53
+ if (!this.#serverPromise) return;
54
+ const server = await this.#serverPromise;
55
+ await server.close();
56
+ this.#server = undefined;
57
+ this.#serverPromise = undefined;
58
+ this.#delegate = undefined;
59
+ }
60
+ async #prepareOptions(options, structuredTool) {
61
+ const prompt = await replaceBase64Images(
62
+ options.prompt,
63
+ this.#litterboxUpload,
64
+ this.#uploader,
65
+ );
66
+ if (!structuredTool || options.responseFormat?.type !== "json") {
67
+ return { ...options, prompt };
68
+ }
69
+ return {
70
+ ...options,
71
+ prompt,
72
+ responseFormat: { type: "text" },
73
+ tools: [
74
+ ...(options.tools ?? []),
75
+ {
76
+ type: "function",
77
+ name: structuredTool,
78
+ description:
79
+ options.responseFormat.description ??
80
+ "Return the response in the required structured format.",
81
+ inputSchema: options.responseFormat.schema ?? { type: "object" },
82
+ strict: true,
83
+ },
84
+ ],
85
+ toolChoice: { type: "tool", toolName: structuredTool },
86
+ };
87
+ }
88
+ async #ensureDelegate() {
89
+ if (this.#delegate) return this.#delegate;
90
+ const server = await this.#ensureServer();
91
+ const createDelegate =
92
+ this.#options.createDelegate ?? defaultCreateDelegate;
93
+ this.#delegate = createDelegate(server.url, this.modelId);
94
+ return this.#delegate;
95
+ }
96
+ #ensureServer() {
97
+ if (this.#server) return Promise.resolve(this.#server);
98
+ if (!this.#serverPromise) {
99
+ const startServer = this.#options.startServer ?? startOpenAIOAuthServer;
100
+ this.#serverPromise = startServer({
101
+ host: "127.0.0.1",
102
+ port: 0,
103
+ ...this.#options.oauthServerOptions,
104
+ }).then((server) => {
105
+ this.#server = server;
106
+ server.server.unref();
107
+ return server;
108
+ });
109
+ }
110
+ return this.#serverPromise;
111
+ }
112
+ }
113
+ function defaultCreateDelegate(baseURL, modelId) {
114
+ return createOpenAI({ baseURL, apiKey: DUMMY_API_KEY, name: "codex" }).chat(
115
+ modelId,
116
+ );
117
+ }
118
+ function structuredOutputToolName(options) {
119
+ if (options.responseFormat?.type !== "json") return;
120
+ let name = STRUCTURED_OUTPUT_TOOL;
121
+ const toolNames = new Set(
122
+ options.tools?.map((tool) =>
123
+ tool.type === "function" ? tool.name : tool.name,
124
+ ),
125
+ );
126
+ while (toolNames.has(name)) name += "_";
127
+ return name;
128
+ }
129
+ function translateStructuredResult(result, toolName) {
130
+ const content = result.content.flatMap((part) =>
131
+ part.type === "tool-call" && part.toolName === toolName
132
+ ? [{ type: "text", text: part.input }]
133
+ : [part],
134
+ );
135
+ const hasText = content.some(
136
+ (part) => part.type === "text" && part.text.trim(),
137
+ );
138
+ return {
139
+ ...result,
140
+ content,
141
+ finishReason:
142
+ result.finishReason.unified === "tool-calls" ||
143
+ (result.finishReason.unified === "other" && hasText)
144
+ ? { unified: "stop", raw: result.finishReason.raw }
145
+ : result.finishReason,
146
+ };
147
+ }
148
+ function structuredOutputStream(toolName) {
149
+ let isStructuredTool = false;
150
+ return new TransformStream({
151
+ transform(part, controller) {
152
+ if (part.type === "tool-input-start" && part.toolName === toolName) {
153
+ isStructuredTool = true;
154
+ controller.enqueue({ type: "text-start", id: part.id });
155
+ } else if (part.type === "tool-input-delta" && isStructuredTool) {
156
+ controller.enqueue({
157
+ type: "text-delta",
158
+ id: part.id,
159
+ delta: part.delta,
160
+ });
161
+ } else if (part.type === "tool-input-end" && isStructuredTool) {
162
+ controller.enqueue({ type: "text-end", id: part.id });
163
+ isStructuredTool = false;
164
+ } else if (part.type === "tool-call" && part.toolName === toolName) {
165
+ } else if (
166
+ part.type === "finish" &&
167
+ part.finishReason.unified === "tool-calls"
168
+ ) {
169
+ controller.enqueue({
170
+ ...part,
171
+ finishReason: { unified: "stop", raw: part.finishReason.raw },
172
+ });
173
+ } else {
174
+ controller.enqueue(part);
175
+ }
176
+ },
177
+ });
178
+ }
179
+ async function replaceBase64Images(prompt, enabled, uploader) {
180
+ return Promise.all(
181
+ prompt.map(async (message) => {
182
+ if (message.role === "user") {
183
+ const content = await Promise.all(
184
+ message.content.map((part) =>
185
+ replaceBase64Image(part, enabled, uploader),
186
+ ),
187
+ );
188
+ return { ...message, content };
189
+ }
190
+ if (message.role === "assistant") {
191
+ const content = await Promise.all(
192
+ message.content.map((part) =>
193
+ replaceBase64Image(part, enabled, uploader),
194
+ ),
195
+ );
196
+ return { ...message, content };
197
+ }
198
+ return message;
199
+ }),
200
+ );
201
+ }
202
+ async function replaceBase64Image(part, enabled, uploader) {
203
+ if (
204
+ !part ||
205
+ typeof part !== "object" ||
206
+ !("type" in part) ||
207
+ part.type !== "file" ||
208
+ !("mediaType" in part) ||
209
+ typeof part.mediaType !== "string" ||
210
+ !part.mediaType.startsWith("image/") ||
211
+ !("data" in part) ||
212
+ !part.data ||
213
+ typeof part.data !== "object" ||
214
+ !("type" in part.data) ||
215
+ part.data.type !== "data" ||
216
+ !("data" in part.data) ||
217
+ (typeof part.data.data !== "string" &&
218
+ !(part.data.data instanceof Uint8Array))
219
+ ) {
220
+ return part;
221
+ }
222
+ if (!enabled) {
223
+ throw new Error(
224
+ "Codex models do not support inline images. Enable litterboxUpload or set LANGCHAIN_CODEX_LITTERBOX_UPLOAD=true to upload images to Litterbox.",
225
+ );
226
+ }
227
+ const base64 = imageBase64(part.data.data);
228
+ const url = await uploader.upload(base64, part.mediaType);
229
+ return { ...part, data: { type: "url", url } };
230
+ }
231
+ function imageBase64(data) {
232
+ if (typeof data !== "string") return Buffer.from(data).toString("base64");
233
+ const match = data.match(/^data:image\/[^;]+;base64,(.+)$/s);
234
+ return match?.[1] ?? data;
235
+ }
236
+
237
+ class LitterboxUploader {
238
+ #cache = new Map();
239
+ #ttl;
240
+ #fetch;
241
+ constructor(ttl, fetch) {
242
+ this.#ttl = ttl;
243
+ this.#fetch = fetch;
244
+ }
245
+ async upload(base64, mediaType) {
246
+ const hash = fnv1aHash(base64);
247
+ const cached = this.#cache.get(hash);
248
+ if (cached) return cached;
249
+ const extension = mediaType.split("/")[1] ?? "png";
250
+ const form = new FormData();
251
+ form.set("reqtype", "fileupload");
252
+ form.set("time", this.#ttl);
253
+ form.set(
254
+ "fileToUpload",
255
+ new File([Buffer.from(base64, "base64")], `image.${extension}`, {
256
+ type: mediaType,
257
+ }),
258
+ );
259
+ const response = await this.#fetch(LITTERBOX_URL, {
260
+ method: "POST",
261
+ body: form,
262
+ });
263
+ const url = (await response.text()).trim();
264
+ if (!url.startsWith("https://")) {
265
+ throw new Error(`Litterbox upload failed: ${url}`);
266
+ }
267
+ this.#cache.set(hash, url);
268
+ return url;
269
+ }
270
+ }
271
+ function fnv1aHash(value) {
272
+ let hash = 0xcbf29ce484222325n;
273
+ for (let index = 0; index < value.length; index++) {
274
+ hash ^= BigInt(value.charCodeAt(index));
275
+ hash = (hash * 0x100000001b3n) & 0xffffffffffffffffn;
276
+ }
277
+ return hash.toString(16);
278
+ }
279
+ // codex/src/llm/codexProviders.ts
280
+ import { LlmFactory, Logger } from "@alumnium/core/internal";
281
+ var logger = Logger.get("packages/typescript/codex/src/llm/codexProviders.ts");
282
+ var codexProviders = {
283
+ codex: (model) => {
284
+ logger.debug(`Creating Codex LLM with model ${model.name}`);
285
+ return new CodexLanguageModel({ modelId: model.name });
286
+ },
287
+ };
288
+ LlmFactory.register(codexProviders);
289
+ export { CodexLanguageModel, codexProviders };
290
+
291
+ //# debugId=3C0FB39B12E7B69064756E2164756E21
292
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../codex/src/llm/CodexLanguageModel.ts", "../../codex/src/llm/codexProviders.ts"],
4
+ "sourcesContent": [
5
+ "import { createOpenAI } from \"@ai-sdk/openai\";\nimport type {\n LanguageModelV4,\n LanguageModelV4CallOptions,\n LanguageModelV4GenerateResult,\n LanguageModelV4StreamPart,\n LanguageModelV4StreamResult,\n} from \"@ai-sdk/provider\";\nimport {\n startOpenAIOAuthServer,\n type OpenAIOAuthServerOptions,\n type RunningOpenAIOAuthServer,\n} from \"openai-oauth\";\nimport { Env } from \"@alumnium/core/internal\";\n\nconst DUMMY_API_KEY = \"codex-oauth\";\nconst LITTERBOX_URL =\n \"https://litterbox.catbox.moe/resources/internals/api.php\";\nconst STRUCTURED_OUTPUT_TOOL = \"__alumnium_structured_output\";\n\ntype LitterboxTtl = \"1h\" | \"12h\" | \"24h\" | \"72h\";\ntype CodexFetch = (\n input: string | URL | Request,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport interface CodexLanguageModelOptions {\n modelId: string;\n oauthServerOptions?: Omit<OpenAIOAuthServerOptions, \"models\">;\n litterboxUpload?: boolean;\n litterboxTtl?: LitterboxTtl;\n fetch?: CodexFetch;\n startServer?: (\n options: OpenAIOAuthServerOptions,\n ) => Promise<RunningOpenAIOAuthServer>;\n createDelegate?: (baseURL: string, modelId: string) => LanguageModelV4;\n}\n\nexport class CodexLanguageModel implements LanguageModelV4 {\n readonly specificationVersion = \"v4\";\n readonly provider = \"codex\";\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {};\n\n #server: RunningOpenAIOAuthServer | undefined;\n #serverPromise: Promise<RunningOpenAIOAuthServer> | undefined;\n #delegate: LanguageModelV4 | undefined;\n #options: CodexLanguageModelOptions;\n #uploader: LitterboxUploader;\n #litterboxUpload: boolean;\n\n constructor(options: CodexLanguageModelOptions) {\n this.modelId = options.modelId;\n this.#options = options;\n this.#litterboxUpload =\n options.litterboxUpload ?? Env.LANGCHAIN_CODEX_LITTERBOX_UPLOAD;\n this.#uploader = new LitterboxUploader(\n options.litterboxTtl ?? \"1h\",\n options.fetch ?? globalThis.fetch,\n );\n }\n\n async doGenerate(\n options: LanguageModelV4CallOptions,\n ): Promise<LanguageModelV4GenerateResult> {\n const structuredTool = structuredOutputToolName(options);\n const delegate = await this.#ensureDelegate();\n const result = await delegate.doGenerate(\n await this.#prepareOptions(options, structuredTool),\n );\n return structuredTool\n ? translateStructuredResult(result, structuredTool)\n : result;\n }\n\n async doStream(\n options: LanguageModelV4CallOptions,\n ): Promise<LanguageModelV4StreamResult> {\n const structuredTool = structuredOutputToolName(options);\n const delegate = await this.#ensureDelegate();\n const result = await delegate.doStream(\n await this.#prepareOptions(options, structuredTool),\n );\n if (!structuredTool) return result;\n\n return {\n ...result,\n stream: result.stream.pipeThrough(structuredOutputStream(structuredTool)),\n };\n }\n\n async close(): Promise<void> {\n if (!this.#serverPromise) return;\n\n const server = await this.#serverPromise;\n await server.close();\n this.#server = undefined;\n this.#serverPromise = undefined;\n this.#delegate = undefined;\n }\n\n async #prepareOptions(\n options: LanguageModelV4CallOptions,\n structuredTool: string | undefined,\n ): Promise<LanguageModelV4CallOptions> {\n const prompt = await replaceBase64Images(\n options.prompt,\n this.#litterboxUpload,\n this.#uploader,\n );\n if (!structuredTool || options.responseFormat?.type !== \"json\") {\n return { ...options, prompt };\n }\n\n return {\n ...options,\n prompt,\n responseFormat: { type: \"text\" },\n tools: [\n ...(options.tools ?? []),\n {\n type: \"function\",\n name: structuredTool,\n description:\n options.responseFormat.description ??\n \"Return the response in the required structured format.\",\n inputSchema: options.responseFormat.schema ?? { type: \"object\" },\n strict: true,\n },\n ],\n toolChoice: { type: \"tool\", toolName: structuredTool },\n };\n }\n\n async #ensureDelegate(): Promise<LanguageModelV4> {\n if (this.#delegate) return this.#delegate;\n\n const server = await this.#ensureServer();\n const createDelegate =\n this.#options.createDelegate ?? defaultCreateDelegate;\n this.#delegate = createDelegate(server.url, this.modelId);\n return this.#delegate;\n }\n\n #ensureServer(): Promise<RunningOpenAIOAuthServer> {\n if (this.#server) return Promise.resolve(this.#server);\n if (!this.#serverPromise) {\n const startServer = this.#options.startServer ?? startOpenAIOAuthServer;\n this.#serverPromise = startServer({\n host: \"127.0.0.1\",\n port: 0,\n ...this.#options.oauthServerOptions,\n }).then((server) => {\n this.#server = server;\n server.server.unref();\n return server;\n });\n }\n return this.#serverPromise;\n }\n}\n\nfunction defaultCreateDelegate(\n baseURL: string,\n modelId: string,\n): LanguageModelV4 {\n return createOpenAI({ baseURL, apiKey: DUMMY_API_KEY, name: \"codex\" }).chat(\n modelId,\n );\n}\n\nfunction structuredOutputToolName(\n options: LanguageModelV4CallOptions,\n): string | undefined {\n if (options.responseFormat?.type !== \"json\") return undefined;\n\n let name = STRUCTURED_OUTPUT_TOOL;\n const toolNames = new Set(\n options.tools?.map((tool) =>\n tool.type === \"function\" ? tool.name : tool.name,\n ),\n );\n while (toolNames.has(name)) name += \"_\";\n return name;\n}\n\nfunction translateStructuredResult(\n result: LanguageModelV4GenerateResult,\n toolName: string,\n): LanguageModelV4GenerateResult {\n const content = result.content.flatMap((part) =>\n part.type === \"tool-call\" && part.toolName === toolName\n ? [{ type: \"text\" as const, text: part.input }]\n : [part],\n );\n const hasText = content.some(\n (part) => part.type === \"text\" && part.text.trim(),\n );\n\n return {\n ...result,\n content,\n finishReason:\n result.finishReason.unified === \"tool-calls\" ||\n (result.finishReason.unified === \"other\" && hasText)\n ? { unified: \"stop\", raw: result.finishReason.raw }\n : result.finishReason,\n };\n}\n\nfunction structuredOutputStream(\n toolName: string,\n): TransformStream<LanguageModelV4StreamPart, LanguageModelV4StreamPart> {\n let isStructuredTool = false;\n return new TransformStream({\n transform(part, controller) {\n if (part.type === \"tool-input-start\" && part.toolName === toolName) {\n isStructuredTool = true;\n controller.enqueue({ type: \"text-start\", id: part.id });\n } else if (part.type === \"tool-input-delta\" && isStructuredTool) {\n controller.enqueue({\n type: \"text-delta\",\n id: part.id,\n delta: part.delta,\n });\n } else if (part.type === \"tool-input-end\" && isStructuredTool) {\n controller.enqueue({ type: \"text-end\", id: part.id });\n isStructuredTool = false;\n } else if (part.type === \"tool-call\" && part.toolName === toolName) {\n // The streamed input deltas already became text deltas.\n } else if (\n part.type === \"finish\" &&\n part.finishReason.unified === \"tool-calls\"\n ) {\n controller.enqueue({\n ...part,\n finishReason: { unified: \"stop\", raw: part.finishReason.raw },\n });\n } else {\n controller.enqueue(part);\n }\n },\n });\n}\n\nasync function replaceBase64Images(\n prompt: LanguageModelV4CallOptions[\"prompt\"],\n enabled: boolean,\n uploader: LitterboxUploader,\n): Promise<LanguageModelV4CallOptions[\"prompt\"]> {\n return Promise.all(\n prompt.map(async (message) => {\n if (message.role === \"user\") {\n const content = await Promise.all(\n message.content.map((part) =>\n replaceBase64Image(part, enabled, uploader),\n ),\n );\n return { ...message, content };\n }\n if (message.role === \"assistant\") {\n const content = await Promise.all(\n message.content.map((part) =>\n replaceBase64Image(part, enabled, uploader),\n ),\n );\n return { ...message, content };\n }\n return message;\n }),\n );\n}\n\nasync function replaceBase64Image<Part>(\n part: Part,\n enabled: boolean,\n uploader: LitterboxUploader,\n): Promise<Part> {\n if (\n !part ||\n typeof part !== \"object\" ||\n !(\"type\" in part) ||\n part.type !== \"file\" ||\n !(\"mediaType\" in part) ||\n typeof part.mediaType !== \"string\" ||\n !part.mediaType.startsWith(\"image/\") ||\n !(\"data\" in part) ||\n !part.data ||\n typeof part.data !== \"object\" ||\n !(\"type\" in part.data) ||\n part.data.type !== \"data\" ||\n !(\"data\" in part.data) ||\n (typeof part.data.data !== \"string\" &&\n !(part.data.data instanceof Uint8Array))\n ) {\n return part;\n }\n if (!enabled) {\n throw new Error(\n \"Codex models do not support inline images. Enable litterboxUpload or set LANGCHAIN_CODEX_LITTERBOX_UPLOAD=true to upload images to Litterbox.\",\n );\n }\n\n const base64 = imageBase64(part.data.data);\n const url = await uploader.upload(base64, part.mediaType);\n return { ...part, data: { type: \"url\", url } };\n}\n\nfunction imageBase64(data: string | Uint8Array): string {\n if (typeof data !== \"string\") return Buffer.from(data).toString(\"base64\");\n const match = data.match(/^data:image\\/[^;]+;base64,(.+)$/s);\n return match?.[1] ?? data;\n}\n\nclass LitterboxUploader {\n #cache = new Map<string, string>();\n #ttl: LitterboxTtl;\n #fetch: CodexFetch;\n\n constructor(ttl: LitterboxTtl, fetch: CodexFetch) {\n this.#ttl = ttl;\n this.#fetch = fetch;\n }\n\n async upload(base64: string, mediaType: string): Promise<string> {\n const hash = fnv1aHash(base64);\n const cached = this.#cache.get(hash);\n if (cached) return cached;\n\n const extension = mediaType.split(\"/\")[1] ?? \"png\";\n const form = new FormData();\n form.set(\"reqtype\", \"fileupload\");\n form.set(\"time\", this.#ttl);\n form.set(\n \"fileToUpload\",\n new File([Buffer.from(base64, \"base64\")], `image.${extension}`, {\n type: mediaType,\n }),\n );\n const response = await this.#fetch(LITTERBOX_URL, {\n method: \"POST\",\n body: form,\n });\n const url = (await response.text()).trim();\n if (!url.startsWith(\"https://\")) {\n throw new Error(`Litterbox upload failed: ${url}`);\n }\n\n this.#cache.set(hash, url);\n return url;\n }\n}\n\nfunction fnv1aHash(value: string): string {\n let hash = 0xcbf29ce484222325n;\n for (let index = 0; index < value.length; index++) {\n hash ^= BigInt(value.charCodeAt(index));\n hash = (hash * 0x100000001b3n) & 0xffffffffffffffffn;\n }\n return hash.toString(16);\n}\n",
6
+ "import { LlmFactory, Logger } from \"@alumnium/core/internal\";\nimport { CodexLanguageModel } from \"./CodexLanguageModel.ts\";\n\nconst logger = Logger.get(\"packages/typescript/codex/src/llm/codexProviders.ts\");\n\nexport const codexProviders: LlmFactory.Providers = {\n codex: (model) => {\n logger.debug(`Creating Codex LLM with model ${model.name}`);\n return new CodexLanguageModel({ modelId: model.name });\n },\n};\n\nLlmFactory.register(codexProviders);\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "3C0FB39B12E7B69064756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,42 @@
1
+ import type {
2
+ LanguageModelV4,
3
+ LanguageModelV4CallOptions,
4
+ LanguageModelV4GenerateResult,
5
+ LanguageModelV4StreamResult,
6
+ } from "@ai-sdk/provider";
7
+ import {
8
+ type OpenAIOAuthServerOptions,
9
+ type RunningOpenAIOAuthServer,
10
+ } from "openai-oauth";
11
+ type LitterboxTtl = "1h" | "12h" | "24h" | "72h";
12
+ type CodexFetch = (
13
+ input: string | URL | Request,
14
+ init?: RequestInit,
15
+ ) => Promise<Response>;
16
+ export interface CodexLanguageModelOptions {
17
+ modelId: string;
18
+ oauthServerOptions?: Omit<OpenAIOAuthServerOptions, "models">;
19
+ litterboxUpload?: boolean;
20
+ litterboxTtl?: LitterboxTtl;
21
+ fetch?: CodexFetch;
22
+ startServer?: (
23
+ options: OpenAIOAuthServerOptions,
24
+ ) => Promise<RunningOpenAIOAuthServer>;
25
+ createDelegate?: (baseURL: string, modelId: string) => LanguageModelV4;
26
+ }
27
+ export declare class CodexLanguageModel implements LanguageModelV4 {
28
+ #private;
29
+ readonly specificationVersion = "v4";
30
+ readonly provider = "codex";
31
+ readonly modelId: string;
32
+ readonly supportedUrls: Record<string, RegExp[]>;
33
+ constructor(options: CodexLanguageModelOptions);
34
+ doGenerate(
35
+ options: LanguageModelV4CallOptions,
36
+ ): Promise<LanguageModelV4GenerateResult>;
37
+ doStream(
38
+ options: LanguageModelV4CallOptions,
39
+ ): Promise<LanguageModelV4StreamResult>;
40
+ close(): Promise<void>;
41
+ }
42
+ export {};
@@ -0,0 +1,2 @@
1
+ import { LlmFactory } from "@alumnium/core/internal";
2
+ export declare const codexProviders: LlmFactory.Providers;