@adonis-agora/agent 0.64.1 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/src/agent-service.d.ts +10 -1
  3. package/dist/src/agent-service.d.ts.map +1 -1
  4. package/dist/src/agent-service.js +3 -2
  5. package/dist/src/agent-service.js.map +1 -1
  6. package/dist/src/channels/adapters/evolution_api.d.ts.map +1 -1
  7. package/dist/src/channels/adapters/evolution_api.js +25 -1
  8. package/dist/src/channels/adapters/evolution_api.js.map +1 -1
  9. package/dist/src/channels/adapters/telegram.d.ts +2 -1
  10. package/dist/src/channels/adapters/telegram.d.ts.map +1 -1
  11. package/dist/src/channels/adapters/telegram.js +57 -4
  12. package/dist/src/channels/adapters/telegram.js.map +1 -1
  13. package/dist/src/channels/adapters/whatsapp_cloud.d.ts +3 -2
  14. package/dist/src/channels/adapters/whatsapp_cloud.d.ts.map +1 -1
  15. package/dist/src/channels/adapters/whatsapp_cloud.js +55 -4
  16. package/dist/src/channels/adapters/whatsapp_cloud.js.map +1 -1
  17. package/dist/src/channels/executor.d.ts +116 -0
  18. package/dist/src/channels/executor.d.ts.map +1 -0
  19. package/dist/src/channels/executor.js +138 -0
  20. package/dist/src/channels/executor.js.map +1 -0
  21. package/dist/src/channels/handler.d.ts +228 -89
  22. package/dist/src/channels/handler.d.ts.map +1 -1
  23. package/dist/src/channels/handler.js +829 -388
  24. package/dist/src/channels/handler.js.map +1 -1
  25. package/dist/src/channels/http.d.ts +15 -0
  26. package/dist/src/channels/http.d.ts.map +1 -1
  27. package/dist/src/channels/http.js +43 -0
  28. package/dist/src/channels/http.js.map +1 -1
  29. package/dist/src/channels/index.d.ts +7 -4
  30. package/dist/src/channels/index.d.ts.map +1 -1
  31. package/dist/src/channels/index.js +6 -3
  32. package/dist/src/channels/index.js.map +1 -1
  33. package/dist/src/channels/texts.d.ts +102 -0
  34. package/dist/src/channels/texts.d.ts.map +1 -0
  35. package/dist/src/channels/texts.js +79 -0
  36. package/dist/src/channels/texts.js.map +1 -0
  37. package/dist/src/channels/types.d.ts +41 -1
  38. package/dist/src/channels/types.d.ts.map +1 -1
  39. package/dist/src/durable/agent-run-context.d.ts +10 -0
  40. package/dist/src/durable/agent-run-context.d.ts.map +1 -1
  41. package/dist/src/durable/agent-run-context.js +22 -0
  42. package/dist/src/durable/agent-run-context.js.map +1 -1
  43. package/dist/src/index.d.ts +2 -2
  44. package/dist/src/index.d.ts.map +1 -1
  45. package/dist/src/index.js +1 -1
  46. package/dist/src/index.js.map +1 -1
  47. package/package.json +1 -1
  48. package/skills/agent-setup/SKILL.md +9 -2
@@ -1,90 +1,142 @@
1
1
  import type { HttpContext } from '@adonisjs/core/http';
2
- import { type TextActionProposalVocabulary } from '../action-proposal-text.js';
3
2
  import { AgentService } from '../agent-service.js';
4
3
  import type { AttachmentLimits } from '../attachment-limits.js';
4
+ import type { UiCapabilities } from '../genui/capabilities.js';
5
5
  import type { ActionProposal } from '../spi/action-proposal-store.js';
6
- import type { ToolConfirmation } from '../tool-presentation.js';
6
+ import type { AttachmentRef } from '../spi/attachment-staging.js';
7
7
  import type { Actor, PageContext } from '../types.js';
