Migrating to 0.15
No rewrites needed. 0.15 is additive: one new capability tag in
@effect-uai/core, three new packages (@effect-uai/telegram,
@effect-uai/discord, @effect-uai/slack), and a small input-batching
helper. Bump your dependencies, run typecheck, done.
No effect bump this release; the peer range stays >=4.0.0-rc.111 <5.0.0.
0.14 was additive too (the ImageGenerator capability) and has no page of
its own. If you hit a compile error that looks like a rename, you are
crossing an earlier breaking release. Apply the 0.13
page and the ones before it first.
What’s new (additive, no migration needed)
Messenger
Messenger puts your agent loop in a chat: one stream of what people say,
five verbs for answering, and a provider layer per platform. Your loop,
tools and history stay as they are.
import * as Messenger from "@effect-uai/core/Messenger"
const messenger = yield * Messenger.Messenger
const reply = (event: Messenger.InboundEvent) => event._tag === "Message" && event.addressed ? messenger .post(Messenger.text(`You said: ${event.text}`, { replyTo: event.id })) .pipe(Messenger.inConversation(event.conversation)) : Effect.void
yield * Stream.runForEach(messenger.events, reply)eventscarriesMessage(withaddressed: a DM, an@mention, or a reply to the bot),Command,ReactionandAction, each with the platform’srawpayload.post,edit,react,typing(scoped) andstream(aStream<string>delivered as one message that fills in as the model writes). A message isMessenger.text,Messenger.mediaover the coreMediaSource, orMessenger.rawfor the platform’s own payload.- The chat a verb targets is ambient:
Messenger.inConversation(ref)once where a conversation starts, and every post underneath lands there, tools included. Posting outside a conversation is a compile error. - Text goes out verbatim. Your system prompt tells the model which markup to write; each provider page says which.
MessengerErrorcovers the failures:RequestFailed,RateLimited,Unsupported,ConnectFailed,TransportClosed.@effect-uai/core/MessengerAdapteris the adapter author’s side (splitForLimit,streamViaEdits), and@effect-uai/core/testing/MockMessengerreplays scripted events and records every verb for unit tests.
Three providers, each a long-lived process with no public URL and no SDK:
pnpm add @effect-uai/telegram # Bot API, long-polling, HTML markuppnpm add @effect-uai/discord # gateway websocket + REST v10, markdownpnpm add @effect-uai/slack # Socket Mode + Web API, markdown, replies in threadsSee Messenger, the provider pages for Telegram, Discord and Slack, and the messenger agent recipe.
Inbox.drainBurst
@effect-uai/core/Inbox has drainBurst(queue, settle): block on the first
item, then keep taking while items keep arriving within settle, and hand
back the batch. It is the debounce a long-lived loop reads its input with,
so three quick messages become one turn.
import { drainBurst } from "@effect-uai/core/Inbox"
const incoming = yield * drainBurst(inbox, "800 millis")It used to live inside the agentic-loop recipe; the recipe now imports it from core.