@heyamiko/openclaw-amiko 0.2.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 (55) hide show
  1. package/README.md +184 -0
  2. package/contracts/channel-config.schema.json +87 -0
  3. package/contracts/platform-ack.schema.json +25 -0
  4. package/contracts/platform-events.schema.json +87 -0
  5. package/contracts/platform-outbound.schema.json +47 -0
  6. package/dist/index.d.ts +20 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +61 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/src/accounts.d.ts +30 -0
  11. package/dist/src/accounts.d.ts.map +1 -0
  12. package/dist/src/accounts.js +115 -0
  13. package/dist/src/accounts.js.map +1 -0
  14. package/dist/src/api.d.ts +13 -0
  15. package/dist/src/api.d.ts.map +1 -0
  16. package/dist/src/api.js +45 -0
  17. package/dist/src/api.js.map +1 -0
  18. package/dist/src/channel.d.ts +174 -0
  19. package/dist/src/channel.d.ts.map +1 -0
  20. package/dist/src/channel.js +140 -0
  21. package/dist/src/channel.js.map +1 -0
  22. package/dist/src/config-schema.d.ts +92 -0
  23. package/dist/src/config-schema.d.ts.map +1 -0
  24. package/dist/src/config-schema.js +17 -0
  25. package/dist/src/config-schema.js.map +1 -0
  26. package/dist/src/monitor.d.ts +19 -0
  27. package/dist/src/monitor.d.ts.map +1 -0
  28. package/dist/src/monitor.js +433 -0
  29. package/dist/src/monitor.js.map +1 -0
  30. package/dist/src/reply-prefix.d.ts +12 -0
  31. package/dist/src/reply-prefix.d.ts.map +1 -0
  32. package/dist/src/reply-prefix.js +8 -0
  33. package/dist/src/reply-prefix.js.map +1 -0
  34. package/dist/src/runtime.d.ts +57 -0
  35. package/dist/src/runtime.d.ts.map +1 -0
  36. package/dist/src/runtime.js +28 -0
  37. package/dist/src/runtime.js.map +1 -0
  38. package/dist/src/send.d.ts +8 -0
  39. package/dist/src/send.d.ts.map +1 -0
  40. package/dist/src/send.js +51 -0
  41. package/dist/src/send.js.map +1 -0
  42. package/dist/src/status.d.ts +19 -0
  43. package/dist/src/status.d.ts.map +1 -0
  44. package/dist/src/status.js +51 -0
  45. package/dist/src/status.js.map +1 -0
  46. package/dist/src/types.d.ts +79 -0
  47. package/dist/src/types.d.ts.map +1 -0
  48. package/dist/src/types.js +2 -0
  49. package/dist/src/types.js.map +1 -0
  50. package/openclaw.plugin.json +51 -0
  51. package/package.json +75 -0
  52. package/skills/amiko/SKILL.md +287 -0
  53. package/skills/amiko/cli.js +521 -0
  54. package/skills/amiko/lib.js +634 -0
  55. package/skills/composio/SKILL.md +102 -0
