Skip to content

align AiPlan constructor to fallback #4781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 41 additions & 7 deletions packages/ai/ai/src/AiPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -84,16 +85,49 @@ export declare namespace AiPlan {

/**
* @since 1.0.0
* @category constructors
* @category models
*/
export const fromModel: <Provides, Requires, EW, Out, ES, RW = never, RS = never>(
model: AiModel.AiModel<Provides, Requires>,
options?: {
export declare namespace make {
type Base = {
readonly model: AiModel.AiModel<any, any>
readonly attempts?: number | undefined
readonly while?: ((error: EW) => boolean | Effect.Effect<boolean, never, RW>) | undefined
readonly schedule?: Schedule.Schedule<Out, ES, RS> | undefined
readonly while?: ((error: any) => boolean | Effect.Effect<boolean, never, any>) | undefined
readonly schedule?: Schedule.Schedule<any, any, any> | undefined
}
type EW<Plan extends Base> = Plan extends { readonly while: (error: infer X) => any } ? X : never
type ES<Plan extends Base> = Plan extends { readonly schedule: Schedule.Schedule<any, infer X, any> } ? X : never
type Provides<Plan extends Base> = Plan extends { readonly model: AiModel.AiModel<infer X, any> } ? X : never
type Requires<Plan extends Base> = Plan extends { readonly model: AiModel.AiModel<any, infer X> } ? X : never
type RW<Plan extends Base> = Plan extends { readonly while: (error: any) => Effect.Effect<any, any, infer X> } ? X
: never
type RS<Plan extends Base> = Plan extends { readonly schedule: Schedule.Schedule<any, any, infer X> } ? X : never
type MakePlan<Plan extends Base> = AiPlan<
EW<Plan> & ES<Plan>,
Provides<Plan>,
RW<Plan> | RS<Plan> | Requires<Plan>
> extends infer X ? X : never
type MergePlan<Plans extends ReadonlyArray<Base>> = AiPlan<
Types.UnionToIntersection<
{ [K in keyof Plans]: MakePlan<Plans[K]> extends AiPlan<infer X, any, any> ? X : never }[number]
>,
{ [K in keyof Plans]: MakePlan<Plans[K]> extends AiPlan<any, infer X, any> ? X : never }[number],
{ [K in keyof Plans]: MakePlan<Plans[K]> extends AiPlan<any, any, infer X> ? X : never }[number]
> extends infer K ? K : never
}

/**
* @since 1.0.0
* @category constructors
*/
export const make: <Plans extends readonly [make.Base, ...ReadonlyArray<make.Base>]>(
...plans: Plans
) => make.MergePlan<Plans> = (function() {
let p = Internal.make(arguments[0])
for (let i = 1; i < arguments.length; i++) {
p = p.pipe(withFallback(arguments[i]))
}
) => AiPlan<EW & ES, Provides, RW | RS | Requires> = Internal.fromModel
return p
}) as any

/**
* @since 1.0.0
Expand Down
8 changes: 4 additions & 4 deletions packages/ai/ai/src/internal/aiPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@ const getRetryOptions = <Error, Provides, Requires>(
}

/** @internal */
export const fromModel = <Provides, Requires, EW, Out, ES, RW = never, RS = never>(
model: AiModel.AiModel<Provides, Requires>,
options?: {
export const make = <Provides, Requires, EW, Out, ES, RW = never, RS = never>(
options: {
readonly model: AiModel.AiModel<Provides, Requires>
readonly attempts?: number | undefined
readonly while?: ((error: EW) => boolean | Effect.Effect<boolean, never, RW>) | undefined
readonly schedule?: Schedule.Schedule<Out, ES, RS> | undefined
}
): AiPlan.AiPlan<EW & ES, Provides, RW | RS | Requires> =>
makePlan([{
model,
model: options.model,
check: Option.fromNullable(options?.while) as any,
schedule: resolveSchedule(options ?? {})
}])
Expand Down