@adonis-agora/agent 0.62.0 → 0.63.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 (141) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/providers/agent_provider.d.ts.map +1 -1
  3. package/dist/providers/agent_provider.js +1 -12
  4. package/dist/providers/agent_provider.js.map +1 -1
  5. package/dist/src/action-proposal-service.d.ts +3 -2
  6. package/dist/src/action-proposal-service.d.ts.map +1 -1
  7. package/dist/src/action-proposal-service.js +1 -0
  8. package/dist/src/action-proposal-service.js.map +1 -1
  9. package/dist/src/actor-resolver.d.ts +12 -4
  10. package/dist/src/actor-resolver.d.ts.map +1 -1
  11. package/dist/src/actor-resolver.js +24 -7
  12. package/dist/src/actor-resolver.js.map +1 -1
  13. package/dist/src/ag-ui/adapter.d.ts.map +1 -1
  14. package/dist/src/ag-ui/adapter.js +32 -6
  15. package/dist/src/ag-ui/adapter.js.map +1 -1
  16. package/dist/src/ag-ui/core/encoder.d.ts +2 -1
  17. package/dist/src/ag-ui/core/encoder.d.ts.map +1 -1
  18. package/dist/src/ag-ui/core/encoder.js +16 -5
  19. package/dist/src/ag-ui/core/encoder.js.map +1 -1
  20. package/dist/src/ag-ui/core/index.d.ts +2 -2
  21. package/dist/src/ag-ui/core/index.d.ts.map +1 -1
  22. package/dist/src/ag-ui/core/index.js +2 -2
  23. package/dist/src/ag-ui/core/index.js.map +1 -1
  24. package/dist/src/ag-ui/core/input.d.ts +21 -3
  25. package/dist/src/ag-ui/core/input.d.ts.map +1 -1
  26. package/dist/src/ag-ui/core/input.js +24 -6
  27. package/dist/src/ag-ui/core/input.js.map +1 -1
  28. package/dist/src/ag-ui/core/stream.d.ts +24 -2
  29. package/dist/src/ag-ui/core/stream.d.ts.map +1 -1
  30. package/dist/src/ag-ui/core/stream.js +25 -3
  31. package/dist/src/ag-ui/core/stream.js.map +1 -1
  32. package/dist/src/ag-ui/core/types.d.ts +2 -2
  33. package/dist/src/ag-ui/core/types.d.ts.map +1 -1
  34. package/dist/src/ag-ui/core/types.js +2 -2
  35. package/dist/src/ag-ui/core/types.js.map +1 -1
  36. package/dist/src/ag-ui/frames.d.ts +5 -1
  37. package/dist/src/ag-ui/frames.d.ts.map +1 -1
  38. package/dist/src/ag-ui/frames.js +13 -3
  39. package/dist/src/ag-ui/frames.js.map +1 -1
  40. package/dist/src/ag-ui/index.d.ts +1 -1
  41. package/dist/src/ag-ui/index.d.ts.map +1 -1
  42. package/dist/src/ag-ui/index.js +1 -1
  43. package/dist/src/ag-ui/index.js.map +1 -1
  44. package/dist/src/agent-service.d.ts +36 -3
  45. package/dist/src/agent-service.d.ts.map +1 -1
  46. package/dist/src/agent-service.js +65 -1
  47. package/dist/src/agent-service.js.map +1 -1
  48. package/dist/src/attachment-limits.d.ts +10 -0
  49. package/dist/src/attachment-limits.d.ts.map +1 -0
  50. package/dist/src/attachment-limits.js +13 -0
  51. package/dist/src/attachment-limits.js.map +1 -0
  52. package/dist/src/channels/adapters/evolution_api.d.ts +49 -0
  53. package/dist/src/channels/adapters/evolution_api.d.ts.map +1 -0
  54. package/dist/src/channels/adapters/evolution_api.js +241 -0
  55. package/dist/src/channels/adapters/evolution_api.js.map +1 -0
  56. package/dist/src/channels/adapters/telegram.d.ts +34 -0
  57. package/dist/src/channels/adapters/telegram.d.ts.map +1 -0
  58. package/dist/src/channels/adapters/telegram.js +196 -0
  59. package/dist/src/channels/adapters/telegram.js.map +1 -0
  60. package/dist/src/channels/adapters/whatsapp_cloud.d.ts +31 -0
  61. package/dist/src/channels/adapters/whatsapp_cloud.d.ts.map +1 -0
  62. package/dist/src/channels/adapters/whatsapp_cloud.js +177 -0
  63. package/dist/src/channels/adapters/whatsapp_cloud.js.map +1 -0
  64. package/dist/src/channels/handler.d.ts +167 -0
  65. package/dist/src/channels/handler.d.ts.map +1 -0
  66. package/dist/src/channels/handler.js +569 -0
  67. package/dist/src/channels/handler.js.map +1 -0
  68. package/dist/src/channels/http.d.ts +45 -0
  69. package/dist/src/channels/http.d.ts.map +1 -0
  70. package/dist/src/channels/http.js +147 -0
  71. package/dist/src/channels/http.js.map +1 -0
  72. package/dist/src/channels/index.d.ts +16 -0
  73. package/dist/src/channels/index.d.ts.map +1 -0
  74. package/dist/src/channels/index.js +15 -0
  75. package/dist/src/channels/index.js.map +1 -0
  76. package/dist/src/channels/markdown.d.ts +12 -0
  77. package/dist/src/channels/markdown.d.ts.map +1 -0
  78. package/dist/src/channels/markdown.js +120 -0
  79. package/dist/src/channels/markdown.js.map +1 -0
  80. package/dist/src/channels/questions.d.ts +43 -0
  81. package/dist/src/channels/questions.d.ts.map +1 -0
  82. package/dist/src/channels/questions.js +90 -0
  83. package/dist/src/channels/questions.js.map +1 -0
  84. package/dist/src/channels/split.d.ts +8 -0
  85. package/dist/src/channels/split.d.ts.map +1 -0
  86. package/dist/src/channels/split.js +45 -0
  87. package/dist/src/channels/split.js.map +1 -0
  88. package/dist/src/channels/store.d.ts +78 -0
  89. package/dist/src/channels/store.d.ts.map +1 -0
  90. package/dist/src/channels/store.js +151 -0
  91. package/dist/src/channels/store.js.map +1 -0
  92. package/dist/src/channels/types.d.ts +138 -0
  93. package/dist/src/channels/types.d.ts.map +1 -0
  94. package/dist/src/channels/types.js +7 -0
  95. package/dist/src/channels/types.js.map +1 -0
  96. package/dist/src/genui/builtins.d.ts.map +1 -1
  97. package/dist/src/genui/builtins.js +65 -6
  98. package/dist/src/genui/builtins.js.map +1 -1
  99. package/dist/src/genui/catalog.d.ts +11 -2
  100. package/dist/src/genui/catalog.d.ts.map +1 -1
  101. package/dist/src/genui/catalog.js +8 -0
  102. package/dist/src/genui/catalog.js.map +1 -1
  103. package/dist/src/genui/text.d.ts +4 -3
  104. package/dist/src/genui/text.d.ts.map +1 -1
  105. package/dist/src/genui/text.js +25 -24
  106. package/dist/src/genui/text.js.map +1 -1
  107. package/dist/src/genui/tools.d.ts +2 -1
  108. package/dist/src/genui/tools.d.ts.map +1 -1
  109. package/dist/src/genui/tools.js +6 -7
  110. package/dist/src/genui/tools.js.map +1 -1
  111. package/dist/src/index.d.ts +3 -2
  112. package/dist/src/index.d.ts.map +1 -1
  113. package/dist/src/index.js +3 -2
  114. package/dist/src/index.js.map +1 -1
  115. package/dist/src/opencode/turns.d.ts +4 -2
  116. package/dist/src/opencode/turns.d.ts.map +1 -1
  117. package/dist/src/opencode/turns.js.map +1 -1
  118. package/dist/src/react/core/ag-ui-backend.d.ts +38 -14
  119. package/dist/src/react/core/ag-ui-backend.d.ts.map +1 -1
  120. package/dist/src/react/core/ag-ui-backend.js +182 -17
  121. package/dist/src/react/core/ag-ui-backend.js.map +1 -1
  122. package/dist/src/react/core/agent-chat-transport.d.ts.map +1 -1
  123. package/dist/src/react/core/agent-chat-transport.js +22 -1
  124. package/dist/src/react/core/agent-chat-transport.js.map +1 -1
  125. package/dist/src/react/core/backend.d.ts +11 -0
  126. package/dist/src/react/core/backend.d.ts.map +1 -1
  127. package/dist/src/react/core/backend.js.map +1 -1
  128. package/dist/src/react/core/index.d.ts +1 -1
  129. package/dist/src/react/core/index.d.ts.map +1 -1
  130. package/dist/src/react/core/index.js.map +1 -1
  131. package/dist/src/stores/lucid-schema.d.ts +24 -6
  132. package/dist/src/stores/lucid-schema.d.ts.map +1 -1
  133. package/dist/src/stores/lucid-schema.js +47 -6
  134. package/dist/src/stores/lucid-schema.js.map +1 -1
  135. package/dist/src/stores/lucid.d.ts +2 -0
  136. package/dist/src/stores/lucid.d.ts.map +1 -1
  137. package/dist/src/stores/lucid.js +4 -0
  138. package/dist/src/stores/lucid.js.map +1 -1
  139. package/package.json +6 -1
  140. package/skills/agent-setup/SKILL.md +39 -3
  141. package/skills/agent-tools/SKILL.md +3 -0