@@ -0,0 +1,433 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { sendTextAmiko } from "./send.js";
3
+ import { createReplyPrefixOptions } from "./reply-prefix.js";
4
+ function verifyHmacSignature(secret, body, signature) {
5
+ const expected = createHmac("sha256", secret)
6
+ .update(typeof body === "string" ? body : body)
7
+ .digest("hex");
8
+ const expectedBuf = Buffer.from(`sha256=${expected}`, "utf8");
9
+ const actualBuf = Buffer.from(signature, "utf8");
10
+ if (expectedBuf.length !== actualBuf.length)
11
+ return false;
12
+ return timingSafeEqual(expectedBuf, actualBuf);
13
+ }
14
+ function buildAmikoReplyContext(event, account) {
15
+ const replyMode = event.replyMode ?? "as_owner";
16
+ const lines = [
17
+ "Amiko reply context:",
18
+ `- Channel account: ${account.accountId}`,
19
+ `- Twin ID: ${account.twinId}`,
20
+ `- Reply mode: ${replyMode}`,
21
+ ];
22
+ if (replyMode === "as_owner") {
23
+ lines.push(`- You are replying on behalf of the owner${event.ownerName ? `, ${event.ownerName}` : ""}.`, `- Write as the owner in first person. Do not describe yourself as an AI, assistant, or proxy unless the owner explicitly wants that.`);
24
+ if (event.ownerId) {
25
+ lines.push(`- Owner ID: ${event.ownerId}`);
26
+ }
27
+ if (event.sharedAccountPrompt?.trim()) {
28
+ lines.push(`- Shared account prompt: ${event.sharedAccountPrompt.trim()}`);
29
+ }
30
+ }
31
+ else {
32
+ lines.push("- You are replying as the twin/agent identity, not as the owner.", "- Write as that persona directly in first person.");
33
+ }
34
+ if (event.senderName || event.senderId) {
35
+ lines.push(`- Incoming sender: ${event.senderName || event.senderId}`);
36
+ }
37
+ if (event.conversationType) {
38
+ lines.push(`- Conversation type: ${event.conversationType}`);
39
+ }
40
+ return lines.join("\n");
41
+ }
42
+ // ── Chat message processing ─────────────────────────────────────────────────
43
+ async function processChatEvent(event, options) {
44
+ const { account, runtime: core, config } = options;
45
+ const replyExpected = event.replyExpected !== false;
46
+ const replyMode = event.replyMode ?? "as_owner";
47
+ console.log(`[amiko:${account.accountId}] processChatEvent: convId=${event.conversationId} sender=${event.senderName} replyExpected=${replyExpected} replyMode=${replyMode}`);
48
+ const isGroup = event.conversationType === "group";
49
+ const conversationId = event.conversationId;
50
+ const peer = { kind: event.conversationType, id: conversationId };
51
+ const route = core.channel.routing.resolveAgentRoute({
52
+ cfg: config,
53
+ channel: "amiko",
54
+ accountId: account.accountId,
55
+ peer,
56
+ });
57
+ const storePath = core.channel.session.resolveStorePath(config.session?.store, { agentId: route.agentId });
58
+ const rawBody = event.text?.trim() ?? "";
59
+ const roleContext = buildAmikoReplyContext(event, account);
60
+ const agentBody = `${roleContext}\n\nIncoming message:\n${rawBody}`.trim();
61
+ const fromLabel = isGroup
62
+ ? `group:${conversationId}`
63
+ : (event.senderName || `user:${event.senderId}`);
64
+ const previousTimestamp = core.channel.session.readSessionUpdatedAt({
65
+ storePath,
66
+ sessionKey: route.sessionKey,
67
+ });
68
+ const body = core.channel.reply.formatAgentEnvelope({
69
+ channel: "Amiko",
70
+ from: fromLabel,
71
+ timestamp: event.timestamp,
72
+ previousTimestamp,
73
+ envelope: core.channel.reply.resolveEnvelopeFormatOptions(config),
74
+ body: agentBody,
75
+ });
76
+ const ctxPayload = core.channel.reply.finalizeInboundContext({
77
+ Body: body,
78
+ BodyForAgent: agentBody,
79
+ RawBody: rawBody,
80
+ CommandBody: rawBody,
81
+ From: isGroup ? `amiko:group:${conversationId}` : `amiko:${event.senderId}`,
82
+ To: `amiko:${conversationId}`,
83
+ SessionKey: route.sessionKey,
84
+ AccountId: route.accountId,
85
+ ChatType: isGroup ? "group" : "direct",
86
+ ConversationLabel: fromLabel,
87
+ SenderName: event.senderName || undefined,
88
+ SenderId: event.senderId,
89
+ Provider: "amiko",
90
+ Surface: "amiko",
91
+ MessageSid: event.id,
92
+ OriginatingChannel: "amiko",
93
+ OriginatingTo: `amiko:${conversationId}`,
94
+ });
95
+ // ── replyExpected: false → persist context only, no agent response ─────────
96
+ if (!replyExpected) {
97
+ console.log(`[amiko:${account.accountId}] recording context only (no reply): ${rawBody.slice(0, 100)}`);
98
+ await core.channel.session.recordInboundSession({
99
+ storePath,
100
+ sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
101
+ ctx: ctxPayload,
102
+ onRecordError: (err) => {
103
+ console.error(`[amiko:${account.accountId}] recordInboundSession error:`, err);
104
+ },
105
+ });
106
+ return;
107
+ }
108
+ // ── replyExpected: true → full agent dispatch ──────────────────────────────
109
+ await core.channel.session.recordInboundSession({
110
+ storePath,
111
+ sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
112
+ ctx: ctxPayload,
113
+ onRecordError: (err) => {
114
+ console.error(`[amiko:${account.accountId}] recordInboundSession error:`, err);
115
+ },
116
+ });
117
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
118
+ cfg: config,
119
+ agentId: route.agentId,
120
+ channel: "amiko",
121
+ accountId: account.accountId,
122
+ });
123
+ console.log(`[amiko:${account.accountId}] dispatching reply: sessionKey=${route.sessionKey} replyMode=${replyMode}`);
124
+ await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
125
+ ctx: ctxPayload,
126
+ cfg: config,
127
+ dispatcherOptions: {
128
+ ...prefixOptions,
129
+ deliver: async (payload) => {
130
+ if (payload.text) {
131
+ console.log(`[amiko:${account.accountId}] delivering reply (${replyMode}) to ${conversationId}: ${payload.text.slice(0, 100)}`);
132
+ const result = await sendTextAmiko(conversationId, payload.text, account, { replyMode });
133
+ if (!result.ok) {
134
+ console.error(`[amiko:${account.accountId}] sendTextAmiko failed:`, result);
135
+ }
136
+ else {
137
+ console.log(`[amiko:${account.accountId}] reply delivered ok: messageId=${result.messageId}`);
138
+ }
139
+ }
140
+ },
141
+ onError: (err, info) => {
142
+ console.error(`[amiko:${account.accountId}] ${info.kind} reply error:`, err);
143
+ },
144
+ },
145
+ replyOptions: {
146
+ onModelSelected,
147
+ },
148
+ });
149
+ }
150
+ // ── Post comment processing ─────────────────────────────────────────────────
151
+ async function processPostEvent(event, options) {
152
+ const { account, runtime: core, config } = options;
153
+ const postId = event.postId ?? event.id;
154
+ const authorName = event.authorName ?? event.senderName ?? "Someone";
155
+ const content = event.text?.trim() ?? "";
156
+ console.log(`[amiko:${account.accountId}] processPostEvent: postId=${postId} author=${authorName}`);
157
+ if (!content)
158
+ return;
159
+ const peer = { kind: "direct", id: `post:${postId}` };
160
+ const route = core.channel.routing.resolveAgentRoute({
161
+ cfg: config,
162
+ channel: "amiko",
163
+ accountId: account.accountId,
164
+ peer,
165
+ });
166
+ // Keep post sessions under OpenClaw's agent-scoped session key convention.
167
+ const sessionKey = route.sessionKey;
168
+ const prompt = `Your friend ${authorName} just posted on Amiko:\n\n"${content}"\n\nWrite a short, genuine comment in your own voice. Be natural, personal, and engaged — react to what they shared, ask a question, or express your thoughts. Keep it brief.\n\nOnly respond with <empty-response/> if the post contains offensive, harmful, or inappropriate content that you should not engage with.`;
169
+ const storePath = core.channel.session.resolveStorePath(config.session?.store, { agentId: route.agentId });
170
+ const ctxPayload = core.channel.reply.finalizeInboundContext({
171
+ Body: prompt,
172
+ BodyForAgent: prompt,
173
+ RawBody: prompt,
174
+ CommandBody: prompt,
175
+ From: `amiko:post:${postId}`,
176
+ To: `amiko:${account.accountId}`,
177
+ SessionKey: sessionKey,
178
+ AccountId: route.accountId,
179
+ ChatType: "direct",
180
+ ConversationLabel: `post by ${authorName}`,
181
+ SenderName: authorName,
182
+ SenderId: event.authorId ?? event.senderId,
183
+ Provider: "amiko",
184
+ Surface: "amiko",
185
+ MessageSid: event.id,
186
+ OriginatingChannel: "amiko",
187
+ OriginatingTo: `amiko:post:${postId}`,
188
+ });
189
+ await core.channel.session.recordInboundSession({
190
+ storePath,
191
+ sessionKey,
192
+ ctx: ctxPayload,
193
+ onRecordError: (err) => {
194
+ console.error(`[amiko:${account.accountId}] recordInboundSession error (post):`, err);
195
+ },
196
+ });
197
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
198
+ cfg: config,
199
+ agentId: route.agentId,
200
+ channel: "amiko",
201
+ accountId: account.accountId,
202
+ });
203
+ console.log(`[amiko:${account.accountId}] dispatching post comment: sessionKey=${sessionKey}`);
204
+ await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
205
+ ctx: ctxPayload,
206
+ cfg: config,
207
+ dispatcherOptions: {
208
+ ...prefixOptions,
209
+ deliver: async (payload) => {
210
+ if (!payload.text)
211
+ return;
212
+ const text = payload.text.trim();
213
+ // Agent chose not to comment
214
+ if (text === "<empty-response/>" || text.includes("<empty-response/>")) {
215
+ console.log(`[amiko:${account.accountId}] agent skipped post comment for ${postId}`);
216
+ return;
217
+ }
218
+ // Post comment via amiko-new API
219
+ const commentUrl = `${account.platformApiBaseUrl}/api/posts/${postId}/comments`;
220
+ console.log(`[amiko:${account.accountId}] posting comment on ${postId}: ${text.slice(0, 100)}`);
221
+ try {
222
+ const res = await fetch(commentUrl, {
223
+ method: "POST",
224
+ headers: {
225
+ Authorization: `Bearer ${account.token}`,
226
+ "Content-Type": "application/json",
227
+ },
228
+ body: JSON.stringify({ comment: text }),
229
+ });
230
+ if (!res.ok) {
231
+ const errText = await res.text().catch(() => "");
232
+ console.error(`[amiko:${account.accountId}] comment POST failed: ${res.status} ${errText.slice(0, 200)}`);
233
+ }
234
+ else {
235
+ const data = (await res.json());
236
+ console.log(`[amiko:${account.accountId}] comment posted ok: ${data.comment?.id ?? "unknown"}`);
237
+ }
238
+ }
239
+ catch (err) {
240
+ console.error(`[amiko:${account.accountId}] comment POST error:`, err);
241
+ }
242
+ },
243
+ onError: (err, info) => {
244
+ console.error(`[amiko:${account.accountId}] ${info.kind} post reply error:`, err);
245
+ },
246
+ },
247
+ replyOptions: {
248
+ onModelSelected,
249
+ },
250
+ });
251
+ }
252
+ async function processPostCommentEvent(event, options) {
253
+ const { account, runtime: core, config } = options;
254
+ const postId = event.postId ?? event.id;
255
+ const commentId = event.commentId ?? event.id;
256
+ const commenterName = event.senderName ?? event.authorName ?? "Someone";
257
+ const postAuthorName = event.authorName ?? "your friend";
258
+ const content = event.text?.trim() ?? "";
259
+ console.log(`[amiko:${account.accountId}] processPostCommentEvent: postId=${postId} commentId=${commentId} commenter=${commenterName}`);
260
+ if (!content)
261
+ return;
262
+ const peer = { kind: "direct", id: `post:${postId}:comment:${commentId}` };
263
+ const route = core.channel.routing.resolveAgentRoute({
264
+ cfg: config,
265
+ channel: "amiko",
266
+ accountId: account.accountId,
267
+ peer,
268
+ });
269
+ // Keep post-comment sessions under OpenClaw's agent-scoped session key convention.
270
+ const sessionKey = route.sessionKey;
271
+ const prompt = `On a post by ${postAuthorName}, ${commenterName} commented:\n\n` +
272
+ `"${content}"\n\n` +
273
+ `If you'd like to reply in the post comments, write your comment. ` +
274
+ `If you don't want to reply, respond with <empty-response/> only.`;
275
+ const storePath = core.channel.session.resolveStorePath(config.session?.store, { agentId: route.agentId });
276
+ const ctxPayload = core.channel.reply.finalizeInboundContext({
277
+ Body: prompt,
278
+ BodyForAgent: prompt,
279
+ RawBody: prompt,
280
+ CommandBody: prompt,
281
+ From: `amiko:post:${postId}:comment:${commentId}`,
282
+ To: `amiko:${account.accountId}`,
283
+ SessionKey: sessionKey,
284
+ AccountId: route.accountId,
285
+ ChatType: "direct",
286
+ ConversationLabel: `comment by ${commenterName} on post ${postId}`,
287
+ SenderName: commenterName,
288
+ SenderId: event.senderId,
289
+ Provider: "amiko",
290
+ Surface: "amiko",
291
+ MessageSid: event.id,
292
+ OriginatingChannel: "amiko",
293
+ OriginatingTo: `amiko:post:${postId}:comment:${commentId}`,
294
+ });
295
+ await core.channel.session.recordInboundSession({
296
+ storePath,
297
+ sessionKey,
298
+ ctx: ctxPayload,
299
+ onRecordError: (err) => {
300
+ console.error(`[amiko:${account.accountId}] recordInboundSession error (post comment):`, err);
301
+ },
302
+ });
303
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
304
+ cfg: config,
305
+ agentId: route.agentId,
306
+ channel: "amiko",
307
+ accountId: account.accountId,
308
+ });
309
+ console.log(`[amiko:${account.accountId}] dispatching post-comment reply: sessionKey=${sessionKey}`);
310
+ await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
311
+ ctx: ctxPayload,
312
+ cfg: config,
313
+ dispatcherOptions: {
314
+ ...prefixOptions,
315
+ deliver: async (payload) => {
316
+ if (!payload.text)
317
+ return;
318
+ const text = payload.text.trim();
319
+ if (text === "<empty-response/>" || text.includes("<empty-response/>")) {
320
+ console.log(`[amiko:${account.accountId}] agent skipped post-comment reply for ${postId}/${commentId}`);
321
+ return;
322
+ }
323
+ const commentUrl = `${account.platformApiBaseUrl}/api/posts/${postId}/comments`;
324
+ console.log(`[amiko:${account.accountId}] posting reply comment on ${postId} for comment ${commentId}: ${text.slice(0, 100)}`);
325
+ try {
326
+ const res = await fetch(commentUrl, {
327
+ method: "POST",
328
+ headers: {
329
+ Authorization: `Bearer ${account.token}`,
330
+ "Content-Type": "application/json",
331
+ },
332
+ body: JSON.stringify({ comment: text }),
333
+ });
334
+ if (!res.ok) {
335
+ const errText = await res.text().catch(() => "");
336
+ console.error(`[amiko:${account.accountId}] reply comment POST failed: ${res.status} ${errText.slice(0, 200)}`);
337
+ }
338
+ else {
339
+ const data = (await res.json());
340
+ console.log(`[amiko:${account.accountId}] reply comment posted ok: ${data.comment?.id ?? "unknown"}`);
341
+ }
342
+ }
343
+ catch (err) {
344
+ console.error(`[amiko:${account.accountId}] reply comment POST error:`, err);
345
+ }
346
+ },
347
+ onError: (err, info) => {
348
+ console.error(`[amiko:${account.accountId}] ${info.kind} post-comment reply error:`, err);
349
+ },
350
+ },
351
+ replyOptions: {
352
+ onModelSelected,
353
+ },
354
+ });
355
+ }
356
+ // ── Event dispatcher ────────────────────────────────────────────────────────
357
+ async function processEvent(event, options) {
358
+ if (event.type === "post.published") {
359
+ return processPostEvent(event, options);
360
+ }
361
+ if (event.type === "post.comment") {
362
+ return processPostCommentEvent(event, options);
363
+ }
364
+ if (event.type === "message.text" || event.type === "message.image") {
365
+ return processChatEvent(event, options);
366
+ }
367
+ console.log(`[amiko:${options.account.accountId}] ignoring event type: ${event.type}`);
368
+ }
369
+ // ── Webhook monitor ─────────────────────────────────────────────────────────
370
+ export async function monitorAmikoProvider(options) {
371
+ const { account, statusSink } = options;
372
+ const webhookPath = account.config.webhookPath ?? `/amiko/webhook/${account.twinId}`;
373
+ const webhookSecret = account.config.webhookSecret;
374
+ const handler = async (req, res) => {
375
+ const sendJson = (statusCode, body) => {
376
+ const json = JSON.stringify(body);
377
+ res.statusCode = statusCode;
378
+ res.setHeader("Content-Type", "application/json");
379
+ res.setHeader("Content-Length", Buffer.byteLength(json));
380
+ res.end(json);
381
+ };
382
+ if ((req.method ?? "POST").toUpperCase() !== "POST") {
383
+ sendJson(405, { error: "method not allowed" });
384
+ return;
385
+ }
386
+ const rawBody = await new Promise((resolve, reject) => {
387
+ const chunks = [];
388
+ req.on("data", (chunk) => chunks.push(chunk));
389
+ req.on("end", () => resolve(Buffer.concat(chunks)));
390
+ req.on("error", reject);
391
+ });
392
+ if (webhookSecret) {
393
+ const sig = req.headers["x-amiko-signature"];
394
+ if (!sig) {
395
+ sendJson(401, { error: "missing signature" });
396
+ return;
397
+ }
398
+ if (!verifyHmacSignature(webhookSecret, rawBody, sig)) {
399
+ sendJson(401, { error: "invalid signature" });
400
+ return;
401
+ }
402
+ }
403
+ let payload;
404
+ try {
405
+ payload = JSON.parse(rawBody.toString("utf8"));
406
+ }
407
+ catch {
408
+ sendJson(400, { error: "invalid JSON" });
409
+ return;
410
+ }
411
+ const event = payload?.event;
412
+ if (!event?.id || !event?.type) {
413
+ sendJson(400, { error: "missing event" });
414
+ return;
415
+ }
416
+ sendJson(200, { ok: true });
417
+ try {
418
+ await processEvent(event, options);
419
+ statusSink({ accountId: account.accountId, status: "healthy" });
420
+ }
421
+ catch (err) {
422
+ console.error(`[amiko:${account.accountId}] Error processing event ${event.id}:`, err);
423
+ statusSink({ accountId: account.accountId, status: "unhealthy", message: String(err) });
424
+ }
425
+ };
426
+ statusSink({ accountId: account.accountId, status: "healthy" });
427
+ return {
428
+ webhookPath,
429
+ handler,
430
+ stop: () => { },
431
+ };
432
+ }
433
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI1D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAgB7D,SAAS,mBAAmB,CAAC,MAAc,EAAE,IAAqB,EAAE,SAAiB;IACnF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC;SAC1C,MAAM,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;SAC9C,MAAM,CAAC,KAAK,CAAC,CAAC;IACjB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1D,OAAO,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAwB,EAAE,OAA6B;IACrF,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,UAAU,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,sBAAsB;QACtB,sBAAsB,OAAO,CAAC,SAAS,EAAE;QACzC,cAAc,OAAO,CAAC,MAAM,EAAE;QAC9B,iBAAiB,SAAS,EAAE;KAC7B,CAAC;IAEF,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CACR,4CAA4C,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAC5F,sIAAsI,CACvI,CAAC;QACF,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,CAAC,mBAAmB,EAAE,IAAI,EAAE,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,4BAA4B,KAAK,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,kEAAkE,EAClE,mDAAmD,CACpD,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,wBAAwB,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,+EAA+E;AAE/E,KAAK,UAAU,gBAAgB,CAC7B,KAAwB,EACxB,OAA+D;IAE/D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC;IACpD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,UAAU,CAAC;IAEhD,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,8BAA8B,KAAK,CAAC,cAAc,WAAW,KAAK,CAAC,UAAU,kBAAkB,aAAa,cAAc,SAAS,EAAE,CACjK,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,gBAAgB,KAAK,OAAO,CAAC;IACnD,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAE5C,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,gBAAsC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC;IAExF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACnD,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CACpD,MAAc,CAAC,OAAO,EAAE,KAAK,EAC9B,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAC3B,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,sBAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,GAAG,WAAW,0BAA0B,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;IAC3E,MAAM,SAAS,GAAG,OAAO;QACvB,CAAC,CAAC,SAAS,cAAc,EAAE;QAC3B,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEnD,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAClE,SAAS;QACT,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC;QAClD,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,iBAAiB;QACjB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,MAAM,CAAC;QACjE,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAC3D,IAAI,EAAE,IAAI;QACV,YAAY,EAAE,SAAS;QACvB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,OAAO;QACpB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,cAAc,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,QAAQ,EAAE;QAC3E,EAAE,EAAE,SAAS,cAAc,EAAE;QAC7B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;QACtC,iBAAiB,EAAE,SAAS;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,SAAS;QACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,OAAO;QAChB,UAAU,EAAE,KAAK,CAAC,EAAE;QACpB,kBAAkB,EAAE,OAAO;QAC3B,aAAa,EAAE,SAAS,cAAc,EAAE;KACzC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,wCAAwC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC3F,CAAC;QAEF,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;YAC9C,SAAS;YACT,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU;YACrD,GAAG,EAAE,UAAU;YACf,aAAa,EAAE,CAAC,GAAY,EAAE,EAAE;gBAC9B,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,+BAA+B,EAAE,GAAG,CAAC,CAAC;YACjF,CAAC;SACF,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,8EAA8E;IAE9E,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAC9C,SAAS;QACT,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU;QACrD,GAAG,EAAE,UAAU;QACf,aAAa,EAAE,CAAC,GAAY,EAAE,EAAE;YAC9B,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,+BAA+B,EAAE,GAAG,CAAC,CAAC;QACjF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,GAAG,wBAAwB,CAAC;QACrE,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,mCAAmC,KAAK,CAAC,UAAU,cAAc,SAAS,EAAE,CACxG,CAAC;IAEF,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC;QAChE,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,MAAM;QACX,iBAAiB,EAAE;YACjB,GAAG,aAAa;YAChB,OAAO,EAAE,KAAK,EAAE,OAA6C,EAAE,EAAE;gBAC/D,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;oBACjB,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,uBAAuB,SAAS,QAAQ,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACnH,CAAC;oBACF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;oBACzF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,yBAAyB,EAAE,MAAM,CAAC,CAAC;oBAC9E,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,SAAS,mCAAmC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;oBAChG,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,EAAE,CAAC,GAAY,EAAE,IAAsB,EAAE,EAAE;gBAChD,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,IAAI,eAAe,EAAE,GAAG,CAAC,CAAC;YAC/E,CAAC;SACF;QACD,YAAY,EAAE;YACZ,eAAe;SAChB;KACF,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAE/E,KAAK,UAAU,gBAAgB,CAC7B,KAAwB,EACxB,OAA+D;IAE/D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC;IACrE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAEzC,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,8BAA8B,MAAM,WAAW,UAAU,EAAE,CACvF,CAAC;IAEF,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,EAAE,EAAE,QAAQ,MAAM,EAAE,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACnD,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI;KACL,CAAC,CAAC;IAEH,2EAA2E;IAC3E,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IAEpC,MAAM,MAAM,GAAG,eAAe,UAAU,8BAA8B,OAAO,0TAA0T,CAAC;IAExY,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CACpD,MAAc,CAAC,OAAO,EAAE,KAAK,EAC9B,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAC3B,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAC3D,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,MAAM;QACpB,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,MAAM;QACnB,IAAI,EAAE,cAAc,MAAM,EAAE;QAC5B,EAAE,EAAE,SAAS,OAAO,CAAC,SAAS,EAAE;QAChC,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,QAAQ;QAClB,iBAAiB,EAAE,WAAW,UAAU,EAAE;QAC1C,UAAU,EAAE,UAAU;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ;QAC1C,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,OAAO;QAChB,UAAU,EAAE,KAAK,CAAC,EAAE;QACpB,kBAAkB,EAAE,OAAO;QAC3B,aAAa,EAAE,cAAc,MAAM,EAAE;KACtC,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAC9C,SAAS;QACT,UAAU;QACV,GAAG,EAAE,UAAU;QACf,aAAa,EAAE,CAAC,GAAY,EAAE,EAAE;YAC9B,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,sCAAsC,EAAE,GAAG,CAAC,CAAC;QACxF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,GAAG,wBAAwB,CAAC;QACrE,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,0CAA0C,UAAU,EAAE,CAClF,CAAC;IAEF,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC;QAChE,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,MAAM;QACX,iBAAiB,EAAE;YACjB,GAAG,aAAa;YAChB,OAAO,EAAE,KAAK,EAAE,OAA0B,EAAE,EAAE;gBAC5C,IAAI,CAAC,OAAO,CAAC,IAAI;oBAAE,OAAO;gBAE1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAEjC,6BAA6B;gBAC7B,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBACvE,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,SAAS,oCAAoC,MAAM,EAAE,CAAC,CAAC;oBACrF,OAAO;gBACT,CAAC;gBAED,iCAAiC;gBACjC,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,kBAAkB,cAAc,MAAM,WAAW,CAAC;gBAChF,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,wBAAwB,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACnF,CAAC;gBAEF,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;wBAClC,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE;4BACP,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;4BACxC,cAAc,EAAE,kBAAkB;yBACnC;wBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;qBACxC,CAAC,CAAC;oBAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;wBACZ,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;wBACjD,OAAO,CAAC,KAAK,CACX,UAAU,OAAO,CAAC,SAAS,0BAA0B,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC3F,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkC,CAAC;wBACjE,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,wBAAwB,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,SAAS,EAAE,CACnF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,uBAAuB,EAAE,GAAG,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YACD,OAAO,EAAE,CAAC,GAAY,EAAE,IAAsB,EAAE,EAAE;gBAChD,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,IAAI,oBAAoB,EAAE,GAAG,CAAC,CAAC;YACpF,CAAC;SACF;QACD,YAAY,EAAE;YACZ,eAAe;SAChB;KACF,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,KAAwB,EACxB,OAA+D;IAE/D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC;IACxC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,EAAE,CAAC;IAC9C,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC;IACxE,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,IAAI,aAAa,CAAC;IACzD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAEzC,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,qCAAqC,MAAM,cAAc,SAAS,cAAc,aAAa,EAAE,CAC3H,CAAC;IAEF,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,EAAE,EAAE,QAAQ,MAAM,YAAY,SAAS,EAAE,EAAE,CAAC;IACpF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACnD,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI;KACL,CAAC,CAAC;IAEH,mFAAmF;IACnF,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACpC,MAAM,MAAM,GACV,gBAAgB,cAAc,KAAK,aAAa,iBAAiB;QACjE,IAAI,OAAO,OAAO;QAClB,mEAAmE;QACnE,kEAAkE,CAAC;IAErE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CACpD,MAAc,CAAC,OAAO,EAAE,KAAK,EAC9B,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAC3B,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAC3D,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,MAAM;QACpB,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,MAAM;QACnB,IAAI,EAAE,cAAc,MAAM,YAAY,SAAS,EAAE;QACjD,EAAE,EAAE,SAAS,OAAO,CAAC,SAAS,EAAE;QAChC,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,QAAQ;QAClB,iBAAiB,EAAE,cAAc,aAAa,YAAY,MAAM,EAAE;QAClE,UAAU,EAAE,aAAa;QACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,OAAO;QAChB,UAAU,EAAE,KAAK,CAAC,EAAE;QACpB,kBAAkB,EAAE,OAAO;QAC3B,aAAa,EAAE,cAAc,MAAM,YAAY,SAAS,EAAE;KAC3D,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAC9C,SAAS;QACT,UAAU;QACV,GAAG,EAAE,UAAU;QACf,aAAa,EAAE,CAAC,GAAY,EAAE,EAAE;YAC9B,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,8CAA8C,EAAE,GAAG,CAAC,CAAC;QAChG,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,GAAG,wBAAwB,CAAC;QACrE,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,gDAAgD,UAAU,EAAE,CACxF,CAAC;IAEF,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC;QAChE,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,MAAM;QACX,iBAAiB,EAAE;YACjB,GAAG,aAAa;YAChB,OAAO,EAAE,KAAK,EAAE,OAA0B,EAAE,EAAE;gBAC5C,IAAI,CAAC,OAAO,CAAC,IAAI;oBAAE,OAAO;gBAE1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACjC,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBACvE,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,0CAA0C,MAAM,IAAI,SAAS,EAAE,CAC3F,CAAC;oBACF,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,kBAAkB,cAAc,MAAM,WAAW,CAAC;gBAChF,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,8BAA8B,MAAM,gBAAgB,SAAS,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAClH,CAAC;gBAEF,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;wBAClC,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE;4BACP,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;4BACxC,cAAc,EAAE,kBAAkB;yBACnC;wBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;qBACxC,CAAC,CAAC;oBAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;wBACZ,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;wBACjD,OAAO,CAAC,KAAK,CACX,UAAU,OAAO,CAAC,SAAS,gCAAgC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACjG,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkC,CAAC;wBACjE,OAAO,CAAC,GAAG,CACT,UAAU,OAAO,CAAC,SAAS,8BAA8B,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,SAAS,EAAE,CACzF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,6BAA6B,EAAE,GAAG,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC;YACD,OAAO,EAAE,CAAC,GAAY,EAAE,IAAsB,EAAE,EAAE;gBAChD,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,IAAI,4BAA4B,EAAE,GAAG,CAAC,CAAC;YAC5F,CAAC;SACF;QACD,YAAY,EAAE;YACZ,eAAe;SAChB;KACF,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAE/E,KAAK,UAAU,YAAY,CACzB,KAAwB,EACxB,OAA+D;IAE/D,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAClC,OAAO,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACpE,OAAO,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,OAAO,CAAC,SAAS,0BAA0B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACzF,CAAC;AAED,+EAA+E;AAE/E,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAuB;IAChE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,kBAAkB,OAAO,CAAC,MAAM,EAAE,CAAC;IACnE,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;IAEnD,MAAM,OAAO,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAQ,EAAE,EAAE;QAC3C,MAAM,QAAQ,GAAG,CAAC,UAAkB,EAAE,IAAa,EAAE,EAAE;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAClC,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC;YAC5B,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAClD,GAAG,CAAC,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACzD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACpD,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5D,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACtD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACpD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAuB,CAAC;YACnE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YACD,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;gBACtD,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;QACH,CAAC;QAED,IAAI,OAA4B,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAwB,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;QAC7B,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;YAC/B,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACnC,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,SAAS,4BAA4B,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACvF,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC;IAEF,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAEhE,OAAO;QACL,WAAW;QACX,OAAO;QACP,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ export type ReplyPrefixOptions = {
2
+ responsePrefix?: string;
3
+ responsePrefixContextProvider?: () => Record<string, unknown>;
4
+ onModelSelected: (ctx: unknown) => void;
5
+ };
6
+ export declare function createReplyPrefixOptions(_params: {
7
+ cfg: unknown;
8
+ agentId: string;
9
+ channel?: string;
10
+ accountId?: string;
11
+ }): ReplyPrefixOptions;
12
+ //# sourceMappingURL=reply-prefix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply-prefix.d.ts","sourceRoot":"","sources":["../../src/reply-prefix.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9D,eAAe,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,kBAAkB,CAMrB"}
@@ -0,0 +1,8 @@
1
+ export function createReplyPrefixOptions(_params) {
2
+ // At runtime this is replaced by the real openclaw/plugin-sdk implementation.
3
+ // This stub is only used during standalone typecheck/build.
4
+ return {
5
+ onModelSelected: () => { },
6
+ };
7
+ }
8
+ //# sourceMappingURL=reply-prefix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply-prefix.js","sourceRoot":"","sources":["../../src/reply-prefix.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,wBAAwB,CAAC,OAKxC;IACC,8EAA8E;IAC9E,4DAA4D;IAC5D,OAAO;QACL,eAAe,EAAE,GAAG,EAAE,GAAE,CAAC;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ export type AgentRoute = {
2
+ agentId: string;
3
+ accountId: string;
4
+ sessionKey: string;
5
+ };
6
+ export type PluginRuntime = {
7
+ channel: {
8
+ reply: {
9
+ finalizeInboundContext(params: unknown): any;
10
+ dispatchReplyWithBufferedBlockDispatcher(params: unknown): Promise<void>;
11
+ formatAgentEnvelope(params: unknown): string;
12
+ resolveEnvelopeFormatOptions(cfg: unknown): unknown;
13
+ };
14
+ session: {
15
+ recordInboundSession(params: {
16
+ storePath: string;
17
+ sessionKey: string;
18
+ ctx: unknown;
19
+ onRecordError: (err: unknown) => void;
20
+ }): Promise<void>;
21
+ resolveStorePath(store: unknown, params: {
22
+ agentId: string;
23
+ }): string;
24
+ readSessionUpdatedAt(params: {
25
+ storePath: string;
26
+ sessionKey: string;
27
+ }): number | undefined;
28
+ };
29
+ routing: {
30
+ resolveAgentRoute(params: {
31
+ cfg: unknown;
32
+ channel: string;
33
+ accountId: string;
34
+ peer: {
35
+ kind: "direct" | "group";
36
+ id: string;
37
+ };
38
+ }): AgentRoute;
39
+ };
40
+ chat: {
41
+ /** Inject a message into a session transcript without triggering agent inference. */
42
+ inject(params: {
43
+ sessionKey: string;
44
+ message: string;
45
+ label?: string;
46
+ }): Promise<{
47
+ ok: boolean;
48
+ messageId?: string;
49
+ }>;
50
+ };
51
+ };
52
+ };
53
+ export declare function setAmikoRuntime(next: PluginRuntime): void;
54
+ export declare function getAmikoRuntime(): PluginRuntime;
55
+ export declare function setWebhookDispatcher(path: string, handler: ((req: any, res: any) => Promise<void> | void) | null): void;
56
+ export declare function dispatchWebhookRequest(req: any, res: any): Promise<boolean>;
57
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE;QACP,KAAK,EAAE;YACL,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,GAAG,CAAC;YAC7C,wCAAwC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACzE,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;YAC7C,4BAA4B,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;SACrD,CAAC;QACF,OAAO,EAAE;YACP,oBAAoB,CAAC,MAAM,EAAE;gBAC3B,SAAS,EAAE,MAAM,CAAC;gBAClB,UAAU,EAAE,MAAM,CAAC;gBACnB,GAAG,EAAE,OAAO,CAAC;gBACb,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;aACvC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAA;aAAE,GAAG,MAAM,CAAC;YACtE,oBAAoB,CAAC,MAAM,EAAE;gBAAE,SAAS,EAAE,MAAM,CAAC;gBAAC,UAAU,EAAE,MAAM,CAAA;aAAE,GAAG,MAAM,GAAG,SAAS,CAAC;SAC7F,CAAC;QACF,OAAO,EAAE;YACP,iBAAiB,CAAC,MAAM,EAAE;gBACxB,GAAG,EAAE,OAAO,CAAC;gBACb,OAAO,EAAE,MAAM,CAAC;gBAChB,SAAS,EAAE,MAAM,CAAC;gBAClB,IAAI,EAAE;oBAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;oBAAC,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;aAChD,GAAG,UAAU,CAAC;SAChB,CAAC;QACF,IAAI,EAAE;YACJ,qFAAqF;YACrF,MAAM,CAAC,MAAM,EAAE;gBACb,UAAU,EAAE,MAAM,CAAC;gBACnB,OAAO,EAAE,MAAM,CAAC;gBAChB,KAAK,CAAC,EAAE,MAAM,CAAC;aAChB,GAAG,OAAO,CAAC;gBAAE,EAAE,EAAE,OAAO,CAAC;gBAAC,SAAS,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAClD,CAAC;KACH,CAAC;CACH,CAAC;AAKF,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAEzD;AAED,wBAAgB,eAAe,IAAI,aAAa,CAG/C;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,GAC7D,IAAI,CAON;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAMjF"}
@@ -0,0 +1,28 @@
1
+ let runtime = null;
2
+ const webhookDispatchers = new Map();
3
+ export function setAmikoRuntime(next) {
4
+ runtime = next;
5
+ }
6
+ export function getAmikoRuntime() {
7
+ if (!runtime)
8
+ throw new Error("Amiko runtime not initialized");
9
+ return runtime;
10
+ }
11
+ export function setWebhookDispatcher(path, handler) {
12
+ if (!path)
13
+ return;
14
+ if (!handler) {
15
+ webhookDispatchers.delete(path);
16
+ return;
17
+ }
18
+ webhookDispatchers.set(path, handler);
19
+ }
20
+ export async function dispatchWebhookRequest(req, res) {
21
+ const pathname = new URL(req.url ?? "/", "http://localhost").pathname;
22
+ const handler = webhookDispatchers.get(pathname);
23
+ if (!handler)
24
+ return false;
25
+ await handler(req, res);
26
+ return true;
27
+ }
28
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AA2CA,IAAI,OAAO,GAAyB,IAAI,CAAC;AACzC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAwD,CAAC;AAE3F,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,OAA8D;IAE9D,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAQ,EAAE,GAAQ;IAC7D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;IACtE,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ResolvedAmikoAccount, AmikoSendResult } from "./types.js";
2
+ export declare function sendTextAmiko(conversationId: string, text: string, account: ResolvedAmikoAccount, options?: {
3
+ replyMode?: "as_owner" | "as_agent";
4
+ }): Promise<AmikoSendResult>;
5
+ export declare function sendMediaAmiko(conversationId: string, text: string, mediaUrl: string, mediaCaption: string | undefined, account: ResolvedAmikoAccount, options?: {
6
+ replyMode?: "as_owner" | "as_agent";
7
+ }): Promise<AmikoSendResult>;
8
+ //# sourceMappingURL=send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/send.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGxE,wBAAsB,aAAa,CACjC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,GAChD,OAAO,CAAC,eAAe,CAAC,CAwB1B;AAED,wBAAsB,cAAc,CAClC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,GAChD,OAAO,CAAC,eAAe,CAAC,CA0B1B"}
@@ -0,0 +1,51 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { sendAmikoOutbound, AmikoApiError } from "./api.js";
3
+ export async function sendTextAmiko(conversationId, text, account, options) {
4
+ const idempotencyKey = `${account.twinId}:${conversationId}:${randomUUID()}`;
5
+ try {
6
+ const res = await sendAmikoOutbound({ chatApiBaseUrl: account.chatApiBaseUrl, token: account.token, timeoutMs: 30_000 }, {
7
+ accountId: account.twinId,
8
+ conversationId,
9
+ idempotencyKey,
10
+ type: "text",
11
+ text,
12
+ replyMode: options?.replyMode,
13
+ });
14
+ if (!res.ok) {
15
+ return { ok: false, retriable: res.retriable ?? false, error: res.error ?? "Unknown error" };
16
+ }
17
+ return { ok: true, messageId: res.messageId };
18
+ }
19
+ catch (err) {
20
+ if (err instanceof AmikoApiError) {
21
+ return { ok: false, retriable: err.retriable, error: err.message };
22
+ }
23
+ return { ok: false, retriable: false, error: String(err) };
24
+ }
25
+ }
26
+ export async function sendMediaAmiko(conversationId, text, mediaUrl, mediaCaption, account, options) {
27
+ const idempotencyKey = `${account.twinId}:${conversationId}:${randomUUID()}`;
28
+ try {
29
+ const res = await sendAmikoOutbound({ chatApiBaseUrl: account.chatApiBaseUrl, token: account.token, timeoutMs: 30_000 }, {
30
+ accountId: account.twinId,
31
+ conversationId,
32
+ idempotencyKey,
33
+ type: "media",
34
+ text,
35
+ mediaUrl,
36
+ mediaCaption,
37
+ replyMode: options?.replyMode,
38
+ });
39
+ if (!res.ok) {
40
+ return { ok: false, retriable: res.retriable ?? false, error: res.error ?? "Unknown error" };
41
+ }
42
+ return { ok: true, messageId: res.messageId };
43
+ }
44
+ catch (err) {
45
+ if (err instanceof AmikoApiError) {
46
+ return { ok: false, retriable: err.retriable, error: err.message };
47
+ }
48
+ return { ok: false, retriable: false, error: String(err) };
49
+ }
50
+ }
51
+ //# sourceMappingURL=send.js.map