diff --git a/packages/ai/ai/src/AiPlan.ts b/packages/ai/ai/src/AiPlan.ts index f36c2f72619..55b89479cac 100644 --- a/packages/ai/ai/src/AiPlan.ts +++ b/packages/ai/ai/src/AiPlan.ts @@ -6,6 +6,7 @@ import type * as Effect from "effect/Effect" import type * as Option from "effect/Option" import type { Pipeable } from "effect/Pipeable" import type * as Schedule from "effect/Schedule" +import type * as Types from "effect/Types" import type * as Unify from "effect/Unify" import type * as AiModel from "./AiModel.js" import type { AiModels } from "./AiModels.js" @@ -84,16 +85,49 @@ export declare namespace AiPlan { /** * @since 1.0.0 - * @category constructors + * @category models */ -export const fromModel: ( - model: AiModel.AiModel, - options?: { +export declare namespace make { + type Base = { + readonly model: AiModel.AiModel readonly attempts?: number | undefined - readonly while?: ((error: EW) => boolean | Effect.Effect) | undefined - readonly schedule?: Schedule.Schedule | undefined + readonly while?: ((error: any) => boolean | Effect.Effect) | undefined + readonly schedule?: Schedule.Schedule | undefined + } + type EW = Plan extends { readonly while: (error: infer X) => any } ? X : never + type ES = Plan extends { readonly schedule: Schedule.Schedule } ? X : never + type Provides = Plan extends { readonly model: AiModel.AiModel } ? X : never + type Requires = Plan extends { readonly model: AiModel.AiModel } ? X : never + type RW = Plan extends { readonly while: (error: any) => Effect.Effect } ? X + : never + type RS = Plan extends { readonly schedule: Schedule.Schedule } ? X : never + type MakePlan = AiPlan< + EW & ES, + Provides, + RW | RS | Requires + > extends infer X ? X : never + type MergePlan> = AiPlan< + Types.UnionToIntersection< + { [K in keyof Plans]: MakePlan extends AiPlan ? X : never }[number] + >, + { [K in keyof Plans]: MakePlan extends AiPlan ? X : never }[number], + { [K in keyof Plans]: MakePlan extends AiPlan ? X : never }[number] + > extends infer K ? K : never +} + +/** + * @since 1.0.0 + * @category constructors + */ +export const make: ]>( + ...plans: Plans +) => make.MergePlan = (function() { + let p = Internal.make(arguments[0]) + for (let i = 1; i < arguments.length; i++) { + p = p.pipe(withFallback(arguments[i])) } -) => AiPlan = Internal.fromModel + return p +}) as any /** * @since 1.0.0 diff --git a/packages/ai/ai/src/internal/aiPlan.ts b/packages/ai/ai/src/internal/aiPlan.ts index 1d078108649..b7cc86e7d61 100644 --- a/packages/ai/ai/src/internal/aiPlan.ts +++ b/packages/ai/ai/src/internal/aiPlan.ts @@ -88,16 +88,16 @@ const getRetryOptions = ( } /** @internal */ -export const fromModel = ( - model: AiModel.AiModel, - options?: { +export const make = ( + options: { + readonly model: AiModel.AiModel readonly attempts?: number | undefined readonly while?: ((error: EW) => boolean | Effect.Effect) | undefined readonly schedule?: Schedule.Schedule | undefined } ): AiPlan.AiPlan => makePlan([{ - model, + model: options.model, check: Option.fromNullable(options?.while) as any, schedule: resolveSchedule(options ?? {}) }])