Prompts and Responses
Every call to a LanguageModel flows through two provider-neutral data models:
Prompt— the conversation you send into the model: an ordered list of messages (system,user,assistant,tool), each made up of typed content parts (text, files, tool calls, tool results, reasoning, approval).Response— the model output that comes back: an ordered list of typed response parts (text, reasoning, tool calls, tool results, sources, metadata, finish info, errors), with both a non-streaming and a streaming taxonomy.
Both live in the effect/unstable/ai package:
import { Prompt, Response } from "effect/unstable/ai"The common case
Section titled “The common case”What prompt accepts (RawInput)
Section titled “What prompt accepts (RawInput)”The prompt option of generateText / streamText is typed as
Prompt.RawInput, which accepts three shapes: a string, an array of
encoded messages, or an already-built Prompt.
import { Prompt } from "effect/unstable/ai"
// 1. A string — becomes a single user messagePrompt.make("Summarize the Effect docs in one sentence.")
// 2. An array of (encoded) messagesPrompt.make([ { role: "system", content: "You are a terse assistant." }, { role: "user", content: [{ type: "text", text: "Say hi." }] }])
// 3. An existing Prompt is passed through unchangedconst existing = Prompt.make("hello")Prompt.make(existing) // => existingIn a LanguageModel call you usually pass the RawInput directly:
import { Effect } from "effect"import { LanguageModel } from "effect/unstable/ai"
const program = Effect.gen(function* () { // string RawInput const a = yield* LanguageModel.generateText({ prompt: "What is 2 + 2?" })
// message-array RawInput const b = yield* LanguageModel.generateText({ prompt: [ { role: "system", content: "You only answer with numbers." }, { role: "user", content: [{ type: "text", text: "What is 2 + 2?" }] } ] })
return [a.text, b.text]})Building a multi-message prompt
Section titled “Building a multi-message prompt”Use the role-specific constructors when you want typed, explicit messages — for example when storing and replaying conversation history.
import { Prompt } from "effect/unstable/ai"
const prompt = Prompt.fromMessages([ Prompt.systemMessage({ content: "You are a helpful assistant specialized in mathematics." }), Prompt.userMessage({ content: [Prompt.textPart({ text: "What is the derivative of x²?" })] }), Prompt.assistantMessage({ content: [Prompt.textPart({ text: "The derivative of x² is 2x." })] })])
prompt.content.length // => 3setSystem, prependSystem, appendSystem, and concat let you layer system
instructions and merge prompts without mutating the originals:
import { Prompt } from "effect/unstable/ai"
const base = Prompt.make("Write a haiku about TypeScript.")
const withSystem = base.pipe( Prompt.prependSystem("You are a poet. "))// => system: "You are a poet. " + user: "Write a haiku about TypeScript."
const longer = Prompt.concat(withSystem, "Now translate it to French.")// => appends a second user messageReading a non-streaming response
Section titled “Reading a non-streaming response”LanguageModel.generateText resolves to a GenerateTextResponse whose
accessors pull the relevant Response parts out of response.content for you.
import { Effect } from "effect"import { LanguageModel } from "effect/unstable/ai"
const program = Effect.gen(function* () { const response = yield* LanguageModel.generateText({ prompt: "What's the weather in SF?" })
response.text // => the concatenated text of all TextParts response.finishReason // => "stop" | "length" | "tool-calls" | ... response.usage // => Response.Usage instance response.toolCalls // => ReadonlyArray<Response.ToolCallPart<...>> response.toolResults // => ReadonlyArray<Response.ToolResultPart<...>> response.content // => the raw ordered Array<Response.Part>
return response.text})If you need finer control, iterate response.content and switch on
part.type — every part carries a type discriminator:
import { Effect } from "effect"import { LanguageModel } from "effect/unstable/ai"
const program = Effect.gen(function* () { const response = yield* LanguageModel.generateText({ prompt: "Call a tool, then summarize." })
for (const part of response.content) { switch (part.type) { case "text": console.log("text:", part.text) break case "tool-call": console.log("calling", part.name, "with", part.params) break case "tool-result": console.log("result for", part.name, "=>", part.result) break case "finish": console.log("done because", part.reason) break } }})Consuming a streamed response
Section titled “Consuming a streamed response”LanguageModel.streamText produces a Stream of Response.StreamParts. Text
arrives as a text-start / text-delta / text-end sequence keyed by a shared
id; reasoning and tool parameters follow the same start/delta/end pattern.
Accumulate the deltas, then treat the completed text as final.
import { Effect, Stream } from "effect"import { LanguageModel } from "effect/unstable/ai"
const program = Effect.gen(function* () { yield* LanguageModel.streamText({ prompt: "Stream a short story." }).pipe( Stream.runForEach((part) => Effect.sync(() => { switch (part.type) { case "text-delta": process.stdout.write(part.delta) // incremental chunk break case "tool-call": console.log("\ntool-call:", part.name) break case "finish": console.log("\nfinished:", part.reason) break } }) ) )})Prompt reference
Section titled “Prompt reference”A Prompt is { content: ReadonlyArray<Message> } plus a brand. Build prompts
with the constructors below rather than constructing the object literal.
RawInput
Section titled “RawInput”The union accepted by make and concat: string | Iterable<MessageEncoded> | Prompt. A string becomes a single user message; an iterable is decoded as
encoded messages.
import type { Prompt } from "effect/unstable/ai"
const a: Prompt.RawInput = "hi"const b: Prompt.RawInput = [{ role: "user", content: "hi" }]Prompt (interface + schema)
Section titled “Prompt (interface + schema)”Prompt.Prompt is the model type; the Prompt.Prompt const is a
Schema.Codec<Prompt, PromptEncoded> for decoding/encoding whole conversations
(e.g. to persist them).
import { Schema } from "effect"import { Prompt } from "effect/unstable/ai"
const decode = Schema.decodeUnknownSync(Prompt.Prompt)const prompt = decode({ content: [{ role: "user", content: "Hello" }]})prompt.content.length // => 1PromptEncoded
Section titled “PromptEncoded”The serialized shape: { content: ReadonlyArray<MessageEncoded> }. This is what
Schema.encode(Prompt.Prompt) produces and what you store on disk / in a DB.
A Prompt with no messages — a useful identity for folds and concat.
import { Prompt } from "effect/unstable/ai"
Prompt.empty.content // => []The primary constructor. Normalizes any RawInput into a Prompt.
import { Prompt } from "effect/unstable/ai"
Prompt.make("Hello").content.length // => 1 (a user message)fromMessages
Section titled “fromMessages”Builds a Prompt directly from an array of already-constructed Messages (no
decoding step).
import { Prompt } from "effect/unstable/ai"
const prompt = Prompt.fromMessages([ Prompt.systemMessage({ content: "Be brief." }), Prompt.userMessage({ content: [Prompt.textPart({ text: "Hi" })] })])prompt.content.length // => 2fromResponseParts
Section titled “fromResponseParts”Folds an array of Response.AnyParts back into a Prompt — completed text and
reasoning streams become assistant parts, tool calls/approvals go in an
assistant message, and non-preliminary tool results go in a tool message. This
is how you append a model turn to conversation history.
import { Prompt, Response } from "effect/unstable/ai"
const prompt = Prompt.fromResponseParts([ Response.makePart("text", { text: "Hello there!" })])prompt.content[0].role // => "assistant"concat
Section titled “concat”Appends one RawInput’s messages after another prompt’s messages, preserving
order. Dual-signature (data-first and data-last/pipeable).
import { Prompt } from "effect/unstable/ai"
const sys = Prompt.make([{ role: "system", content: "You are helpful." }])Prompt.concat(sys, "Hello!").content.length // => 2setSystem
Section titled “setSystem”Returns a new prompt whose system message is replaced by the given text, dropping any previous system messages.
import { Prompt } from "effect/unstable/ai"
const p = Prompt.make([{ role: "system", content: "Old." }, { role: "user", content: "Hi" }])Prompt.setSystem(p, "New.").content[0] // => system message with content "New."prependSystem
Section titled “prependSystem”Prepends content to the existing system message (or creates one), leaving a leading system message.
import { Prompt } from "effect/unstable/ai"
const p = Prompt.make([{ role: "system", content: "an expert." }])Prompt.prependSystem(p, "You are ").content[0]// => system content: "You are an expert."appendSystem
Section titled “appendSystem”Like prependSystem, but appends content to the existing system message instead.
import { Prompt } from "effect/unstable/ai"
const p = Prompt.make([{ role: "system", content: "You are an expert." }])Prompt.appendSystem(p, " Be concise.").content[0]// => system content: "You are an expert. Be concise."isPrompt
Section titled “isPrompt”Type guard for a Prompt value.
import { Prompt } from "effect/unstable/ai"
Prompt.isPrompt(Prompt.empty) // => truePrompt.isPrompt("hello") // => falseisMessage / isPart
Section titled “isMessage / isPart”Type guards for a prompt Message and a prompt content Part respectively.
import { Prompt } from "effect/unstable/ai"
Prompt.isMessage(Prompt.systemMessage({ content: "hi" })) // => truePrompt.isPart(Prompt.textPart({ text: "hi" })) // => truemakeMessage
Section titled “makeMessage”Generic message constructor — pass a role literal and the role’s params. The role-specific helpers below wrap this.
import { Prompt } from "effect/unstable/ai"
Prompt.makeMessage("user", { content: [Prompt.makePart("text", { text: "Hi" })]}).role // => "user"makePart
Section titled “makePart”Generic part constructor — pass a part type literal and its params. The
part-specific helpers below wrap this.
import { Prompt } from "effect/unstable/ai"
Prompt.makePart("text", { text: "Hi" }).type // => "text"Prompt messages
Section titled “Prompt messages”Prompt.Message is the union SystemMessage | UserMessage | AssistantMessage | ToolMessage. Each role has an interface, a Schema const of the same name, and
a lowercase constructor.
SystemMessage / systemMessage
Section titled “SystemMessage / systemMessage”System instructions/context. content is plain text.
import { Prompt } from "effect/unstable/ai"
Prompt.systemMessage({ content: "You are a helpful assistant." }).role// => "system"UserMessage / userMessage
Section titled “UserMessage / userMessage”User input. content is an array of TextPart | FilePart (the schema also
decodes a bare string into a single text part via ContentFromString).
import { Prompt } from "effect/unstable/ai"
Prompt.userMessage({ content: [ Prompt.textPart({ text: "What is in this image?" }), Prompt.filePart({ mediaType: "image/jpeg", data: "data:image/jpeg;base64,..." }) ]}).role // => "user"AssistantMessage / assistantMessage
Section titled “AssistantMessage / assistantMessage”Model responses for history. content may contain text, file, reasoning,
tool-call, tool-result, and tool-approval-request parts.
import { Prompt } from "effect/unstable/ai"
Prompt.assistantMessage({ content: [ Prompt.textPart({ text: "Let me check the weather." }), Prompt.toolCallPart({ id: "call_1", name: "get_weather", params: { city: "SF" }, providerExecuted: false }) ]}).role // => "assistant"ToolMessage / toolMessage
Section titled “ToolMessage / toolMessage”Tool-side content: ToolResultParts and ToolApprovalResponseParts answering an
assistant’s requests.
import { Prompt } from "effect/unstable/ai"
Prompt.toolMessage({ content: [ Prompt.toolResultPart({ id: "call_1", name: "get_weather", isFailure: false, result: { temperature: 72 } }) ]}).role // => "tool"Message / ContentFromString
Section titled “Message / ContentFromString”Prompt.Message is also a Schema.Codec over the message union, used internally
by the Prompt codec. Prompt.ContentFromString is the transform that lets a
string stand in for [{ type: "text", text }] when decoding user/assistant
content.
import { Schema } from "effect"import { Prompt } from "effect/unstable/ai"
const m = Schema.decodeUnknownSync(Prompt.Message)({ role: "user", content: "Hello" // decoded into a single TextPart})m.role // => "user"Prompt parts
Section titled “Prompt parts”Prompt.Part is the union of all content parts. Each has an interface, a Schema
const of the same name, and a lowercase constructor. All parts carry an
options field of type ProviderOptions (defaults to {}).
TextPart / textPart
Section titled “TextPart / textPart”Plain text content. The most common part.
import { Prompt } from "effect/unstable/ai"
Prompt.textPart({ text: "Hello, world!" }).type // => "text"ReasoningPart / reasoningPart
Section titled “ReasoningPart / reasoningPart”Provider-supplied reasoning summary attached to an assistant message. Not raw hidden chain-of-thought.
import { Prompt } from "effect/unstable/ai"
Prompt.reasoningPart({ text: "Compared options by price." }).type// => "reasoning"FilePart / filePart
Section titled “FilePart / filePart”A file attachment. data may be a base64/data-URL string, a Uint8Array, or a
URL.
import { Prompt } from "effect/unstable/ai"
Prompt.filePart({ mediaType: "application/pdf", fileName: "report.pdf", data: new Uint8Array([1, 2, 3])}).mediaType // => "application/pdf"ToolCallPart / toolCallPart
Section titled “ToolCallPart / toolCallPart”A request to invoke a tool. providerExecuted distinguishes provider-run from
framework-run tools.
import { Prompt } from "effect/unstable/ai"
Prompt.toolCallPart({ id: "call_123", name: "get_weather", params: { city: "San Francisco" }, providerExecuted: false}).name // => "get_weather"ToolResultPart / toolResultPart
Section titled “ToolResultPart / toolResultPart”The result of a tool call to feed back into the conversation. isFailure flags
whether the handler errored.
import { Prompt } from "effect/unstable/ai"
Prompt.toolResultPart({ id: "call_123", name: "get_weather", isFailure: false, result: { temperature: 22, condition: "sunny" }}).isFailure // => falseToolApprovalRequestPart / toolApprovalRequestPart
Section titled “ToolApprovalRequestPart / toolApprovalRequestPart”Stored in an assistant message when a tool needs user approval before running.
Pairs an approvalId with the toolCallId awaiting approval.
import { Prompt } from "effect/unstable/ai"
Prompt.toolApprovalRequestPart({ approvalId: "approval_123", toolCallId: "call_456"}).approvalId // => "approval_123"ToolApprovalResponsePart / toolApprovalResponsePart
Section titled “ToolApprovalResponsePart / toolApprovalResponsePart”The user’s answer to an approval request, placed in a tool message. Carries
approved and an optional reason.
import { Prompt } from "effect/unstable/ai"
Prompt.toolApprovalResponsePart({ approvalId: "approval_123", approved: false, reason: "Operation not allowed"}).approved // => falseProviderOptions
Section titled “ProviderOptions”Prompt.ProviderOptions is a Schema.Record<String, Json | null> for
provider-specific options attached to any message or part via its options
field. Augment per-part *Options interfaces to type these for a provider.
import type { Prompt } from "effect/unstable/ai"
const opts: Prompt.ProviderOptions = { anthropic: { cacheControl: { type: "ephemeral" } }}Response reference
Section titled “Response reference”A response is an ordered sequence of typed parts. Non-streaming responses use
complete parts (TextPart, ToolCallPart, …); streaming responses use
event parts (TextStartPart, TextDeltaPart, …). Every response part
carries a metadata field of type ProviderMetadata (defaults to {}) — note
this is metadata, distinct from a prompt part’s options.
makePart
Section titled “makePart”Generic response-part constructor: a type literal plus its params. Tool-aware
parts have dedicated constructors below.
import { Response } from "effect/unstable/ai"
Response.makePart("text", { text: "Hello" }).type // => "text"isPart
Section titled “isPart”Type guard for any response part.
import { Response } from "effect/unstable/ai"
Response.isPart(Response.makePart("text", { text: "hi" })) // => trueResult parts (non-streaming)
Section titled “Result parts (non-streaming)”These appear in generateText output (response.content).
TextPart
Section titled “TextPart”Plain text content. response.text concatenates the text of all TextParts.
import { Response } from "effect/unstable/ai"
Response.makePart("text", { text: "The answer is 42." }).text// => "The answer is 42."ReasoningPart
Section titled “ReasoningPart”Provider-exposed reasoning summary. Read via response.reasoningText.
import { Response } from "effect/unstable/ai"
Response.makePart("reasoning", { text: "Step 1: analyze the question..." }).type// => "reasoning"ToolCallPart / toolCallPart
Section titled “ToolCallPart / toolCallPart”A tool invocation requested by the model. Generic over Name and Params so the
parameters stay typed to the tool. Response.ToolCallPart(name, paramsSchema)
builds a schema for a specific tool.
import { Response } from "effect/unstable/ai"
const part = Response.toolCallPart({ id: "call_123", name: "get_weather", params: { city: "San Francisco" }, providerExecuted: false})part.params // => { city: "San Francisco" }ToolResultPart / toolResultPart
Section titled “ToolResultPart / toolResultPart”The decoded result of a tool call. It is a union of ToolResultSuccess and
ToolResultFailure (discriminated by isFailure), both carrying the decoded
result, the encodedResult, providerExecuted, and preliminary flags.
Response.ToolResultPart(name, success, failure) builds a tool-specific schema.
import { Response } from "effect/unstable/ai"
// success variantconst ok = Response.toolResultPart({ id: "call_123", name: "get_weather", isFailure: false, result: { temperature: 22 }, encodedResult: { temperature: 22 }, providerExecuted: false, preliminary: false})ok.isFailure // => false
// failure variantconst bad = Response.toolResultPart({ id: "call_124", name: "get_weather", isFailure: true, result: { message: "city not found" }, encodedResult: { message: "city not found" }, providerExecuted: false, preliminary: false})bad.isFailure // => trueToolApprovalRequestPart / toolApprovalRequestPart
Section titled “ToolApprovalRequestPart / toolApprovalRequestPart”Emitted instead of running a tool when the tool’s needsApproval is set. Pairs
an approvalId with the toolCallId.
import { Response } from "effect/unstable/ai"
Response.toolApprovalRequestPart({ approvalId: "approval_123", toolCallId: "call_456"}).toolCallId // => "call_456"FilePart
Section titled “FilePart”A binary file returned by the model. data is a Uint8Array when decoded (a
base64 string when encoded).
import { Response } from "effect/unstable/ai"
Response.makePart("file", { mediaType: "image/png", data: new Uint8Array([1, 2, 3])}).mediaType // => "image/png"DocumentSourcePart / UrlSourcePart
Section titled “DocumentSourcePart / UrlSourcePart”Citations for sources used to generate the response. Both have type: "source"
discriminated by sourceType ("document" vs "url").
import { Response } from "effect/unstable/ai"
const url = Response.makePart("source", { sourceType: "url", id: "src_1", url: new URL("https://effect.website"), title: "Effect"})url.sourceType // => "url"
const doc = Response.makePart("source", { sourceType: "document", id: "src_2", mediaType: "application/pdf", title: "Spec"})doc.sourceType // => "document"ResponseMetadataPart
Section titled “ResponseMetadataPart”Per-response metadata: provider id, modelId, timestamp, and the HTTP
request details. All fields may be undefined.
import { DateTime } from "effect"import { Response } from "effect/unstable/ai"
Response.makePart("response-metadata", { id: "resp_123", modelId: "gpt-4", timestamp: DateTime.nowUnsafe(), request: undefined}).modelId // => "gpt-4"FinishPart
Section titled “FinishPart”The terminal part of every response: the reason, token usage, and optional
HTTP response details. response.finishReason and response.usage read from
this part.
import { Response } from "effect/unstable/ai"
Response.makePart("finish", { reason: "stop", usage: new Response.Usage({ inputTokens: { uncached: undefined, total: 50, cacheRead: undefined, cacheWrite: undefined }, outputTokens: { total: 25, text: undefined, reasoning: undefined } }), response: undefined}).reason // => "stop"ErrorPart
Section titled “ErrorPart”Signals an error occurred while generating. error is unknown — narrow it
before reading Error fields.
import { Response } from "effect/unstable/ai"
Response.makePart("error", { error: new Error("boom") }).type // => "error"Stream parts
Section titled “Stream parts”In addition to the result parts above (which can also appear mid-stream), a
streamed response emits start/delta/end events. Accumulate deltas keyed by id.
TextStartPart / TextDeltaPart / TextEndPart
Section titled “TextStartPart / TextDeltaPart / TextEndPart”A text chunk lifecycle: text-start opens an id, each text-delta adds a
delta fragment, text-end closes it.
import { Response } from "effect/unstable/ai"
Response.makePart("text-start", { id: "t1" }).type // => "text-start"Response.makePart("text-delta", { id: "t1", delta: "Hel" }).delta // => "Hel"Response.makePart("text-end", { id: "t1" }).type // => "text-end"ReasoningStartPart / ReasoningDeltaPart / ReasoningEndPart
Section titled “ReasoningStartPart / ReasoningDeltaPart / ReasoningEndPart”The same start/delta/end lifecycle for streamed reasoning text.
import { Response } from "effect/unstable/ai"
Response.makePart("reasoning-start", { id: "r1" }).type // => "reasoning-start"Response.makePart("reasoning-delta", { id: "r1", delta: "Think" }).delta // => "Think"Response.makePart("reasoning-end", { id: "r1" }).type // => "reasoning-end"ToolParamsStartPart / ToolParamsDeltaPart / ToolParamsEndPart
Section titled “ToolParamsStartPart / ToolParamsDeltaPart / ToolParamsEndPart”Streamed tool-call parameters. tool-params-start includes the tool name and
providerExecuted; deltas are JSON fragments; tool-params-end closes the
chunk, after which a complete tool-call part follows.
import { Response } from "effect/unstable/ai"
Response.makePart("tool-params-start", { id: "tp1", name: "get_weather", providerExecuted: false}).name // => "get_weather"Response.makePart("tool-params-delta", { id: "tp1", delta: '{"city":' }).delta// => '{"city":'Response.makePart("tool-params-end", { id: "tp1" }).type // => "tool-params-end"Unions and schema builders
Section titled “Unions and schema builders”The Response module distinguishes three families. The type-level unions
describe the shapes; the like-named functions build a tool-aware Schema.Codec
from a Toolkit so tool-call params and tool-result payloads stay
aligned with each tool definition.
AnyPart / Part / StreamPart (types)
Section titled “AnyPart / Part / StreamPart (types)”AnyPart/AnyPartEncoded— every possible response part (tool parts useany).Part<Tools>/PartEncoded— non-streaming result parts, tool-typed.StreamPart<Tools>/StreamPartEncoded— streaming event parts, tool-typed.AllParts<Tools>/AllPartsEncoded— the full set (result + stream), tool-typed.
import type { Response } from "effect/unstable/ai"
// StreamPart is what Stream.runForEach receives from streamTextdeclare const part: Response.StreamPart<{}>part.type // => one of the streaming part type literalsAllParts / Part / StreamPart (schema builders)
Section titled “AllParts / Part / StreamPart (schema builders)”Each takes a Toolkit and returns a Schema.Codec over the corresponding union,
with ToolCallPart/ToolResultPart schemas generated per tool.
import { Schema } from "effect"import { Response, Tool, Toolkit } from "effect/unstable/ai"
const toolkit = Toolkit.make( Tool.make("GetWeather", { parameters: Schema.Struct({ city: Schema.String }), success: Schema.Struct({ temperature: Schema.Number }) }))
const partSchema = Response.Part(toolkit) // non-streaming, tool-awareconst streamSchema = Response.StreamPart(toolkit) // streaming, tool-awareconst allSchema = Response.AllParts(toolkit) // bothUsage, finish reason, and HTTP details
Section titled “Usage, finish reason, and HTTP details”A Schema.Class of token-usage statistics, split into inputTokens
(uncached, total, cacheRead, cacheWrite) and outputTokens (total,
text, reasoning). Every field is number | undefined.
import { Response } from "effect/unstable/ai"
const usage = new Response.Usage({ inputTokens: { uncached: 40, total: 50, cacheRead: 10, cacheWrite: 0 }, outputTokens: { total: 25, text: 20, reasoning: 5 }})usage.outputTokens.total // => 25FinishReason
Section titled “FinishReason”A Schema.Literals of why generation stopped:
"stop", "length", "content-filter", "tool-calls", "error", "pause",
"other", "unknown".
import type { Response } from "effect/unstable/ai"
const reason: Response.FinishReason = "tool-calls"ProviderMetadata
Section titled “ProviderMetadata”Schema.Record<String, Json | null> for provider-specific metadata attached to
any response part via its metadata field. Provider extra usage info typically
lands here on the FinishPart.
import type { Response } from "effect/unstable/ai"
const meta: Response.ProviderMetadata = { openai: { systemFingerprint: "fp_123" }}HttpRequestDetails / HttpResponseDetails
Section titled “HttpRequestDetails / HttpResponseDetails”Schemas describing the HTTP exchange with the provider. HttpRequestDetails
(on ResponseMetadataPart.request) captures method, url, urlParams,
hash, and headers; HttpResponseDetails (on FinishPart.response) captures
status and headers. Header values may be Redacted.
import type { Response } from "effect/unstable/ai"
const details: typeof Response.HttpResponseDetails.Type = { status: 200, headers: { "X-Request-Id": "req_abc123" }}Utility types and guards
Section titled “Utility types and guards”ConstructorParams
Section titled “ConstructorParams”Given a response part type, the params object accepted by its constructor — the
part minus the brand, type, sourceType, and metadata (which is optional).
import type { Response } from "effect/unstable/ai"
type Params = Response.ConstructorParams<Response.TextPart>// => { readonly text: string; readonly metadata?: ... }ToolCallParts / ToolResultParts
Section titled “ToolCallParts / ToolResultParts”Type-level helpers that map a Record<string, Tool.Any> to the union of its
ToolCallParts / ToolResultParts. Used internally to build Part,
StreamPart, and AllParts.
import type { Response, Tool } from "effect/unstable/ai"
declare const tools: Record<string, Tool.Any>type Calls = Response.ToolCallParts<typeof tools>type Results = Response.ToolResultParts<typeof tools>See also
Section titled “See also”- LanguageModel — produces a
PromptfromRawInputand returns responses with.text,.toolCalls,.usage, and friends. - Tools and Toolkits — define the tools whose schemas drive the
tool-aware
Response.Part/StreamPart/AllPartsbuilders.