8
- import { type ChannelQuestionTexts } from './questions.js';
8
+ import { type ChannelRetryOptions, type ChannelWorkflowEngine } from './executor.js';
9
9
  import { type ChannelStore } from './store.js';
10
- import type { ChannelAdapter, InboundMedia, InboundMessage } from './types.js';
10
+ import { type ChannelComponent, type ChannelMediaRefusal, type ChannelTexts, type ChannelTextsOverrides } from './texts.js';
11
+ import type { ChannelAdapter, ChannelMediaFile, ChannelRequest, InboundMedia, InboundMessage, OutboundMedia, OutboundMessage } from './types.js';
11
12
  /**
12
13
  * What a channel turn needs from the agent — `AgentService` is one. The optional methods turn
13
14
  * features on: proposals (buttons, outcomes), questions (`answer`), media (`stageAttachment`), and
14
15
  * the Lucid default store (`lucidDatabase`).
15
16
  */
16
- export interface ChannelTurnService extends Pick<AgentService, 'send' | 'subscribe' | 'skip' | 'cancel' | 'actionProposalReply'>, Partial<Pick<AgentService, 'decideActionProposal' | 'listActionProposals' | 'actionProposalVocabulary' | 'actionApprovalMode' | 'answer' | 'attachmentLimits' | 'stageAttachment' | 'lucidDatabase'>> {
17
- }
18
- /** A proposal the turn left pending, as the channel puts it to the person. */
19
- export interface ChannelProposal {
20
- id: string;
21
- toolName: string;
22
- confirmation?: ToolConfirmation;
17
+ export interface ChannelTurnService extends Pick<AgentService, 'subscribe' | 'skip' | 'cancel' | 'actionProposalReply'>, Partial<Pick<AgentService, 'decideActionProposal' | 'listActionProposals' | 'actionProposalVocabulary' | 'actionApprovalMode' | 'answer' | 'attachmentLimits' | 'stageAttachment' | 'lucidDatabase'>> {
18
+ /**
19
+ * Start (or queue) a turn. The channel passes `{ textDecisions: false }`: it decides text
20
+ * decisions itself, only for the cards it delivered to the conversation.
21
+ */
22
+ send(...args: Parameters<AgentService['send']>): ReturnType<AgentService['send']>;
23
23
  }
24
- /** Why a media message could not be attached. */
25
- export type ChannelMediaRefusal = 'disabled' | 'type' | 'size' | 'failed';
26
24
  /**
27
- * Everything the channel says on its own (not the model). English by default, Brazilian Portuguese
28
- * ({@link ptBrChannelTexts}) when the agent's `actionProposalText` is `ptBrActionProposalText`;
29
- * override any.
25
+ * Something the channel sends on the app's behalf (a hook's answer): text in the model's markdown
26
+ * (converted and split for the channel), text sent exactly as given (`raw` — a message the person
27
+ * forwards as is), or a file with a caption.
30
28
  */
31
- export interface ChannelTexts {
32
- /** The Confirm button's label. */
33
- approve: string;
34
- /** The Cancel button's label. */
35
- reject: string;
36
- /** What a proposal says above its buttons — default: its confirmation's bold title and detail. */
37
- proposal(proposal: ChannelProposal): string;
38
- /**
39
- * How to answer a proposal by text, when there are no buttons. `approve`/`reject` are the reply
40
- * commands, built from the configured `actionProposalText.vocabulary` — `#ID` included when more
41
- * than one proposal is waiting.
42
- */
43
- instruction(commands: {
44
- approve: string;
45
- reject: string;
46
- }): string;
47
- /** An approval in blocking mode, which a text channel cannot settle. */
48
- blockingApproval: string;
49
- /** The turn failed. */
50
- failed: string;
51
- /** An approved action ran, and presented nothing the channel could show. */
52
- actionSucceeded: string;
53
- /** An approved action's execution failed. */
54
- actionFailed: string;
55
- /** A file that could not be attached — no attachment store, a type or size it refuses, a failed download. */
56
- mediaRefused(reason: ChannelMediaRefusal, media: InboundMedia, limits: AttachmentLimits | null): string;
57
- /** How questions (the `ask` tool, intakes) are worded. */
58
- questions: ChannelQuestionTexts;
59
- /** Answer a sender `actor()` maps to nobody. Omitted → say nothing. */
60
- unknownSender?: string;
29
+ export type ChannelReply = string | {
30
+ text: string;
31
+ raw?: boolean;
32
+ } | {
33
+ media: OutboundMedia;
34
+ /** In the model's markdown, converted. */
35
+ caption?: string;
36
+ /** What a channel without files sends instead. Default: the caption. */
37
+ fallbackText?: string;
38
+ };
39
+ /** What {@link ChannelHandleOptions.beforeTurn} decides. */
40
+ export type ChannelGate = 'continue' | 'stop' | undefined | {
41
+ reply: ChannelReply;
42
+ } | {
43
+ replies: ChannelReply[];
44
+ };
45
+ /** What a hook is told about the message being handled. */
46
+ export interface ChannelHookContext {
47
+ /** The adapter's name. */
48
+ channel: string;
49
+ conversation: string;
50
+ message: InboundMessage;
61
51
  }
62
- export declare const DEFAULT_CHANNEL_TEXTS: ChannelTexts;
63
- /**
64
- * Brazilian Portuguese channel texts — the default when the agent's `actionProposalText` is
65
- * `ptBrActionProposalText`, so the reply words and what the channel says agree.
66
- */
67
- export declare const ptBrChannelTexts: ChannelTexts;
68
- /**
69
- * The channel texts that speak the language of the agent's text-decision words: {@link
70
- * ptBrChannelTexts} for `ptBrActionProposalText` (or any vocabulary whose `language` is Portuguese),
71
- * else {@link DEFAULT_CHANNEL_TEXTS}.
72
- */
73
- export declare function channelTextsFor(vocabulary?: TextActionProposalVocabulary | null): ChannelTexts;
74
- /**
75
- * `texts` as `channels.handle` takes it: any part, `questions` too — over the texts in the language of
76
- * the agent's `actionProposalText` (see {@link channelTextsFor}).
77
- */
78
- export type ChannelTextsOverrides = Partial<Omit<ChannelTexts, 'questions'>> & {
79
- questions?: Partial<ChannelQuestionTexts>;
52
+ /** One message about to go out — what {@link ChannelHandleOptions.canDeliver} checks. */
53
+ export interface ChannelDelivery {
54
+ channel: string;
55
+ conversation: string;
56
+ /** What goes out, exactly as the adapter will get it. */
57
+ outbound: OutboundMessage;
58
+ /**
59
+ * What it is: the turn's answer (`reply`), a proposal card, a relayed `outcome`, a `question`, a
60
+ * hook's answer before the turn (`gate`), or the channel's own text (`notice`).
61
+ */
62
+ kind: 'reply' | 'card' | 'outcome' | 'question' | 'gate' | 'notice';
63
+ /** Who the conversation was answered as, when known. */
64
+ actor: Actor | null;
65
+ /** The account reference the outbound belongs to: the actor's id, or a relayed proposal's `actorRef`. */
66
+ actorRef: string | null;
67
+ /** The message being answered, when there is one. */
68
+ message: InboundMessage | null;
69
+ /** The proposal whose outcome is relayed (`kind: 'outcome'`). */
70
+ proposal: ActionProposal | null;
71
+ }
72
+ /** What a webhook request came to — {@link ChannelHandleOptions.onWebhook}. */
73
+ export interface ChannelWebhookEvent {
74
+ channel: string;
75
+ /**
76
+ * `accepted` → at least one new message taken; `duplicate` → only messages already taken;
77
+ * `ignored` → a verified body with no message to answer; `unauthorized` → `verify` refused it;
78
+ * `challenge` → a subscription check answered; `method_not_allowed`; `failed` → the messages
79
+ * could not be taken (store or engine down): answered `500`, the provider retries.
80
+ */
81
+ status: 'accepted' | 'duplicate' | 'ignored' | 'unauthorized' | 'challenge' | 'method_not_allowed' | 'failed';
82
+ /** Why it was ignored (the adapter's reason — never message content), or what failed. */
83
+ reason?: string;
84
+ /** The provider's event name, when the body has one. */
85
+ event?: string;
86
+ /** New messages taken. */
87
+ accepted: number;
88
+ /** Messages already taken before (provider retries). */
89
+ duplicates: number;
90
+ /** The new messages, for counting — handled on their own, do not answer them here. */
91
+ messages: readonly InboundMessage[];
92
+ }
93
+ /** A turn has started — {@link ChannelHandleOptions.onTurnStarted}. */
94
+ export interface ChannelTurnStarted {
95
+ runId: string;
96
+ threadId: string;
97
+ actor: Actor;
98
+ message: InboundMessage;
99
+ /** The message waits in the thread's queue (its run starts later under `runId`). */
100
+ queued: boolean;
101
+ }
102
+ /** What {@link ChannelHandleOptions.prepareMedia} makes of a downloaded file. */
103
+ export type ChannelPreparedMedia = undefined
104
+ /** Attach this file instead (converted, resized…). */
105
+ | {
106
+ file: ChannelMediaFile;
107
+ }
108
+ /** Read the file as this text (a voice note's transcript): added to the message, not attached. */
109
+ | {
110
+ text: string;
111
+ }
112
+ /** Refuse it with `texts.mediaRefused(reason)`. */
113
+ | {
114
+ refuse: ChannelMediaRefusal;
80
115
  };
116
+ /** The message as it goes to the agent — what {@link ChannelHandleOptions.transformInbound} edits. */
117
+ export interface ChannelInbound {
118
+ /** The text (with prepared media's text appended). */
119
+ text: string;
120
+ attachments: AttachmentRef[];
121
+ }
81
122
  export interface ChannelHandleOptions {
82
123
  /**
83
124
  * The account the sender is — from `message.from` (a phone number, a Telegram id). `null` → the
84
- * message is not answered (or answered with `texts.unknownSender`). This IS the authentication of
85
- * every message, so map only senders the channel itself vouches for.
125
+ * message is not answered by the agent ({@link unknownSender} / `texts.unknownSender`). This IS
126
+ * the authentication of every message, so map only senders the channel itself vouches for.
86
127
  */
87
128
  actor(message: InboundMessage): Actor | null | Promise<Actor | null>;
129
+ /**
130
+ * A sender `actor()` mapped to nobody: what to answer (an onboarding step, a "link your number"
131
+ * link) — `null`/`undefined` → nothing. Default: `texts.unknownSender`.
132
+ */
133
+ unknownSender?(message: InboundMessage, context: ChannelHookContext): ChannelReply | ChannelReply[] | null | undefined | Promise<ChannelReply | ChannelReply[] | null | undefined>;
134
+ /**
135
+ * Before anything else for a known sender — before its answers, button presses, text decisions
136
+ * and turns: `'continue'` (or nothing) goes on; `'stop'` ends here; `{ reply }` / `{ replies }`
137
+ * answers and ends here. For flows the app owns: terms to accept, an account to finish, a quota.
138
+ */
139
+ beforeTurn?(message: InboundMessage, actor: Actor, context: ChannelHookContext): ChannelGate | Promise<ChannelGate>;
88
140
  /**
89
141
  * The thread this conversation continues; `null`/`undefined` → a new one, reported to
90
142
  * {@link onThreadCreated} so you can store it.
@@ -92,6 +144,13 @@ export interface ChannelHandleOptions {
92
144
  thread(actor: Actor, message: InboundMessage): string | null | undefined | Promise<string | null | undefined>;
93
145
  /** A new thread was created for the conversation — remember it for {@link thread}. */
94
146
  onThreadCreated?(threadId: string, actor: Actor, message: InboundMessage): void | Promise<void>;
147
+ /** A turn started (or was queued) for a message — record where it came from, start a meter. */
148
+ onTurnStarted?(turn: ChannelTurnStarted): void | Promise<void>;
149
+ /**
150
+ * Checked before EVERY message the channel sends — replies, cards, questions, relayed outcomes.
151
+ * `false` → that message is dropped (e.g. the number was unlinked from the account mid-turn).
152
+ */
153
+ canDeliver?(delivery: ChannelDelivery): boolean | Promise<boolean>;
95
154
  /**
96
155
  * The turn's page context. Default `{ kind: adapter.name }`. The handler adds `channel: { name,
97
156
  * conversation }` to it — what a proposal's outcome is routed back by.
@@ -102,36 +161,112 @@ export interface ChannelHandleOptions {
102
161
  /** The agent service. Default: `AgentService` from the container. */
103
162
  service?: ChannelTurnService;
104
163
  /**
105
- * Where the channel's short-lived state lives: message ids already taken, questions waiting for an
106
- * answer, outcomes already relayed. Default: `lucidChannelStore()` over the agent store's database
107
- * when the agent store is Lucid, else this process's memory.
164
+ * Where the channel's short-lived state lives: message ids already taken, what was delivered,
165
+ * questions waiting for an answer, cards sent, outcomes relayed. Default: `lucidChannelStore()`
166
+ * over the agent store's database when the agent store is Lucid, else this process's memory.
108
167
  */
109
168
  store?: ChannelStore;
110
- /** How long a message id is remembered. Default 24 h. */
169
+ /**
170
+ * Process messages as `@adonis-agora/durable` runs: persisted before the `200`, one at a time per
171
+ * conversation, retried, and resumed after a crash (a reply never lost, never sent twice). Default:
172
+ * on when the agent runs durably (`durable: true` in `config/agent.ts`), on that engine. `false` →
173
+ * in this process (a restart loses what is in flight). An engine → that one.
174
+ */
175
+ durable?: boolean | ChannelWorkflowEngine;
176
+ /** How each phase of a message is retried when it fails. */
177
+ retry?: ChannelRetryOptions;
178
+ /** How long a message id (and what was delivered for it) is remembered. Default 24 h. */
111
179
  dedupeTtlMs?: number;
112
180
  /** Stop waiting for a turn after this long (and cancel it). Default 5 minutes. */
113
181
  timeoutMs?: number;
114
182
  /**
115
183
  * After a proposal is approved, wait this long for it to execute and relay its outcome. `0` → do
116
- * not wait (the decision reply is all the person gets; `channels.onSettled` can still relay it).
117
- * Default 60 s.
184
+ * not wait (`channels.onSettled` relays it once it runs). Default 60 s.
118
185
  */
119
186
  outcomeTimeoutMs?: number;
120
187
  /** How long a question waits for its answer before the agent proceeds without it. Default 30 min. */
121
188
  questionTimeoutMs?: number;
122
189
  /**
123
190
  * What the channel says on its own. Omitted parts come from {@link channelTextsFor}: Brazilian
124
- * Portuguese when the agent's `actionProposalText` is `ptBrActionProposalText`, else English.
191
+ * Portuguese when the agent's `actionProposalText` is `ptBrActionProposalText`, else English. A
192
+ * function picks them per message (the actor's locale) — `actor` is `null` before it is known and
193
+ * for a relayed outcome (then `proposal` is set).
194
+ */
195
+ texts?: ChannelTextsOverrides | ((context: {
196
+ actor: Actor | null;
197
+ message: InboundMessage | null;
198
+ proposal?: ActionProposal;
199
+ }) => ChannelTextsOverrides | Promise<ChannelTextsOverrides>);
200
+ /**
201
+ * Accept "always in this conversation" in a text decision. Default `true`; `false` → it is refused
202
+ * with `texts.rememberRefused` (every action needs its own confirmation here).
203
+ */
204
+ allowRemember?: boolean;
205
+ /**
206
+ * What the turn may draw. Default `{ components: [] }`: every component arrives as its
207
+ * `fallbackText`. Allow some with {@link renderComponent} to send them as files.
125
208
  */
126
- texts?: ChannelTextsOverrides;
127
- /** A message whose handling failed. Default: `console.error`. */
209
+ uiCapabilities?: UiCapabilities;
210
+ /**
211
+ * A component the turn drew: what to send for it — a file (a chart as an image), text, several —
212
+ * or `null`/`undefined` for its `fallbackText`. Rendered components are sent when the turn ends (or
213
+ * asks a question), before its text; a later one with the same id replaces it; a failed turn sends
214
+ * none.
215
+ */
216
+ renderComponent?(component: ChannelComponent, context: {
217
+ actor: Actor;
218
+ conversation: string;
219
+ runId: string;
220
+ rendered: number;
221
+ }): ChannelReply | ChannelReply[] | null | undefined | Promise<ChannelReply | ChannelReply[] | null | undefined>;
222
+ /**
223
+ * The attachment limits for one file — e.g. let audio through to {@link prepareMedia}, which
224
+ * transcribes it. Default: the agent's.
225
+ */
226
+ mediaLimits?(limits: AttachmentLimits | null, media: InboundMedia): AttachmentLimits | null;
227
+ /**
228
+ * A downloaded file, before it is attached: attach another (`{ file }`), read it as text (`{ text }`
229
+ * — a voice note's transcript), refuse it, or (nothing) attach it as is.
230
+ */
231
+ prepareMedia?(file: ChannelMediaFile, media: InboundMedia, context: ChannelHookContext & {
232
+ actor: Actor;
233
+ }): ChannelPreparedMedia | Promise<ChannelPreparedMedia>;
234
+ /**
235
+ * The message as it goes to the agent, last: add a note about the attachments, a default question
236
+ * for an image without a caption… Text decisions are read from the result.
237
+ */
238
+ transformInbound?(inbound: ChannelInbound, context: ChannelHookContext & {
239
+ actor: Actor;
240
+ threadId: string | null;
241
+ }): ChannelInbound | Promise<ChannelInbound>;
242
+ /**
243
+ * What an executed proposal tells the person, in order — the outcome, then follow-ups (a message
244
+ * to forward, sent `raw` and alone). Relayed once. `null`/`undefined` → the default (`text`: the
245
+ * proposal's own outcome text, else `texts.actionSucceeded` / `texts.actionFailed`); `[]` → nothing.
246
+ */
247
+ formatOutcome?(proposal: ActionProposal, context: {
248
+ text: string;
249
+ texts: ChannelTexts;
250
+ }): ChannelReply[] | null | undefined | Promise<ChannelReply[] | null | undefined>;
251
+ /** What every webhook request came to — for counters and logs, without parsing the body again. */
252
+ onWebhook?(event: ChannelWebhookEvent): void | Promise<void>;
253
+ /** A message whose handling failed (after its retries). Default: `console.error`. */
128
254
  onError?(error: unknown, message: InboundMessage): void;
129
255
  }
130
256
  /** The route handler `channels.handle()` returns. */
131
257
  export interface ChannelRouteHandler {
132
258
  (ctx: HttpContext): Promise<void>;
133
- /** Resolves once every turn this handler started has been answered — for tests and shutdown. */
259
+ /**
260
+ * Resolves once every message this handler took has been handled — for tests and shutdown. With
261
+ * a durable engine: once their runs ended.
262
+ */
134
263
  drain(): Promise<void>;
264
+ /** Handle a request built by hand (another framework, a test). */
265
+ handleRequest(request: ChannelRequest): Promise<{
266
+ status: number;
267
+ body: unknown;
268
+ contentType?: string;
269
+ }>;
135
270
  }
136
271
  /** The button ids for a proposal: what {@link ChannelRouteHandler} maps back to its decision. */
137
272
  export declare function proposalButtonIds(proposalId: string): {
@@ -145,31 +280,35 @@ export interface ChannelAddress {
145
280
  }
146
281
  /**
147
282
  * The webhook route for one channel. Each request is verified (`401` when it is not the provider's),
148
- * parsed, deduplicated by the provider's message id, and acknowledged with `200` at once; the turn
149
- * runs after the response, so a slow model never makes the provider retry. Then:
283
+ * parsed, deduplicated by the provider's message id, taken (persisted, with a durable engine) and
284
+ * acknowledged with `200`; the message is handled after the response — one at a time per
285
+ * conversation, each phase retried — so a slow model never makes the provider retry. Then:
150
286
  *
151
- * - media are downloaded and attached (held to the attachment store's limits), or refused with a text;
152
- * - the message is sent with text-only capabilities (components arrive as their `fallbackText`);
153
- * a text decision ("yes", "confirm #ID") is answered with its reply instead of starting a turn;
287
+ * - an unknown sender gets `unknownSender`; a known one goes through `beforeTurn`;
288
+ * - an answer to a question the turn asked resumes it;
154
289
  * - a press on a proposal's button decides that proposal (`via` = the adapter's name);
155
- * - a question the turn asks is sent as text, one at a time, and the next messages answer it;
156
- * - the reply is converted to the channel's markdown, split at its length limit, and sent;
157
- * - a proposal the turn left pending is sent with Confirm/Cancel buttons — or, on a channel without
158
- * them, with a text instruction in the configured `actionProposalText` vocabulary;
290
+ * - a text decision ("yes", "no #ID", a button label) decides a card delivered to THIS conversation
291
+ * — never a proposal made elsewhere (`texts.noPendingConfirmation`);
292
+ * - media are downloaded (`prepareMedia`) and attached, or refused with a text;
293
+ * - the message (`transformInbound`) starts a turn with the channel's capabilities;
294
+ * - the reply is converted to the channel's markdown, split at its length limit, and sent — each
295
+ * message once, even when the work is retried or resumed after a crash;
296
+ * - a proposal the turn left pending is sent with Confirm/Cancel buttons (or a text instruction);
159
297
  * - an approved proposal's outcome is relayed once it executed (see `outcomeTimeoutMs`, and
160
298
  * `channels.onSettled` for one that runs later).
161
299
  *
162
300
  * Wants `actionApprovalMode: 'independent'`: a blocking approval holds the turn open until someone
163
301
  * decides it in the app, so the channel sends what it has and `texts.blockingApproval`.
164
302
  *
165
- * Registers the adapter under its `name` for `channels.onSettled` — names must be unique.
303
+ * Registers the adapter under its `name` for `channels.onSettled` and the durable jobs — names must
304
+ * be unique, and a process that resumes durable channel jobs must create the same handlers at boot.
166
305
  */
167
306
  export declare function handleChannel(adapter: ChannelAdapter, options: ChannelHandleOptions): ChannelRouteHandler;
168
307
  /**
169
308
  * `actionProposalWorker.onSettled` for text channels: relays an executed proposal's outcome to the
170
- * conversation it was proposed in, through the adapter registered under the recorded channel name.
171
- * Proposals from other surfaces are ignored. Safe next to the handler's own wait: an outcome is
172
- * relayed once.
309
+ * conversation it was proposed in, through the adapter registered under the recorded channel name
310
+ * (with its `formatOutcome`, `texts` and `canDeliver`). Proposals from other surfaces are ignored.
311
+ * Safe next to the handler's own wait: an outcome is relayed once.
173
312
  *
174
313
  * ```ts
175
314
  * // config/agent.ts
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/channels/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/channels/handler.ts"],"names":[],"mappings":"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"}