diff --git a/examples/files.ts b/examples/files.ts new file mode 100644 index 0000000..640654a --- /dev/null +++ b/examples/files.ts @@ -0,0 +1,8 @@ +import { OpenAI } from "../mod.ts"; + +const openAI = new OpenAI( + "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", +); + +// TODO: Do this more portably +console.log(await openAI.uploadFile("./testdata/example.jsonl", "fine-tune")); diff --git a/examples/testdata/example.jsonl b/examples/testdata/example.jsonl new file mode 100644 index 0000000..e1b7c6a --- /dev/null +++ b/examples/testdata/example.jsonl @@ -0,0 +1,4 @@ +{"prompt": "red", "completion": "angry"} +{"prompt": "orange", "completion": "angry"} +{"prompt": "blue", "completion": "calm"} +{"prompt": "purple", "completion": "calm"} \ No newline at end of file diff --git a/src/openai.ts b/src/openai.ts index e2dd0a1..f3e7af6 100644 --- a/src/openai.ts +++ b/src/openai.ts @@ -9,8 +9,9 @@ import type { EditOptions, Embedding, EmbeddingsOptions, - File, + FileInstance, FileList, + FileSpecifier, FineTune, FineTuneEvent, FineTuneEventList, @@ -303,10 +304,33 @@ export class OpenAI { * * https://platform.openai.com/docs/api-reference/files/upload */ - async uploadFile(file: string, purpose: string): Promise { - return await this.#request(`/files`, { - file, - purpose, + async uploadFile( + file: FileSpecifier, + purpose: string, + ): Promise { + const formData = new FormData(); + + // Model specified + formData.append("file", file); + + // File data + if (typeof file === "string") { + const fileData = await Deno.readFile(file); + + formData.append( + "file", + new File([fileData], basename(file)), + ); + } else { + // Deno types are wrong + formData.append("file", file as unknown as Blob); + } + + formData.append("purpose", purpose); + + return await this.#request(`/files`, formData, { + noContentType: true, + method: "POST", }); } @@ -326,7 +350,7 @@ export class OpenAI { * * https://platform.openai.com/docs/api-reference/files/retrieve */ - async retrieveFile(fileId: string): Promise { + async retrieveFile(fileId: string): Promise { return await this.#request(`/files/${fileId}`, undefined, { method: "GET", }); diff --git a/src/types.ts b/src/types.ts index de0986e..48bf92a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -669,7 +669,7 @@ export interface Translation { text: string; } -export interface File { +export interface FileInstance { id: string; object: "file"; bytes: number; @@ -679,7 +679,7 @@ export interface File { } export interface FileList { - data: File[]; + data: FileInstance[]; object: "list"; } @@ -714,10 +714,10 @@ export interface FineTune { prompt_loss_weight: number; }; organization_id: string; - result_files: File[]; + result_files: FileInstance[]; status: "pending" | "succeeded" | "cancelled"; - validation_files: File[]; - training_files: File[]; + validation_files: FileInstance[]; + training_files: FileInstance[]; updated_at: number; }