import type * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import type { RuntimeContext } from "../RuntimeContext.ts"; import { effectClass } from "../Util/effect.ts"; import type { ToolImpl } from "./Tool.ts"; export type Services = Refs[number] extends infer A ? A extends | ToolImpl | Context.Service ? Req : never : never; export interface Agent< Name extends string = string, Refs extends any[] = any[], Service = AgentService, Req = never, > { [Symbol.iterator](): Effect.EffectIterator< Effect.Effect >; "~alchemy/Kind": "Agent"; name: Name; refs: Refs; req: Services; new (): AgentService; } export interface AgentService { send(request: { input: any; session?: string; }): Effect.Effect; } export const Agent: { (): { ( id: Name, ): { ( template: TemplateStringsArray, ...refs: Refs ): Agent>; }; }; ( id: Name, ): { ( template: TemplateStringsArray, ...refs: Refs ): Agent>; }; } = ((name?: string) => name ? (template: TemplateStringsArray, ...refs: any[]) => makeAgent(name, template, refs) : (name: string) => (template: TemplateStringsArray, ...refs: any[]) => makeAgent(name, template, refs)) as any; const makeAgent = (name: string, template: TemplateStringsArray, refs: any[]) => Object.assign( effectClass( Effect.gen(function* () { // TODO(sam): implement the agent }), ), { "~alchemy/Kind": "Agent", "~alchemy/Name": name, refs, template, }, ) as any;