@@ -0,0 +1,569 @@
1
+ import { DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY } from '../action-proposal-text.js';
2
+ import { AgentService, AttachmentRefusedError } from '../agent-service.js';
3
+ import { ChannelMediaTooLargeError } from './http.js';
4
+ import { toChannelMarkdown } from './markdown.js';
5
+ import { DEFAULT_CHANNEL_QUESTION_TEXTS, formatChannelQuestion, parseChannelAnswer, } from './questions.js';
6
+ import { splitMessage } from './split.js';
7
+ import { InMemoryChannelStore, lucidChannelStore } from './store.js';
8
+ /** `20 MB`, `512 KB`. */
9
+ const readableSize = (bytes) => bytes >= 1024 * 1024
10
+ ? `${Math.round(bytes / (1024 * 1024))} MB`
11
+ : `${Math.max(1, Math.ceil(bytes / 1024))} KB`;
12
+ export const DEFAULT_CHANNEL_TEXTS = {
13
+ approve: 'Confirm',
14
+ reject: 'Cancel',
15
+ proposal: ({ confirmation, toolName }) => confirmation
16
+ ? `*${confirmation.title}*${confirmation.detail ? `\n${confirmation.detail}` : ''}`
17
+ : `*Run ${toolName}?*`,
18
+ instruction: ({ approve, reject }) => `Reply *${approve}* to confirm or *${reject}* to cancel.`,
19
+ blockingApproval: 'This action needs an approval that can only be given in the app.',
20
+ failed: 'Sorry, something went wrong. Please try again.',
21
+ actionSucceeded: 'Done.',
22
+ actionFailed: 'The action could not be completed.',
23
+ mediaRefused: (reason, media, limits) => reason === 'disabled'
24
+ ? 'I can only read text messages here.'
25
+ : reason === 'size'
26
+ ? `That file is too large${limits ? ` (the limit is ${readableSize(limits.maxBytes)})` : ''}.`
27
+ : reason === 'failed'
28
+ ? 'I could not download that file. Please send it again.'
29
+ : media.kind === 'audio'
30
+ ? 'I cannot listen to audio messages. Please type your message.'
31
+ : `I cannot read this kind of file${media.contentType ? ` (${media.contentType})` : ''}.`,
32
+ questions: DEFAULT_CHANNEL_QUESTION_TEXTS,
33
+ };
34
+ const BUTTON_ID = /^agora:(approve|reject):([^\s]+)$/;
35
+ /** The tail of a proposal id a button carries — Telegram's `callback_data` holds 64 bytes. */
36
+ const BUTTON_REF_LENGTH = 32;
37
+ const OUTCOME_POLL_MS = 500;
38
+ /** How long "this outcome was relayed" is remembered. */
39
+ const OUTCOME_TTL_MS = 7 * 24 * 60 * 60 * 1000;
40
+ const buttonRef = (proposalId) => proposalId.slice(-BUTTON_REF_LENGTH);
41
+ /** The button ids for a proposal: what {@link ChannelRouteHandler} maps back to its decision. */
42
+ export function proposalButtonIds(proposalId) {
43
+ const ref = buttonRef(proposalId);
44
+ return { approve: `agora:approve:${ref}`, reject: `agora:reject:${ref}` };
45
+ }
46
+ function requestOf(ctx) {
47
+ return {
48
+ method: ctx.request.method().toUpperCase(),
49
+ url: ctx.request.url(true),
50
+ header: (name) => ctx.request.header(name),
51
+ params: (ctx.params ?? {}),
52
+ body: ctx.request.body(),
53
+ rawBody: ctx.request.raw(),
54
+ };
55
+ }
56
+ /** `AgentService` from the app's container, for code that runs outside a request. */
57
+ async function containerService() {
58
+ const { default: app } = await import('@adonisjs/core/services/app');
59
+ return (await app.container.make(AgentService));
60
+ }
61
+ const registry = new Map();
62
+ const mergeTexts = (overrides = {}) => ({
63
+ ...DEFAULT_CHANNEL_TEXTS,
64
+ ...overrides,
65
+ questions: { ...DEFAULT_CHANNEL_QUESTION_TEXTS, ...overrides.questions },
66
+ });
67
+ /** Send `text` converted to the channel's markdown, split at its length limit. */
68
+ async function deliverText(adapter, conversation, text) {
69
+ const { markdown, maxLength } = adapter.capabilities;
70
+ for (const piece of splitMessage(toChannelMarkdown(text, markdown), maxLength))
71
+ await adapter.send(conversation, { text: piece });
72
+ }
73
+ /** What an executed proposal tells the person; `null` when it did not execute. */
74
+ function outcomeText(proposal, texts) {
75
+ const status = proposal.execution?.status;
76
+ if (status === 'failed')
77
+ return texts.actionFailed;
78
+ if (status !== 'succeeded')
79
+ return null;
80
+ // What its presentation said (`present` / `emitUi` text), else a plain confirmation.
81
+ return proposal.outcome?.text?.trim() || texts.actionSucceeded;
82
+ }
83
+ /**
84
+ * Relay an executed proposal's outcome to the conversation it was proposed in — once: the handler's
85
+ * own wait and this share a claim in the channel's store. `false` when it was not relayed (no
86
+ * channel recorded, the channel is not registered in this process, not executed, already relayed).
87
+ */
88
+ async function deliverOutcome(proposal, service) {
89
+ const address = record(proposal.executionContext?.pageContext?.channel);
90
+ const name = typeof address?.name === 'string' ? address.name : undefined;
91
+ const conversation = typeof address?.conversation === 'string' ? address.conversation : undefined;
92
+ const registration = name === undefined ? undefined : registry.get(name);
93
+ if (!registration || conversation === undefined)
94
+ return false;
95
+ return relayOnce(await registration.store(service), registration.adapter, registration.texts, conversation, proposal);
96
+ }
97
+ /** Send an executed proposal's outcome unless it was sent already (by this or another replica). */
98
+ async function relayOnce(store, adapter, texts, conversation, proposal) {
99
+ const text = outcomeText(proposal, texts);
100
+ if (text === null)
101
+ return false;
102
+ if (!(await store.claim(`${adapter.name}:outcome:${proposal.id}`, OUTCOME_TTL_MS)))
103
+ return false;
104
+ await deliverText(adapter, conversation, text);
105
+ return true;
106
+ }
107
+ function record(value) {
108
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
109
+ ? value
110
+ : undefined;
111
+ }
112
+ /** `image/jpeg` → `jpeg`, for a file that arrives without a name. */
113
+ const extensionOf = (contentType) => (contentType.split('/')[1] ?? 'bin').split(/[;+]/)[0] ?? 'bin';
114
+ /**
115
+ * The webhook route for one channel. Each request is verified (`401` when it is not the provider's),
116
+ * parsed, deduplicated by the provider's message id, and acknowledged with `200` at once; the turn
117
+ * runs after the response, so a slow model never makes the provider retry. Then:
118
+ *
119
+ * - media are downloaded and attached (held to the attachment store's limits), or refused with a text;
120
+ * - the message is sent with text-only capabilities (components arrive as their `fallbackText`);
121
+ * a text decision ("yes", "confirm #ID") is answered with its reply instead of starting a turn;
122
+ * - a press on a proposal's button decides that proposal (`via` = the adapter's name);
123
+ * - a question the turn asks is sent as text, one at a time, and the next messages answer it;
124
+ * - the reply is converted to the channel's markdown, split at its length limit, and sent;
125
+ * - a proposal the turn left pending is sent with Confirm/Cancel buttons — or, on a channel without
126
+ * them, with a text instruction in the configured `actionProposalText` vocabulary;
127
+ * - an approved proposal's outcome is relayed once it executed (see `outcomeTimeoutMs`, and
128
+ * `channels.onSettled` for one that runs later).
129
+ *
130
+ * Wants `actionApprovalMode: 'independent'`: a blocking approval holds the turn open until someone
131
+ * decides it in the app, so the channel sends what it has and `texts.blockingApproval`.
132
+ *
133
+ * Registers the adapter under its `name` for `channels.onSettled` — names must be unique.
134
+ */
135
+ export function handleChannel(adapter, options) {
136
+ const texts = mergeTexts(options.texts);
137
+ const dedupeTtlMs = options.dedupeTtlMs ?? 24 * 60 * 60 * 1000;
138
+ const timeoutMs = options.timeoutMs ?? 5 * 60 * 1000;
139
+ const outcomeTimeoutMs = options.outcomeTimeoutMs ?? 60_000;
140
+ const questionTimeoutMs = options.questionTimeoutMs ?? 30 * 60 * 1000;
141
+ const { capabilities } = adapter;
142
+ const buttons = (capabilities.buttons ?? 0) >= 2;
143
+ const inFlight = new Set();
144
+ let resolvedStore;
145
+ /** The configured store, else Lucid over the agent store's database, else memory — chosen once. */
146
+ const storeFor = (service) => {
147
+ resolvedStore ??= (async () => {
148
+ if (options.store)
149
+ return options.store;
150
+ const agent = options.service ?? service ?? (await containerService().catch(() => undefined));
151
+ const db = agent?.lucidDatabase?.() ?? null;
152
+ return db === null ? new InMemoryChannelStore() : lucidChannelStore(db);
153
+ })();
154
+ return resolvedStore;
155
+ };
156
+ registry.set(adapter.name, { adapter, texts, store: storeFor });
157
+ const deliver = (conversation, text) => deliverText(adapter, conversation, text);
158
+ const questionKey = (conversation) => `${adapter.name}:question:${conversation}`;
159
+ const commandsFor = (service, proposalId, withId) => {
160
+ const vocabulary = service.actionProposalVocabulary?.() ?? DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY;
161
+ const suffix = withId ? ` #${proposalId}` : '';
162
+ return {
163
+ approve: `${vocabulary.approve[0] ?? 'yes'}${suffix}`,
164
+ reject: `${vocabulary.reject[0] ?? 'no'}${suffix}`,
165
+ };
166
+ };
167
+ const sendProposal = async (service, conversation, proposal, withId) => {
168
+ const summary = texts.proposal(proposal);
169
+ const instruction = texts.instruction(commandsFor(service, proposal.id, withId));
170
+ const asText = toChannelMarkdown(`${summary}\n\n${instruction}`, capabilities.markdown);
171
+ if (!buttons) {
172
+ for (const piece of splitMessage(asText, capabilities.maxLength))
173
+ await adapter.send(conversation, { text: piece });
174
+ return;
175
+ }
176
+ const ids = proposalButtonIds(proposal.id);
177
+ const message = {
178
+ text: toChannelMarkdown(summary, capabilities.markdown).slice(0, capabilities.maxLength),
179
+ buttons: [
180
+ { id: ids.approve, label: texts.approve },
181
+ { id: ids.reject, label: texts.reject },
182
+ ],
183
+ fallbackText: asText.slice(0, capabilities.maxLength),
184
+ };
185
+ await adapter.send(conversation, message);
186
+ };
187
+ /** Wait for an approved proposal to run, then relay what it said (or that it failed). */
188
+ const relayOutcome = async (service, actor, threadId, proposalId, conversation) => {
189
+ if (outcomeTimeoutMs <= 0 || !service.listActionProposals)
190
+ return;
191
+ const deadline = Date.now() + outcomeTimeoutMs;
192
+ while (Date.now() < deadline) {
193
+ const current = (await service.listActionProposals(actor, threadId)).find((proposal) => proposal.id === proposalId);
194
+ if (current?.decision !== 'approved')
195
+ return;
196
+ if (outcomeText(current, texts) !== null) {
197
+ await relayOnce(await storeFor(service), adapter, texts, conversation, current);
198
+ return;
199
+ }
200
+ await new Promise((resolve) => setTimeout(resolve, OUTCOME_POLL_MS));
201
+ }
202
+ };
203
+ /** A press on one of our proposal buttons: decide it. `false` → not one of ours. */
204
+ const pressButton = async (service, actor, threadId, message) => {
205
+ const match = message.buttonId === undefined ? null : BUTTON_ID.exec(message.buttonId);
206
+ if (!match || !service.decideActionProposal || !service.listActionProposals)
207
+ return false;
208
+ const decision = match[1] === 'approve' ? 'approved' : 'rejected';
209
+ const ref = match[2] ?? '';
210
+ const proposal = threadId === null
211
+ ? undefined
212
+ : (await service.listActionProposals(actor, threadId)).find((candidate) => buttonRef(candidate.id) === ref);
213
+ if (threadId === null || !proposal) {
214
+ await deliver(message.conversation, service.actionProposalReply({ status: 'not_found' }, decision));
215
+ return true;
216
+ }
217
+ const result = await service.decideActionProposal(actor, threadId, proposal.id, decision, {}, adapter.name);
218
+ await deliver(message.conversation, service.actionProposalReply(result, decision));
219
+ if (result.status === 'applied' && decision === 'approved')
220
+ await relayOutcome(service, actor, threadId, proposal.id, message.conversation);
221
+ return true;
222
+ };
223
+ const askNext = (conversation, pending) => {
224
+ const question = pending.questions[pending.index];
225
+ if (!question)
226
+ return Promise.resolve();
227
+ return deliver(conversation, formatChannelQuestion(question, {
228
+ index: pending.index,
229
+ total: pending.questions.length,
230
+ ...(pending.preamble !== undefined ? { preamble: pending.preamble } : {}),
231
+ }, texts.questions));
232
+ };
233
+ /** The person's message answers the question in front of them; the last one resumes the run. */
234
+ const answerQuestion = async (service, store, actor, message, pending) => {
235
+ const question = pending.questions[pending.index];
236
+ if (!question || !service.answer)
237
+ return;
238
+ const parsed = parseChannelAnswer(question, message.text, texts.questions.skipWord);
239
+ if (parsed.status === 'invalid') {
240
+ await deliver(message.conversation, texts.questions.invalid(parsed.problem));
241
+ await askNext(message.conversation, pending);
242
+ return;
243
+ }
244
+ const next = {
245
+ ...pending,
246
+ index: pending.index + 1,
247
+ answers: parsed.status === 'answer'
248
+ ? { ...pending.answers, [question.id]: parsed.values }
249
+ : pending.answers,
250
+ };
251
+ const key = questionKey(message.conversation);
252
+ if (next.index < next.questions.length) {
253
+ await store.set(key, JSON.stringify(next), questionTimeoutMs);
254
+ await askNext(message.conversation, next);
255
+ return;
256
+ }
257
+ await store.delete(key);
258
+ // The turn that asked is still being read: what the agent says next reaches the person there.
259
+ await service.answer({
260
+ runId: next.runId,
261
+ toolCallId: next.toolCallId,
262
+ answers: next.answers,
263
+ answeredByRef: actor.id,
264
+ answeredVia: adapter.name,
265
+ });
266
+ };
267
+ /** Download a message's files and stage them for the turn; refuse what cannot be attached. */
268
+ const attachMedia = async (service, actor, message) => {
269
+ const refs = [];
270
+ const limits = service.attachmentLimits?.() ?? null;
271
+ for (const media of message.media ?? []) {
272
+ const refuse = (reason) => deliver(message.conversation, texts.mediaRefused(reason, media, limits));
273
+ if (limits === null || !adapter.download || !service.stageAttachment) {
274
+ await refuse('disabled');
275
+ continue;
276
+ }
277
+ const declared = media.contentType?.split(';')[0]?.trim().toLowerCase();
278
+ if (declared !== undefined && !limits.allowedContentTypes.includes(declared)) {
279
+ await refuse('type');
280
+ continue;
281
+ }
282
+ if (media.sizeBytes !== undefined && media.sizeBytes > limits.maxBytes) {
283
+ await refuse('size');
284
+ continue;
285
+ }
286
+ try {
287
+ const file = await adapter.download(media, { maxBytes: limits.maxBytes });
288
+ const attachment = await service.stageAttachment(actor, {
289
+ data: file.data,
290
+ contentType: file.contentType,
291
+ filename: file.filename ?? `${media.kind}.${extensionOf(file.contentType)}`,
292
+ });
293
+ refs.push({ mediaId: attachment.mediaId });
294
+ }
295
+ catch (error) {
296
+ if (error instanceof ChannelMediaTooLargeError)
297
+ await refuse('size');
298
+ else if (error instanceof AttachmentRefusedError)
299
+ await refuse(error.status === 413 ? 'size' : error.status === 415 ? 'type' : 'failed');
300
+ else {
301
+ await refuse('failed');
302
+ options.onError?.(error, message);
303
+ }
304
+ }
305
+ }
306
+ return refs;
307
+ };
308
+ /** Read a run's frames until it ends (or parks on something a text channel cannot settle). */
309
+ const readTurn = async (service, store, actor, runId, threadId, conversation) => {
310
+ const parts = [];
311
+ const proposals = new Map();
312
+ let failed = false;
313
+ let blocked = false;
314
+ let deadlineAt = Date.now() + timeoutMs;
315
+ /** The question set this reader is waiting on, while it waits. */
316
+ let asking = null;
317
+ const flush = async () => {
318
+ const text = parts.join('').trim();
319
+ parts.length = 0;
320
+ if (text !== '')
321
+ await deliver(conversation, text);
322
+ };
323
+ const stream = service.subscribe(runId)[Symbol.asyncIterator]();
324
+ let reading;
325
+ try {
326
+ for (;;) {
327
+ let timer;
328
+ const timeout = new Promise((resolve) => {
329
+ timer = setTimeout(() => resolve('timeout'), Math.max(0, deadlineAt - Date.now()));
330
+ });
331
+ // A read that lost a race to the timer is still the next frame: keep it, never ask twice.
332
+ reading ??= stream.next();
333
+ const next = await Promise.race([reading, timeout]).finally(() => clearTimeout(timer));
334
+ if (next !== 'timeout')
335
+ reading = undefined;
336
+ if (next === 'timeout') {
337
+ if (asking !== null) {
338
+ // Nobody answered: the agent goes on on its own assumptions.
339
+ const { runId: parkedRun, toolCallId } = asking;
340
+ asking = null;
341
+ await store.delete(questionKey(conversation));
342
+ await service
343
+ .skip({
344
+ runId: parkedRun,
345
+ toolCallId,
346
+ answeredByRef: actor.id,
347
+ answeredVia: adapter.name,
348
+ })
349
+ .catch(() => { });
350
+ deadlineAt = Date.now() + timeoutMs;
351
+ continue;
352
+ }
353
+ failed = parts.length === 0;
354
+ await service.cancel(runId).catch(() => { });
355
+ break;
356
+ }
357
+ if (next.done)
358
+ break;
359
+ const frame = next.value;
360
+ if (asking !== null) {
361
+ // The run moved on: the questions were answered (or skipped elsewhere).
362
+ asking = null;
363
+ deadlineAt = Date.now() + timeoutMs;
364
+ }
365
+ if (frame.t === 'text')
366
+ parts.push(frame.v);
367
+ else if (frame.t === 'component' && frame.fallbackText) {
368
+ // Only a component the turn negotiated as drawable comes as a frame — never with
369
+ // text-only capabilities; its text is all a channel can show.
370
+ parts.push(`\n\n${frame.fallbackText}\n\n`);
371
+ }
372
+ else if (frame.t === 'approval') {
373
+ if (frame.target?.kind === 'proposal') {
374
+ proposals.set(frame.target.proposalId, {
375
+ id: frame.target.proposalId,
376
+ toolName: frame.toolName,
377
+ ...(frame.confirmation ? { confirmation: frame.confirmation } : {}),
378
+ });
379
+ }
380
+ else {
381
+ // Blocking mode: the run waits for a decision this channel cannot make.
382
+ blocked = true;
383
+ break;
384
+ }
385
+ }
386
+ else if (frame.t === 'elicitation') {
387
+ const questions = frame.request.questions;
388
+ if (!service.answer || questions.length === 0) {
389
+ await service
390
+ .skip({
391
+ runId: frame.runId,
392
+ toolCallId: frame.id,
393
+ answeredByRef: actor.id,
394
+ answeredVia: adapter.name,
395
+ })
396
+ .catch(() => { });
397
+ continue;
398
+ }
399
+ await flush();
400
+ const pending = {
401
+ threadId,
402
+ runId: frame.runId,
403
+ toolCallId: frame.id,
404
+ ...(frame.request.preamble !== undefined ? { preamble: frame.request.preamble } : {}),
405
+ questions,
406
+ index: 0,
407
+ answers: {},
408
+ };
409
+ await store.set(questionKey(conversation), JSON.stringify(pending), questionTimeoutMs);
410
+ await askNext(conversation, pending);
411
+ asking = { runId: frame.runId, toolCallId: frame.id };
412
+ deadlineAt = Date.now() + questionTimeoutMs;
413
+ }
414
+ else if (frame.t === 'error')
415
+ failed = true;
416
+ }
417
+ }
418
+ finally {
419
+ void stream.return?.();
420
+ }
421
+ return { text: parts.join('').trim(), proposals: [...proposals.values()], failed, blocked };
422
+ };
423
+ const handleMessage = async (service, message) => {
424
+ await adapter.acknowledge?.(message).catch(() => { });
425
+ const store = await storeFor(service);
426
+ const actor = await options.actor(message);
427
+ if (actor === null) {
428
+ if (texts.unknownSender !== undefined)
429
+ await deliver(message.conversation, texts.unknownSender);
430
+ return;
431
+ }
432
+ const threadId = (await options.thread(actor, message)) ?? null;
433
+ const ours = message.buttonId !== undefined && BUTTON_ID.test(message.buttonId);
434
+ if (!ours) {
435
+ const waiting = await store.get(questionKey(message.conversation));
436
+ const pending = waiting === null ? null : JSON.parse(waiting);
437
+ if (pending !== null && (pending.threadId === null || pending.threadId === threadId)) {
438
+ await answerQuestion(service, store, actor, message, pending);
439
+ return;
440
+ }
441
+ }
442
+ if (await pressButton(service, actor, threadId, message))
443
+ return;
444
+ const attachments = await attachMedia(service, actor, message);
445
+ // A file nobody could attach, and no caption: there is nothing left to answer.
446
+ if (message.text === '' && attachments.length === 0)
447
+ return;
448
+ const pageContext = typeof options.pageContext === 'function'
449
+ ? options.pageContext(message)
450
+ : (options.pageContext ?? { kind: adapter.name });
451
+ const channel = { name: adapter.name, conversation: message.conversation };
452
+ const sent = await service.send({
453
+ actor,
454
+ message: message.text,
455
+ ...(threadId !== null ? { threadId } : {}),
456
+ ...(options.agentName !== undefined ? { agentName: options.agentName } : {}),
457
+ ...(attachments.length > 0 ? { attachments } : {}),
458
+ // Nothing is drawn: every component arrives as its text.
459
+ uiCapabilities: { components: [] },
460
+ pageContext: { ...pageContext, channel },
461
+ hostContext: {
462
+ channel: adapter.name,
463
+ conversation: message.conversation,
464
+ messageId: message.id,
465
+ },
466
+ });
467
+ if (threadId === null)
468
+ await options.onThreadCreated?.(sent.threadId, actor, message);
469
+ if ('proposalDecision' in sent) {
470
+ await deliver(message.conversation, sent.text);
471
+ const decided = sent.proposalDecision;
472
+ if ('proposal' in decided &&
473
+ decided.status === 'applied' &&
474
+ decided.proposal?.decision === 'approved')
475
+ await relayOutcome(service, actor, sent.threadId, decided.proposal.id, message.conversation);
476
+ return;
477
+ }
478
+ // A queued message starts later under its own id: its answer is read the same way.
479
+ const runId = sent.queued === true ? (sent.runId ?? sent.messageId) : sent.runId;
480
+ const turn = await readTurn(service, store, actor, runId, sent.threadId, message.conversation);
481
+ if (turn.text !== '')
482
+ await deliver(message.conversation, turn.text);
483
+ if (turn.failed)
484
+ await deliver(message.conversation, texts.failed);
485
+ if (turn.blocked)
486
+ await deliver(message.conversation, texts.blockingApproval);
487
+ for (const proposal of turn.proposals)
488
+ await sendProposal(service, message.conversation, proposal, turn.proposals.length > 1);
489
+ };
490
+ const track = (work) => {
491
+ inFlight.add(work);
492
+ void work.finally(() => inFlight.delete(work));
493
+ };
494
+ const handler = async (ctx) => {
495
+ const request = requestOf(ctx);
496
+ const challenge = adapter.challenge?.(request) ?? null;
497
+ if (challenge !== null) {
498
+ ctx.response
499
+ .status(challenge.status)
500
+ .header('content-type', challenge.contentType ?? 'text/plain')
501
+ .send(challenge.body);
502
+ return;
503
+ }
504
+ if (request.method !== 'POST') {
505
+ ctx.response.status(405).send({ error: 'method_not_allowed' });
506
+ return;
507
+ }
508
+ if (!(await adapter.verify(request))) {
509
+ ctx.response.status(401).send({ error: 'unauthorized' });
510
+ return;
511
+ }
512
+ const parsed = adapter.parse(request.body);
513
+ const messages = parsed === null ? [] : Array.isArray(parsed) ? parsed : [parsed];
514
+ if (messages.length > 0) {
515
+ const service = options.service ??
516
+ (await ctx.containerResolver.make(AgentService));
517
+ const store = await storeFor(service);
518
+ const fresh = [];
519
+ // Claimed before the 200: a store that is down answers 500, and the provider retries.
520
+ for (const message of messages) {
521
+ if (await store.claim(`${adapter.name}:${message.id}`, dedupeTtlMs))
522
+ fresh.push(message);
523
+ }
524
+ for (const message of fresh) {
525
+ track(handleMessage(service, message).catch((error) => {
526
+ if (options.onError)
527
+ options.onError(error, message);
528
+ else
529
+ console.error('[@adonis-agora/agent] Channel message failed', {
530
+ channel: adapter.name,
531
+ message: error instanceof Error ? error.message : String(error),
532
+ });
533
+ }));
534
+ }
535
+ }
536
+ ctx.response.status(200).send({ ok: true });
537
+ };
538
+ return Object.assign(handler, {
539
+ async drain() {
540
+ while (inFlight.size > 0)
541
+ await Promise.allSettled([...inFlight]);
542
+ },
543
+ });
544
+ }
545
+ /**
546
+ * `actionProposalWorker.onSettled` for text channels: relays an executed proposal's outcome to the
547
+ * conversation it was proposed in, through the adapter registered under the recorded channel name.
548
+ * Proposals from other surfaces are ignored. Safe next to the handler's own wait: an outcome is
549
+ * relayed once.
550
+ *
551
+ * ```ts
552
+ * // config/agent.ts
553
+ * actionProposalWorker: { onSettled: channels.onSettled }
554
+ * ```
555
+ */
556
+ export async function relayChannelOutcome(proposal) {
557
+ await deliverOutcome(proposal);
558
+ }
559
+ export const channels = {
560
+ /** See {@link handleChannel}. */
561
+ handle: handleChannel,
562
+ /** See {@link relayChannelOutcome}. */
563
+ onSettled: relayChannelOutcome,
564
+ /** Relay one proposal's outcome now; `true` when it was sent. */
565
+ deliverOutcome: (proposal, service) => deliverOutcome(proposal, service),
566
+ /** The adapter registered under `name` (by `channels.handle`), if any. */
567
+ adapter: (name) => registry.get(name)?.adapter,
568
+ };
569
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/channels/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /** A provider refused (or could not be reached for) a delivery. `status` is its HTTP status, if any. */
2
+ export declare class ChannelDeliveryError extends Error {
3
+ readonly channel: string;
4
+ readonly status: number | null;
5
+ constructor(channel: string, status: number | null, message: string);
6
+ /**
7
+ * The provider answered and said no (400, 403, 404, 422): the message was certainly not delivered,
8
+ * so sending something else in its place cannot duplicate it.
9
+ */
10
+ get definite(): boolean;
11
+ }
12
+ /** A file was larger than the attachment limit; it was not (fully) downloaded. */
13
+ export declare class ChannelMediaTooLargeError extends Error {
14
+ readonly maxBytes: number;
15
+ constructor(maxBytes: number);
16
+ }
17
+ /**
18
+ * GET a file, refusing one past `maxBytes` — by its `content-length` before reading, and by what
19
+ * actually arrives while reading. Throws a {@link ChannelDeliveryError} on a non-2xx.
20
+ */
21
+ export declare function fetchBytes(channel: string, fetcher: ChannelFetch, url: string, headers: Record<string, string>, timeoutMs: number, maxBytes: number): Promise<{
22
+ data: Buffer;
23
+ contentType: string | undefined;
24
+ }>;
25
+ /** Bytes of a base64 string, refusing past `maxBytes` before decoding. */
26
+ export declare function decodeBase64(base64: string, maxBytes: number): Buffer;
27
+ /** A positive number out of a webhook field that may be a number, a numeric string or a Long object. */
28
+ export declare function sizeOf(value: unknown): number | undefined;
29
+ /** Compare two secrets in constant time (over their hashes, so lengths leak nothing either). */
30
+ export declare function safeEqual(supplied: string | undefined | null, expected: string): boolean;
31
+ /** The `fetch` adapters use — `globalThis.fetch` unless a test (or a proxy) hands one in. */
32
+ export type ChannelFetch = typeof fetch;
33
+ /**
34
+ * POST a JSON body. Resolves with the parsed JSON answer (`null` when it is not JSON); throws a
35
+ * {@link ChannelDeliveryError} on a non-2xx or a network failure. The provider's error body is never
36
+ * put in the error — it can echo the message text or credentials.
37
+ */
38
+ export declare function postJson(channel: string, fetcher: ChannelFetch, url: string, headers: Record<string, string>, body: unknown, timeoutMs: number): Promise<unknown>;
39
+ /** A query-string parameter of a request's url. */
40
+ export declare function queryParam(url: string, name: string): string | undefined;
41
+ /** `value` when it is a plain object, else `undefined` — for reading untyped webhook bodies. */
42
+ export declare function record(value: unknown): Record<string, unknown> | undefined;
43
+ /** `value` when it is a non-empty string. */
44
+ export declare function str(value: unknown): string | undefined;
45
+ //# sourceMappingURL=http.d.ts.map