import * as Context from "../Context.ts"; import * as Effect from "../Effect.ts"; import type * as JsonSchema from "../JsonSchema.ts"; import * as Schema from "../Schema.ts"; import * as Stream from "../Stream.ts"; import type { Span } from "../Tracer.ts"; import type { Concurrency, NoExcessProperties } from "../Types.ts"; import * as AiError from "./AiError.ts"; import { IdGenerator } from "./IdGenerator.ts"; import * as Prompt from "./Prompt.ts"; import * as Response from "./Response.ts"; import type * as Tool from "./Tool.ts"; import * as Toolkit from "./Toolkit.ts"; /** * Service key for text generation, structured output, and tool calls. * * **Example** (Accessing the language model service) * * ```ts import.meta.vitest * import { Effect, Layer, Stream } from "effect" * import { LanguageModel } from "effect/ai" * * const FakeLanguageModel = Layer.effect( * LanguageModel.LanguageModel, * LanguageModel.make({ * generateText: () => * Effect.succeed([{ * type: "text", * text: "Machine learning finds patterns in data." * }]), * streamText: () => Stream.empty * }) * ) * * const program = Effect.gen(function*() { * const model = yield* LanguageModel.LanguageModel * const response = yield* model.generateText({ * prompt: "What is machine learning?" * }) * return response.text * }) * * await Effect.runPromise(program.pipe(Effect.provide(FakeLanguageModel))) // => "Machine learning finds patterns in data." * ``` * * @stability unstable * @category services * @since 4.0.0 */ export declare const LanguageModel: Context.Service; /** * Brand type for `LanguageModel`. * * @stability unstable * @category type IDs * @since 4.0.0 */ export type TypeId = "~effect/ai/LanguageModel"; /** * Brand for `LanguageModel` implementations. * * @stability unstable * @category type IDs * @since 4.0.0 */ export declare const TypeId: TypeId; /** * Text generation, streaming, and structured output operations. * * @stability unstable * @category models * @since 4.0.0 */ export interface LanguageModel { readonly [TypeId]: TypeId; /** * Whether the effective provider configuration supports system messages in * history. Evaluate in the request's context to respect scoped overrides. * Placement restrictions may apply; an absent capability means unknown support. */ readonly supportsSystemMessagesInHistory?: Effect.Effect | undefined; /** * Generate text using the language model. */ readonly generateText: { >(options: Options & GenerateTextOptionsWithoutToolkit): Effect.Effect>, ExtractError, ExtractServices>; , Options extends NoExcessProperties & { readonly toolkit: ToolkitInput; }, Options>>(options: Options & GenerateTextOptions & { readonly toolkit: ToolkitInput; }): Effect.Effect>, ExtractError, ExtractServices>; ; } & NoExcessProperties, Options>>(options: Options & GenerateTextOptions> & { readonly toolkit: Options["toolkit"]; }): Effect.Effect, ExtractToolParametersMode>, ExtractError, ExtractServices>; }; /** * Generate a structured object from a schema using the language model. */ readonly generateObject: , StructuredOutputSchema extends Schema.Encoder, Options extends NoExcessProperties, Options>, Tools extends Record = {}>(options: Options & GenerateObjectOptions) => Effect.Effect>, ExtractError, ExtractServices | StructuredOutputSchema["DecodingServices"]>; /** * Generate text using the language model with streaming output. */ readonly streamText: { >(options: Options & GenerateTextOptionsWithoutToolkit): Stream.Stream>, ExtractError, ExtractServices>; , Options extends NoExcessProperties & { readonly toolkit: ToolkitInput; }, Options>>(options: Options & GenerateTextOptions & { readonly toolkit: ToolkitInput; }): Stream.Stream>, ExtractError, ExtractServices>; ; } & NoExcessProperties, Options>>(options: Options & GenerateTextOptions> & { readonly toolkit: Options["toolkit"]; }): Stream.Stream, ExtractToolParametersMode>, ExtractError, ExtractServices>; }; } /** * A function that transforms a `Schema.Codec` into a provider-compatible form for structured output generation. * * **Details** * * Different language model providers have varying constraints on the JSON * schemas they accept. A `CodecTransformer` rewrites a codec's encoded side to * satisfy those constraints while preserving the decoded type. A provider * schema may be less restrictive than the codec when the provider cannot * express every constraint; the returned codec remains authoritative for * validating model output. * * @stability unstable * @category utility types * @since 4.0.0 */ export type CodecTransformer = (schema: Schema.ConstraintCodec) => { readonly codec: Schema.ConstraintCodec; readonly jsonSchema: JsonSchema.JsonSchema; }; /** * The default codec transformer that passes schemas through without * provider-specific rewrites. * * **When to use** * * Use as the codec transformer for provider implementations when the provider * accepts the JSON Schema generated from an `Effect` Schema codec without * provider-specific rewrites. * * **Details** * * The transformer returns the original codec, resolves a top-level `$ref`, and * copies schema definitions into `$defs`. * * @see {@link CodecTransformer} for the structured-output transformer contract * @see {@link make} for where this transformer is used as the default * * @stability unstable * @category services * @since 4.0.0 */ export declare const defaultCodecTransformer: CodecTransformer; /** * Configuration options for text generation. * * @stability unstable * @category options * @since 4.0.0 */ export interface GenerateTextOptions> { /** * The prompt input to use to generate text. */ readonly prompt: Prompt.RawInput; /** * A toolkit containing both the tools and the tool call handler to use to * augment text generation. */ readonly toolkit?: ToolkitInput | undefined; /** * The tool choice mode for the language model. * - `auto` (default): The model can decide whether or not to call tools, as * well as which tools to call. * - `required`: The model **must** call a tool but can decide which tool will * be called. * - `none`: The model **must not** call a tool. * - `{ tool: }`: The model must call the specified tool. * - `{ mode?: "auto" (default) | "required", "oneOf": [] }`: The * model is restricted to the subset of tools specified by `oneOf`. When * `mode` is `"auto"` or omitted, the model can decide whether or not a tool * from the allowed subset of tools can be called. When `mode` is * `"required"`, the model **must** call one tool from the allowed subset of * tools. */ readonly toolChoice?: ToolChoice<{ [Name in keyof Tools]: Tools[Name]["name"]; }[keyof Tools]> | undefined; /** * The concurrency level for resolving tool calls. */ readonly concurrency?: Concurrency | undefined; /** * When set to `true`, tool calls requested by the large language model are not auto-resolved by the framework. * * **When to use** * * Use when you want to include tool call definitions from an `AiToolkit` * in requests to the large language model, while controlling tool call * resolver execution yourself. */ readonly disableToolCallResolution?: boolean | undefined; /** * Controls tool call validation when `disableToolCallResolution` is `true`. * Defaults to `"strict"`, which validates tool names and encoded parameters. * * **Details** * * `"deferred"` returns model-generated calls with `unknown` parameters for * the caller to validate, including undeclared names and calls without a * toolkit. Provider-executed calls and other response parts remain validated. * Providers must support this option to return undeclared tool calls. * * Has no effect when resolution is enabled; `Toolkit` validates parameters * according to each tool's `failureMode`. */ readonly toolCallValidation?: "strict" | "deferred" | undefined; } type GenerateTextOptionsWithoutToolkit = Omit, "toolkit"> & { readonly toolkit?: undefined; }; /** * Configuration options for structured object generation. * * @stability unstable * @category options * @since 4.0.0 */ export interface GenerateObjectOptions, StructuredOutputSchema extends Schema.Top> extends GenerateTextOptions { /** * The name of the structured output that should be generated. Used by some * large language model providers to provide additional guidance to the model. */ readonly objectName?: string | undefined; /** * The schema to be used to specify the structure of the object to generate. */ readonly schema: StructuredOutputSchema; } /** * The tool choice mode for the language model. * - `auto` (default): The model can decide whether or not to call tools, as * well as which tools to call. * - `required`: The model **must** call a tool but can decide which tool will * be called. * - `none`: The model **must not** call a tool. * - `{ tool: }`: The model must call the specified tool. * - `{ mode?: "auto" (default) | "required", "oneOf": [] }`: The * model is restricted to the subset of tools specified by `oneOf`. When * `mode` is `"auto"` or omitted, the model can decide whether or not a tool * from the allowed subset of tools can be called. When `mode` is * `"required"`, the model **must** call one tool from the allowed subset of * tools. * * @stability unstable * @category models * @since 4.0.0 */ export type ToolChoice = "auto" | "none" | "required" | { readonly tool: ToolName; } | { readonly mode?: "auto" | "required"; readonly oneOf: ReadonlyArray; }; /** * Response class for text generation operations, with accessors for extracting text, tool calls, usage information, and other response parts from generated content. * * **Example** (Inspecting a text response) * * ```ts import.meta.vitest * import { LanguageModel, Response } from "effect/ai" * * const response = new LanguageModel.GenerateTextResponse([ * Response.makePart("text", { text: "Plants convert light into energy." }) * ]) * * const result = [response.text, response.finishReason] // => ["Plants convert light into energy.", "unknown"] * ``` * * @stability unstable * @category models * @since 4.0.0 */ export declare class GenerateTextResponse, ParametersMode extends Response.ToolParametersMode = "decoded"> { readonly content: Array>; constructor(content: Array>); /** * Extracts and concatenates all text parts from the response. */ get text(): string; /** * Returns all reasoning parts from the response. */ get reasoning(): Array; /** * Extracts and concatenates all reasoning text, or undefined if none exists. */ get reasoningText(): string | undefined; /** * Returns all tool call parts from the response. */ get toolCalls(): Array>; /** * Returns all tool result parts from the response. */ get toolResults(): Array>; /** * The reason why text generation finished. */ get finishReason(): Response.FinishReason; /** * Token usage statistics for the generation request. */ get usage(): Response.Usage; } /** * Response class for structured object generation operations. * * **Example** (Inspecting an object response) * * ```ts import.meta.vitest * import { LanguageModel, Response } from "effect/ai" * * const response = new LanguageModel.GenerateObjectResponse( * { name: "John Doe", email: "john@example.com" }, * [Response.makePart("text", { text: '{"name":"John Doe","email":"john@example.com"}' })] * ) * * response.value // => { name: "John Doe", email: "john@example.com" } * response.text // => '{"name":"John Doe","email":"john@example.com"}' * ``` * * @stability unstable * @category models * @since 4.0.0 */ export declare class GenerateObjectResponse, A, ParametersMode extends Response.ToolParametersMode = "decoded"> extends GenerateTextResponse { /** * The parsed structured object that conforms to the provided schema. */ readonly value: A; constructor(value: A, content: Array>); } /** * The supported toolkit option shapes for language model operations. * * @stability unstable * @category utility types * @since 4.0.0 */ export type ToolkitOption, E = never, R = any> = Tools extends any ? (Toolkit.WithHandler | Effect.Effect, E, R>) : never; /** * The supported toolkit input shapes for language model operation options. * * **Details** * * Unlike `ToolkitOption`, this type does not distribute over unions. It is * intended for call-site assignability, while `ToolkitOption` remains the * distributive helper used for extraction and inference. * * @stability unstable * @category utility types * @since 4.0.0 */ export type ToolkitInput, E = never, R = any> = ToolkitOption | Toolkit.WithHandler | Effect.Effect, E, R>; type ExtractToolsFromToolkitOption = ToolkitValue extends Toolkit.WithHandler ? Tools : ToolkitValue extends Effect.Effect, infer _E, infer _R> ? _Tools : never; /** * Utility type that extracts the toolset from LanguageModel options. * * @stability unstable * @category utility types * @since 4.0.0 */ export type ExtractTools = Options extends { readonly toolkit: infer ToolkitValue; } ? ExtractToolsFromToolkitOption> : {}; /** * Resolves to `"deferred"` when tool call resolution may be disabled with * deferred tool call validation. Otherwise resolves to `"encoded"` when tool * call resolution is disabled and `"opaque"` when it may be enabled. * * @stability unstable * @category utility types * @since 4.0.0 */ export type ExtractToolParametersMode = "deferred" extends Options["toolCallValidation" & keyof Options] ? true extends Options["disableToolCallResolution" & keyof Options] ? "deferred" : "opaque" : Options extends { readonly disableToolCallResolution: true; } ? "encoded" : "opaque"; /** * Resolves the tool parameters mode for requests without a toolkit: * `"deferred"` when tool call validation may be deferred, otherwise * `"decoded"`. * * @stability unstable * @category utility types * @since 4.0.4 */ export type ExtractToolParametersModeWithoutToolkit = "deferred" extends ExtractToolParametersMode ? "deferred" : "decoded"; type ExtractErrorFromToolkitOption = ToolkitValue extends Toolkit.WithHandler ? AiError.AiError | (DisableToolCallResolution extends true ? never : Tool.HandlerError) : ToolkitValue extends Effect.Effect, infer E, infer _R> ? AiError.AiError | E | (DisableToolCallResolution extends true ? never : Tool.HandlerError<_Tools[keyof _Tools]>) : AiError.AiError; type ExtractServicesFromToolkitOption = ToolkitValue extends Toolkit.WithHandler ? Tool.HandlerServices | Tool.ResultDecodingServices | Tool.ParametersEncodingServices : ToolkitValue extends Effect.Effect, infer _E, infer R> ? Tool.HandlerServices | Tool.ResultDecodingServices | Tool.ParametersEncodingServices | R : never; type ExtractDisabledResolutionServicesFromToolkitOption = ToolkitValue extends Toolkit.WithHandler ? Tool.ParametersEncodingServices : ToolkitValue extends Toolkit.Toolkit ? Tool.ParametersEncodingServices : ToolkitValue extends Effect.Effect, infer _E, infer R> ? Tool.ParametersEncodingServices | R : never; /** * Utility type that extracts the error type from LanguageModel options. * * **Details** * * Automatically infers the possible error types based on toolkit configuration * and tool call resolution settings. * * @stability unstable * @category utility types * @since 4.0.0 */ export type ExtractError = Options extends { readonly disableToolCallResolution: true; readonly toolkit: infer ToolkitValue; } ? ExtractErrorFromToolkitOption, true> : Options extends { readonly toolkit: infer ToolkitValue; } ? ExtractErrorFromToolkitOption, false> : Options extends { readonly disableToolCallResolution: true; } ? AiError.AiError : AiError.AiError; /** * Utility type that extracts the context requirements from LanguageModel options. * * **Details** * * Automatically infers the required services based on the toolkit configuration. * * @stability unstable * @category utility types * @since 4.0.0 */ export type ExtractServices = Options extends { readonly disableToolCallResolution: true; } ? Options extends { readonly toolkit: infer ToolkitValue; } ? ExtractDisabledResolutionServicesFromToolkitOption> : never : Options extends { readonly toolkit: infer ToolkitValue; } ? ExtractServicesFromToolkitOption> : never; /** * Configuration options passed along to language model provider implementations. * * **Details** * * This interface defines the normalized options that are passed to the * underlying provider implementation, regardless of the specific provider being * used. * * @stability unstable * @category options * @since 4.0.0 */ export interface ProviderOptions { /** * The prompt messages to use to generate text. */ readonly prompt: Prompt.Prompt; /** * The tools that the large language model will have available to provide * additional information which can be incorporated into its text generation. */ readonly tools: ReadonlyArray; /** * The format the response should be provided in. * * **Details** * * If `"text"` is specified, the large language model response is returned as * text. If `"json"` is specified, the large language model response is * provided as a JSON object that conforms to the shape of the specified schema. * The default is `{ type: "text" }`. */ readonly responseFormat: { readonly type: "text"; } | { readonly type: "json"; readonly objectName: string; readonly schema: Schema.Top; }; /** * The tool choice mode for the language model. * - `auto` (default): The model can decide whether or not to call tools, as * well as which tools to call. * - `required`: The model **must** call a tool but can decide which tool will * be called. * - `none`: The model **must not** call a tool. * - `{ tool: }`: The model must call the specified tool. * - `{ mode?: "auto" (default) | "required", "oneOf": [] }`: The * model is restricted to the subset of tools specified by `oneOf`. When * `mode` is `"auto"` or omitted, the model can decide whether or not a tool * from the allowed subset of tools can be called. When `mode` is * `"required"`, the model **must** call one tool from the allowed subset of * tools. */ readonly toolChoice: ToolChoice; /** * The span to use to trace interactions with the large language model. */ readonly span: Span; /** * The previous response identifier for incremental provider calls. */ readonly previousResponseId: string | undefined; /** * The prompt reduced to messages not yet seen by the provider. */ readonly incrementalPrompt: Prompt.Prompt | undefined; /** * Whether this request is retrying an incremental request with the full * prompt after the provider rejected the incremental request. */ readonly incrementalFallback?: boolean | undefined; /** * Defaults to `"strict"`. With `"deferred"`, return calls to tools absent * from `tools` with unchanged parameters instead of `ToolNotFoundError`. */ readonly toolCallValidation?: "strict" | "deferred" | undefined; } /** * Creates a LanguageModel service from provider-specific text generation and * streaming implementations. * * **When to use** * * Use when you are implementing a provider adapter and need to expose the * standard language-model service while keeping provider-specific request hooks * behind it. * * **Details** * * The returned service implements `generateText`, `generateObject`, and * `streamText`. It prepares `ProviderOptions` for each request, including the * normalized prompt, tools, tool choice, response format, tracing span, and * incremental response fields, before calling the supplied provider hook. * Structured object generation uses the `generateText` hook and the configured * `codecTransformer`, or `defaultCodecTransformer` when none is supplied. * * **Gotchas** * * Provider hooks must return encoded response parts that match the toolkit and * response format prepared in `ProviderOptions`; invalid parts fail decoding as * `AiError.InvalidOutputError`. * * @see {@link LanguageModel} for the returned service contract * @see {@link ProviderOptions} for the normalized options passed to provider hooks * @see {@link defaultCodecTransformer} for the default structured-output schema transformer * * @stability unstable * @category constructors * @since 4.0.0 */ export declare const make: (params: { /** * A method that requests text generation from the large language model provider and returns the final result when generation finishes. */ readonly generateText: (options: ProviderOptions) => Effect.Effect, AiError.AiError, IdGenerator>; /** * A method that requests text generation from the large language model provider and streams intermediate results. */ readonly streamText: (options: ProviderOptions) => Stream.Stream; /** * A function that transforms a `Schema.Codec` into a provider-compatible form * for structured output generation. */ readonly codecTransformer?: CodecTransformer | undefined; /** Whether the effective provider configuration supports system messages in history. */ readonly supportsSystemMessagesInHistory?: Effect.Effect | undefined; }) => Effect.Effect; /** * Generates text using a language model. * * **Example** (Generating text with options) * * ```ts import.meta.vitest * import { Effect, Layer, Stream } from "effect" * import { LanguageModel } from "effect/ai" * * const FakeLanguageModel = Layer.effect( * LanguageModel.LanguageModel, * LanguageModel.make({ * generateText: (options) => * Effect.succeed([ * { * type: "text", * text: options.toolChoice === "none" * ? "Code flows through types / Errors become values / Programs stay composed" * : "Unexpected tool choice" * }, * { * type: "finish", * reason: "stop", * usage: { * inputTokens: { total: 6 }, * outputTokens: { total: 12 } * } * } * ]), * streamText: () => Stream.empty * }) * ) * * const program = LanguageModel.generateText({ * prompt: "Write a haiku about programming", * toolChoice: "none" * }).pipe( * Effect.map((response) => [response.text, response.usage.inputTokens.total]), * Effect.provide(FakeLanguageModel) * ) * * await Effect.runPromise(program) // => ["Code flows through types / Errors become values / Programs stay composed", 6] * ``` * * @stability unstable * @category text generation * @since 4.0.0 */ export declare const generateText: { >(options: Options & GenerateTextOptionsWithoutToolkit): Effect.Effect>, ExtractError, LanguageModel | ExtractServices>; , Options extends NoExcessProperties & { readonly toolkit: ToolkitInput; }, Options>>(options: Options & GenerateTextOptions & { readonly toolkit: ToolkitInput; }): Effect.Effect>, ExtractError, LanguageModel | ExtractServices>; ; } & NoExcessProperties, Options>>(options: Options & GenerateTextOptions> & { readonly toolkit: Options["toolkit"]; }): Effect.Effect, ExtractToolParametersMode>, ExtractError, ExtractServices | LanguageModel>; }; /** * Generates a structured object from a schema using a language model. * * **Example** (Generating an object) * * ```ts import.meta.vitest * import { Effect, Layer, Schema, Stream } from "effect" * import { LanguageModel } from "effect/ai" * * const EventSchema = Schema.Struct({ * title: Schema.String, * date: Schema.String, * location: Schema.String * }) * * const FakeLanguageModel = Layer.effect( * LanguageModel.LanguageModel, * LanguageModel.make({ * generateText: () => * Effect.succeed([{ * type: "text", * text: '{"title":"Tech Conference","date":"March 15th","location":"San Francisco"}' * }]), * streamText: () => Stream.empty * }) * ) * * const program = LanguageModel.generateObject({ * prompt: "Extract event info: Tech Conference on March 15th in San Francisco", * schema: EventSchema, * objectName: "event" * }).pipe( * Effect.map((response) => response.value), * Effect.provide(FakeLanguageModel) * ) * * await Effect.runPromise(program) // => { title: "Tech Conference", date: "March 15th", location: "San Francisco" } * ``` * * @stability unstable * @category generators * @since 4.0.0 */ export declare const generateObject: , StructuredOutputSchema extends Schema.Encoder, Options extends NoExcessProperties, Options>>(options: Options & GenerateObjectOptions, StructuredOutputSchema>) => Effect.Effect, StructuredOutputSchema["Type"], ExtractToolParametersMode>, ExtractError, ExtractServices | StructuredOutputSchema["DecodingServices"] | LanguageModel>; /** * Generates text using a language model with streaming output. * * **Details** * * Returns a stream of response parts that are emitted as soon as they are * available from the model, enabling real-time text generation experiences. * * **Example** (Streaming text deltas) * * ```ts import.meta.vitest * import { Effect, Layer, Stream } from "effect" * import { LanguageModel } from "effect/ai" * * const FakeLanguageModel = Layer.effect( * LanguageModel.LanguageModel, * LanguageModel.make({ * generateText: () => Effect.succeed([]), * streamText: () => * Stream.make( * { type: "text-delta", id: "story", delta: "The explorer reached orbit." }, * { type: "text-delta", id: "story", delta: " Earth glowed below." } * ) * }) * ) * * const program = LanguageModel.streamText({ * prompt: "Write a story about a space explorer" * }).pipe( * Stream.runFold(() => "", (text, part) => part.type === "text-delta" ? text + part.delta : text), * Effect.provide(FakeLanguageModel) * ) * * await Effect.runPromise(program) // => "The explorer reached orbit. Earth glowed below." * ``` * * @stability unstable * @category text generation * @since 4.0.0 */ export declare const streamText: { >(options: Options & GenerateTextOptionsWithoutToolkit): Stream.Stream>, ExtractError, ExtractServices | LanguageModel>; , Options extends NoExcessProperties & { readonly toolkit: ToolkitInput; }, Options>>(options: Options & GenerateTextOptions & { readonly toolkit: ToolkitInput; }): Stream.Stream>, ExtractError, ExtractServices | LanguageModel>; ; } & NoExcessProperties, Options>>(options: Options & GenerateTextOptions> & { readonly toolkit: Options["toolkit"]; }): Stream.Stream, ExtractToolParametersMode>, ExtractError, ExtractServices | LanguageModel>; }; export {}; //# sourceMappingURL=LanguageModel.d.ts.map