From 8dc1ed7015efcf3c4229339fcb515cf8a9833f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 5 Sep 2024 01:48:48 +0200 Subject: [PATCH] OpenAIClient --- bun.lockb | Bin 120381 -> 126182 bytes package.json | 1 + src/Layers/OpenAIClient.ts | 68 +++++++++++++++++++++++++++++++++++++ src/Layers/index.ts | 1 + 4 files changed, 70 insertions(+) create mode 100644 src/Layers/OpenAIClient.ts diff --git a/bun.lockb b/bun.lockb index a1e2534d1f7a58f3415692294337c72b8242c405..2cafe940b4bf63eb09cd0196cfc1c3b270c21eea 100755 GIT binary patch delta 17630 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 diff --git a/package.json b/package.json index 8550066..792141c 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "mobx": "^6.13.1", "npm-check-updates": "^17.1.1", "npm-sort": "^0.0.4", + "openai": "^4.57.3", "tsup": "^8.2.4", "tsx": "^4.19.0", "typescript": "^5.5.4" diff --git a/src/Layers/OpenAIClient.ts b/src/Layers/OpenAIClient.ts new file mode 100644 index 0000000..cfab980 --- /dev/null +++ b/src/Layers/OpenAIClient.ts @@ -0,0 +1,68 @@ +import { Config, Context, Effect, Layer } from "effect" +import type { OpenAI } from "openai" + + +export class OpenAIClient extends Context.Tag("OpenAIClient")() {} + +export class OpenAIClientService { + constructor( + readonly openai: Effect.Effect.Success, + readonly client: OpenAI, + ) {} + + try( + try_: ( + client: OpenAI, + signal: AbortSignal, + ) => Promise + ) { + return Effect.tryPromise({ + try: signal => try_(this.client, signal), + catch: e => e instanceof this.openai.OpenAIError + ? e + : new Error(`Unknown OpenAIClient error: ${ e }`), + }) + } +} + + +const importOpenAI = Effect.tryPromise({ + try: () => import("openai"), + catch: cause => new Error("Could not import 'openai'. Make sure it is installed.", { cause }), +}) + +export const OpenAIClientLive = ( + config: { + readonly apiKey: Config.Config + readonly organization?: Config.Config + readonly project?: Config.Config + readonly baseURL?: Config.Config + readonly timeout?: Config.Config + readonly maxRetries?: Config.Config + + readonly httpAgent?: any + readonly fetch?: any + readonly defaultHeaders?: { [x: string]: string } + readonly defaultQuery?: { [x: string]: string } + } +) => Layer.effect(OpenAIClient, Effect.gen(function*() { + const openai = yield* importOpenAI + + return new OpenAIClientService( + openai, + + new openai.OpenAI({ + apiKey: yield* config.apiKey, + organization: (yield* config.organization || Config.succeed(undefined)) || null, + project: (yield* config.project || Config.succeed(undefined)) || null, + baseURL: (yield* config.baseURL || Config.succeed(undefined)) || "https://api.openai.com/v1", + timeout: yield* config.timeout || Config.succeed(undefined), + maxRetries: yield* config.maxRetries || Config.succeed(undefined), + + httpAgent: config.httpAgent, + fetch: config.fetch, + defaultHeaders: config.defaultHeaders, + defaultQuery: config.defaultQuery, + }), + ) +})) diff --git a/src/Layers/index.ts b/src/Layers/index.ts index 6a72a2d..2f143bb 100644 --- a/src/Layers/index.ts +++ b/src/Layers/index.ts @@ -1,2 +1,3 @@ export * from "./express" export * as JSONWebToken from "./JSONWebToken" +export * as OpenAIClient from "./OpenAIClient"