diff --git a/packages/ai/ai/src/Completions.ts b/packages/ai/ai/src/Completions.ts index 973387147f..363d2dbe19 100644 --- a/packages/ai/ai/src/Completions.ts +++ b/packages/ai/ai/src/Completions.ts @@ -78,6 +78,21 @@ export declare namespace Completions { const constEmptyMap = new Map() +/** + * @since 1.0.0 + * @category models + */ +export interface CompletionOptions { + readonly system: Option.Option + readonly input: Chunk.NonEmptyChunk + readonly tools: Array<{ + readonly name: string + readonly description: string + readonly parameters: JSONSchema.JsonSchema7 + }> + readonly required: boolean | string +} + /** * @since 1.0.0 * @category constructors diff --git a/packages/ai/openai/src/OpenAiCompletions.ts b/packages/ai/openai/src/OpenAiCompletions.ts index 124c193539..29b4f4ddcb 100644 --- a/packages/ai/openai/src/OpenAiCompletions.ts +++ b/packages/ai/openai/src/OpenAiCompletions.ts @@ -25,33 +25,38 @@ const make = (options: { const client = yield* OpenAiClient const config = yield* OpenAiConfig.getOrUndefined + const makeRequest = ({ input, required, system, tools }: Completions.CompletionOptions) => + Effect.map( + Effect.context(), + (context): typeof Generated.CreateChatCompletionRequest.Encoded => ({ + model: options.model, + ...config, + ...context.unsafeMap.get(OpenAiConfig.key), + messages: makeMessages(input, system), + tools: tools.length > 0 ? + tools.map((tool) => ({ + type: "function", + function: { + name: tool.name, + description: tool.description, + parameters: tool.parameters as any, + strict: true + } + })) : + undefined, + tool_choice: tools.length > 0 ? + typeof required === "boolean" ? (required ? "required" : "auto") : { + type: "function", + function: { name: required } + } : + undefined + }) + ) + return Completions.make({ - create({ input, required, system, tools }) { - return OpenAiConfig.getOrUndefined.pipe( - Effect.flatMap((localConfig) => - client.client.createChatCompletion({ - model: options.model, - ...config, - ...localConfig, - messages: makeMessages(input, system), - tools: tools.length > 0 ? - tools.map((tool) => ({ - type: "function", - function: { - name: tool.name, - description: tool.description, - parameters: tool.parameters as any - } - })) : - undefined, - tool_choice: tools.length > 0 ? - typeof required === "boolean" ? (required ? "required" : "auto") : { - type: "function", - function: { name: required } - } : - undefined - }) - ), + create(options) { + return makeRequest(options).pipe( + Effect.flatMap(client.client.createChatCompletion), Effect.catchAll((cause) => Effect.fail( new AiError({ @@ -65,32 +70,9 @@ const make = (options: { Effect.flatMap((response) => makeResponse(response, "create")) ) }, - stream({ input, required, system, tools }) { - return OpenAiConfig.getOrUndefined.pipe( - Effect.map((localConfig) => - client.stream({ - model: options.model, - ...config, - ...localConfig, - messages: makeMessages(input, system), - tools: tools.length > 0 ? - tools.map((tool) => ({ - type: "function", - function: { - name: tool.name, - description: tool.description, - parameters: tool.parameters as any - } - })) : - undefined, - tool_choice: tools.length > 0 ? - typeof required === "boolean" ? (required ? "required" : "auto") : { - type: "function", - function: { name: required } - } : - undefined - }) - ), + stream(options) { + return makeRequest(options).pipe( + Effect.map(client.stream), Stream.unwrap, Stream.catchAll((cause) => Effect.fail(