@agentmbox/plugin-agentmbox 1.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,811 @@
1
+ // src/index.ts
2
+ import { logger as logger4 } from "@elizaos/core";
3
+
4
+ // src/services/AgentMBoxService.ts
5
+ import { Service, logger as logger2 } from "@elizaos/core";
6
+
7
+ // src/types/index.ts
8
+ function isAgentMBoxError(response) {
9
+ return typeof response === "object" && response !== null && "error" in response && typeof response.error === "string";
10
+ }
11
+
12
+ // src/services/AgentMBoxService.ts
13
+ var AgentMBoxService = class _AgentMBoxService extends Service {
14
+ apiKey = "";
15
+ mailbox;
16
+ baseUrl = "https://agentmbox.com/api/v1";
17
+ static serviceName = "agentmbox";
18
+ constructor(runtime) {
19
+ super(runtime);
20
+ }
21
+ get serviceName() {
22
+ return _AgentMBoxService.serviceName;
23
+ }
24
+ get capabilityDescription() {
25
+ return "AgentMBox email service - allows sending and receiving emails";
26
+ }
27
+ async initialize(runtime) {
28
+ const apiKey = String(runtime.getSetting("AGENTMBOX_API_KEY") || "");
29
+ const mailbox = String(runtime.getSetting("AGENTMBOX_MAILBOX") || "");
30
+ const baseUrl = String(runtime.getSetting("AGENTMBOX_BASE_URL") || "");
31
+ if (!apiKey) {
32
+ throw new Error(
33
+ "AGENTMBOX_API_KEY is required. Get your API key from https://agentmbox.com"
34
+ );
35
+ }
36
+ const agentName = runtime.character?.name?.toLowerCase().replace(/\s+/g, "-") || "agent";
37
+ const defaultMailbox = mailbox || `${agentName}@agentmbox.com`;
38
+ this.apiKey = apiKey;
39
+ this.mailbox = defaultMailbox;
40
+ this.baseUrl = baseUrl || "https://agentmbox.com/api/v1";
41
+ this.runtime = runtime;
42
+ if (!this.apiKey.startsWith("ai_")) {
43
+ logger2.warn("AgentMBox API key should start with 'ai_'");
44
+ }
45
+ logger2.info("AgentMBox service initialized for: " + this.mailbox);
46
+ }
47
+ async stop() {
48
+ logger2.info("AgentMBox service stopped");
49
+ }
50
+ async request(endpoint, options = {}) {
51
+ const url = `${this.baseUrl}${endpoint}`;
52
+ const headers = {
53
+ Authorization: `Bearer ${this.apiKey}`,
54
+ "Content-Type": "application/json",
55
+ ...options.headers
56
+ };
57
+ const response = await fetch(url, { ...options, headers });
58
+ const data = await response.json();
59
+ if (!response.ok) {
60
+ if (isAgentMBoxError(data)) {
61
+ throw new Error(`AgentMBox API error (${response.status}): ${data.error}`);
62
+ }
63
+ throw new Error(`AgentMBox API error: ${response.status}`);
64
+ }
65
+ return data;
66
+ }
67
+ getMailboxParam() {
68
+ if (!this.mailbox) {
69
+ throw new Error("Mailbox not configured");
70
+ }
71
+ return "?mailbox=" + encodeURIComponent(this.mailbox);
72
+ }
73
+ async listEmails(limit = 50, offset = 0) {
74
+ const mailboxParam = this.getMailboxParam();
75
+ return this.request("/mail" + mailboxParam + "&limit=" + limit + "&offset=" + offset);
76
+ }
77
+ async getEmail(emailId) {
78
+ const mailboxParam = this.getMailboxParam();
79
+ return this.request("/mail/" + emailId + mailboxParam);
80
+ }
81
+ async sendEmail(request) {
82
+ const from = request.from || this.mailbox;
83
+ if (!from) {
84
+ throw new Error("Sender address not specified");
85
+ }
86
+ return this.request("/mail/send", {
87
+ method: "POST",
88
+ body: JSON.stringify({ ...request, from })
89
+ });
90
+ }
91
+ async deleteEmail(emailId) {
92
+ const mailboxParam = this.getMailboxParam();
93
+ return this.request("/mail/" + emailId + mailboxParam, {
94
+ method: "DELETE"
95
+ });
96
+ }
97
+ async listMailboxes() {
98
+ return this.request("/mailboxes");
99
+ }
100
+ async createMailbox(request) {
101
+ return this.request("/mailboxes", {
102
+ method: "POST",
103
+ body: JSON.stringify(request)
104
+ });
105
+ }
106
+ async deleteMailbox(mailboxId) {
107
+ return this.request("/mailboxes/" + mailboxId, {
108
+ method: "DELETE"
109
+ });
110
+ }
111
+ async getPaymentStatus() {
112
+ return this.request("/payment");
113
+ }
114
+ async checkPayment() {
115
+ return this.request("/payment/check", {
116
+ method: "POST"
117
+ });
118
+ }
119
+ async listDomains() {
120
+ return this.request("/domains");
121
+ }
122
+ async addDomain(domain) {
123
+ return this.request("/domains", {
124
+ method: "POST",
125
+ body: JSON.stringify({ domain })
126
+ });
127
+ }
128
+ async verifyDomain(domainId) {
129
+ return this.request("/domains/" + domainId + "/verify", {
130
+ method: "POST"
131
+ });
132
+ }
133
+ async deleteDomain(domainId) {
134
+ return this.request("/domains/" + domainId, {
135
+ method: "DELETE"
136
+ });
137
+ }
138
+ async createApiKey(name) {
139
+ return this.request("/keys", {
140
+ method: "POST",
141
+ body: JSON.stringify({ name })
142
+ });
143
+ }
144
+ async getStatus() {
145
+ try {
146
+ const status = await this.getPaymentStatus();
147
+ return { paid: status.paid, paidUntil: status.paidUntil };
148
+ } catch (error) {
149
+ logger2.error("Failed to get AgentMBox status");
150
+ return { paid: false, paidUntil: null };
151
+ }
152
+ }
153
+ };
154
+
155
+ // src/services/AgentMBoxOnboardingService.ts
156
+ import { Service as Service2, logger as logger3 } from "@elizaos/core";
157
+ var AgentMBoxOnboardingService = class _AgentMBoxOnboardingService extends Service2 {
158
+ apiKey = "";
159
+ mailbox;
160
+ baseUrl = "https://agentmbox.com/api/v1";
161
+ cfg = null;
162
+ status = { stage: "pending" };
163
+ static serviceName = "agentmbox-onboarding";
164
+ constructor(runtime) {
165
+ super(runtime);
166
+ }
167
+ get serviceName() {
168
+ return _AgentMBoxOnboardingService.serviceName;
169
+ }
170
+ get capabilityDescription() {
171
+ return "AgentMBox autonomous onboarding - creates account, pays for subscription, sets up mailbox";
172
+ }
173
+ getApiKey() {
174
+ return this.apiKey;
175
+ }
176
+ getMailbox() {
177
+ return this.mailbox;
178
+ }
179
+ generatePassword(length = 32) {
180
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
181
+ let password = "";
182
+ const array = new Uint8Array(length);
183
+ crypto.getRandomValues(array);
184
+ for (let i = 0; i < length; i++) {
185
+ password += chars[array[i] % chars.length];
186
+ }
187
+ return password;
188
+ }
189
+ async getAgentWallet() {
190
+ if (!this.runtime) return null;
191
+ try {
192
+ const privateKeyBase58 = String(
193
+ this.runtime.getSetting("SOLANA_PRIVATE_KEY") || ""
194
+ );
195
+ if (privateKeyBase58) {
196
+ const { default: bs58 } = await import("bs58");
197
+ const { Keypair } = await import("@solana/web3.js");
198
+ const privateKey = bs58.decode(privateKeyBase58);
199
+ const keypair = Keypair.fromSecretKey(privateKey);
200
+ return {
201
+ publicKey: keypair.publicKey.toBase58(),
202
+ privateKey
203
+ };
204
+ }
205
+ const walletService = await this.runtime.getService("wallet");
206
+ if (walletService) {
207
+ const keypair = await walletService.getKeypair?.();
208
+ if (keypair) {
209
+ return {
210
+ publicKey: keypair.publicKey.toBase58(),
211
+ privateKey: keypair.secretKey
212
+ };
213
+ }
214
+ }
215
+ } catch (error) {
216
+ logger3.warn("Could not get agent wallet");
217
+ }
218
+ return null;
219
+ }
220
+ async request(endpoint, options = {}) {
221
+ const url = `${this.baseUrl}${endpoint}`;
222
+ const headers = {
223
+ "Content-Type": "application/json",
224
+ ...options.headers
225
+ };
226
+ const response = await fetch(url, { ...options, headers });
227
+ const data = await response.json();
228
+ if (!response.ok) {
229
+ const error = data.error || `${response.status}`;
230
+ throw new Error(error);
231
+ }
232
+ return data;
233
+ }
234
+ async authenticatedRequest(endpoint, options = {}) {
235
+ if (!this.apiKey) {
236
+ throw new Error("API key not set");
237
+ }
238
+ const url = `${this.baseUrl}${endpoint}`;
239
+ const headers = {
240
+ Authorization: `Bearer ${this.apiKey}`,
241
+ "Content-Type": "application/json",
242
+ ...options.headers
243
+ };
244
+ const response = await fetch(url, { ...options, headers });
245
+ const data = await response.json();
246
+ if (!response.ok) {
247
+ const error = data.error || `${response.status}`;
248
+ throw new Error(error);
249
+ }
250
+ return data;
251
+ }
252
+ async startOnboarding(runtime) {
253
+ this.runtime = runtime;
254
+ const existingApiKey = String(
255
+ runtime.getSetting("AGENTMBOX_API_KEY") || ""
256
+ );
257
+ if (existingApiKey && existingApiKey.startsWith("ai_")) {
258
+ this.apiKey = existingApiKey;
259
+ return await this.checkExistingSetup();
260
+ }
261
+ const agentName = runtime.character?.name?.toLowerCase().replace(/\s+/g, "-") || "agent";
262
+ const mailboxSetting = String(
263
+ runtime.getSetting("AGENTMBOX_MAILBOX") || ""
264
+ );
265
+ this.cfg = {
266
+ ownerEmail: String(runtime.getSetting("AGENTMBOX_OWNER_EMAIL")) || `agent-${agentName}@owner.local`,
267
+ password: this.generatePassword(32),
268
+ mailboxLocalPart: mailboxSetting ? mailboxSetting.split("@")[0] : agentName
269
+ };
270
+ try {
271
+ await this.createAccount();
272
+ this.status = { stage: "account_created" };
273
+ logger3.info("AgentMBox account created");
274
+ const apiKeyResponse = await this.createApiKey(agentName);
275
+ this.apiKey = apiKeyResponse.key;
276
+ this.status = { stage: "api_key_created" };
277
+ logger3.info("AgentMBox API key created");
278
+ const payment = await this.getPaymentStatus();
279
+ this.status = {
280
+ stage: "awaiting_payment",
281
+ paymentAddress: payment.solanaAddress
282
+ };
283
+ logger3.info("Payment address: " + payment.solanaAddress);
284
+ await this.payForSubscription(payment.solanaAddress, runtime);
285
+ this.status = { stage: "paid" };
286
+ logger3.info("Payment completed");
287
+ const mailbox = await this.createMailbox(this.cfg.mailboxLocalPart);
288
+ this.mailbox = mailbox.address;
289
+ this.status = {
290
+ stage: "complete",
291
+ mailbox: mailbox.address
292
+ };
293
+ logger3.info("Mailbox created: " + mailbox.address);
294
+ return this.status;
295
+ } catch (error) {
296
+ const errorMsg = error instanceof Error ? error.message : "Unknown error";
297
+ logger3.error("AgentMBox onboarding failed: " + errorMsg);
298
+ this.status = { stage: "error", error: errorMsg };
299
+ throw error;
300
+ }
301
+ }
302
+ async checkExistingSetup() {
303
+ try {
304
+ const payment = await this.getPaymentStatus();
305
+ if (payment.paid) {
306
+ const mailbox = await this.getOrCreateMailbox();
307
+ this.status = mailbox ? { stage: "complete", mailbox: mailbox.address } : { stage: "paid" };
308
+ } else {
309
+ const wallet = await this.getAgentWallet();
310
+ if (wallet && this.runtime) {
311
+ await this.payForSubscription(payment.solanaAddress, this.runtime);
312
+ this.status = { stage: "paid" };
313
+ const mailbox = await this.getOrCreateMailbox();
314
+ if (mailbox) {
315
+ this.status = { stage: "complete", mailbox: mailbox.address };
316
+ }
317
+ } else {
318
+ this.status = {
319
+ stage: "awaiting_payment",
320
+ paymentAddress: payment.solanaAddress
321
+ };
322
+ }
323
+ }
324
+ } catch (error) {
325
+ logger3.warn("Could not check existing setup");
326
+ this.status = { stage: "pending" };
327
+ }
328
+ return this.status;
329
+ }
330
+ async payForSubscription(paymentAddress, runtime) {
331
+ const wallet = await this.getAgentWallet();
332
+ if (!wallet) {
333
+ logger3.warn("No agent wallet found, waiting for manual payment");
334
+ await this.waitForPayment();
335
+ return;
336
+ }
337
+ logger3.info("Using agent wallet to pay for subscription");
338
+ try {
339
+ const { Connection, Keypair } = await import("@solana/web3.js");
340
+ const { transfer, getOrCreateAssociatedTokenAccount } = await import("@solana/spl-token");
341
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
342
+ const signer = Keypair.fromSecretKey(wallet.privateKey);
343
+ const usdcMintStr = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGZwyTDt1v";
344
+ const { PublicKey } = await import("@solana/web3.js");
345
+ const usdcMint = new PublicKey(usdcMintStr);
346
+ const toPublicKey = new PublicKey(paymentAddress);
347
+ const fromTokenAccount = await getOrCreateAssociatedTokenAccount(
348
+ connection,
349
+ signer,
350
+ usdcMint,
351
+ signer.publicKey
352
+ );
353
+ const toTokenAccount = await getOrCreateAssociatedTokenAccount(
354
+ connection,
355
+ signer,
356
+ usdcMint,
357
+ toPublicKey
358
+ );
359
+ const amount = 5e6;
360
+ await transfer(
361
+ connection,
362
+ signer,
363
+ fromTokenAccount.address,
364
+ toTokenAccount.address,
365
+ signer.publicKey,
366
+ amount
367
+ );
368
+ logger3.info("USDC transfer complete");
369
+ await this.waitForPayment();
370
+ } catch (error) {
371
+ logger3.error("Failed to transfer USDC, waiting for manual payment");
372
+ await this.waitForPayment();
373
+ }
374
+ }
375
+ async stop() {
376
+ logger3.info("AgentMBox onboarding service stopped");
377
+ }
378
+ async createAccount() {
379
+ if (!this.cfg) throw new Error("Config not set");
380
+ const response = await this.request("/auth/signup", {
381
+ method: "POST",
382
+ body: JSON.stringify({
383
+ email: this.cfg.ownerEmail,
384
+ password: this.cfg.password
385
+ })
386
+ });
387
+ logger3.info("Account created: " + response.id);
388
+ }
389
+ async createApiKey(name) {
390
+ const response = await this.request("/keys", {
391
+ method: "POST",
392
+ body: JSON.stringify({ name })
393
+ });
394
+ logger3.info("API key created: " + response.key.substring(0, 12) + "...");
395
+ return response;
396
+ }
397
+ async getPaymentStatus() {
398
+ return this.authenticatedRequest("/payment");
399
+ }
400
+ async waitForPayment(maxAttempts = 60, intervalMs = 5e3) {
401
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
402
+ try {
403
+ const result = await this.authenticatedRequest(
404
+ "/payment/check",
405
+ {
406
+ method: "POST"
407
+ }
408
+ );
409
+ if (result.paid) {
410
+ return result;
411
+ }
412
+ logger3.info(
413
+ "Waiting for payment... (" + attempt + "/" + maxAttempts + ")"
414
+ );
415
+ } catch (e) {
416
+ logger3.warn(
417
+ "Payment check failed: " + (e instanceof Error ? e.message : "unknown")
418
+ );
419
+ }
420
+ if (attempt < maxAttempts) {
421
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
422
+ }
423
+ }
424
+ throw new Error("Payment not received after " + maxAttempts + " attempts");
425
+ }
426
+ async createMailbox(localPart) {
427
+ const response = await this.authenticatedRequest(
428
+ "/mailboxes",
429
+ {
430
+ method: "POST",
431
+ body: JSON.stringify({
432
+ localPart,
433
+ displayName: this.cfg?.mailboxLocalPart || "Agent Mailbox"
434
+ })
435
+ }
436
+ );
437
+ return response.mailbox;
438
+ }
439
+ async getOrCreateMailbox() {
440
+ try {
441
+ const response = await this.authenticatedRequest("/mailboxes");
442
+ if (response.mailboxes.length > 0) {
443
+ return response.mailboxes[0];
444
+ }
445
+ if (this.cfg?.mailboxLocalPart) {
446
+ return await this.createMailbox(this.cfg.mailboxLocalPart);
447
+ }
448
+ return null;
449
+ } catch (error) {
450
+ logger3.error("Failed to get/create mailbox");
451
+ return null;
452
+ }
453
+ }
454
+ getStatus() {
455
+ return this.status;
456
+ }
457
+ async getPaymentAddress() {
458
+ if (this.status.paymentAddress) {
459
+ return this.status.paymentAddress;
460
+ }
461
+ try {
462
+ const payment = await this.getPaymentStatus();
463
+ return payment.solanaAddress;
464
+ } catch {
465
+ return null;
466
+ }
467
+ }
468
+ isOnboardingComplete() {
469
+ return this.status.stage === "complete";
470
+ }
471
+ };
472
+
473
+ // src/actions/sendEmail.ts
474
+ var sendEmailAction = {
475
+ name: "SEND_EMAIL",
476
+ description: "Send an email to a recipient using AgentMBox email service",
477
+ handler: async (runtime, message, state, options, callback) => {
478
+ const service = runtime.getService("agentmbox");
479
+ if (!service) {
480
+ throw new Error("AgentMBox service not initialized");
481
+ }
482
+ const { to, subject, text, html } = options;
483
+ if (!to) {
484
+ throw new Error("Missing required field: 'to' (recipient email)");
485
+ }
486
+ if (!subject) {
487
+ throw new Error("Missing required field: 'subject'");
488
+ }
489
+ const from = options.from;
490
+ try {
491
+ const result = await service.sendEmail({
492
+ from,
493
+ to: Array.isArray(to) ? to : to,
494
+ subject,
495
+ text,
496
+ html
497
+ });
498
+ if (callback) {
499
+ await callback({
500
+ text: `Email sent successfully to ${to}`,
501
+ values: {
502
+ success: result.success,
503
+ recipient: to,
504
+ subject
505
+ }
506
+ });
507
+ }
508
+ return {
509
+ success: true,
510
+ values: {
511
+ sentTo: to,
512
+ subject
513
+ }
514
+ };
515
+ } catch (error) {
516
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
517
+ logger.error("Failed to send email", { error: errorMessage });
518
+ if (callback) {
519
+ await callback({
520
+ text: `Failed to send email: ${errorMessage}`,
521
+ values: {
522
+ success: false,
523
+ error: errorMessage
524
+ }
525
+ });
526
+ }
527
+ return {
528
+ success: false,
529
+ error: errorMessage
530
+ };
531
+ }
532
+ },
533
+ validate: async (runtime) => {
534
+ try {
535
+ const service = runtime.getService("agentmbox");
536
+ return !!service;
537
+ } catch {
538
+ return false;
539
+ }
540
+ },
541
+ examples: [
542
+ [
543
+ {
544
+ name: "user",
545
+ content: "Send an email to john@example.com about the project update"
546
+ },
547
+ {
548
+ name: "assistant",
549
+ content: "I'll send that email for you."
550
+ }
551
+ ],
552
+ [
553
+ {
554
+ name: "user",
555
+ content: "Email the team that the meeting is at 3pm"
556
+ },
557
+ {
558
+ name: "assistant",
559
+ content: "Sending that email now."
560
+ }
561
+ ],
562
+ [
563
+ {
564
+ name: "user",
565
+ content: "Can you notify alice@example.com that the report is ready?"
566
+ },
567
+ {
568
+ name: "assistant",
569
+ content: "I'll send her an email right away."
570
+ }
571
+ ]
572
+ ]
573
+ };
574
+
575
+ // src/actions/getEmails.ts
576
+ var getEmailsAction = {
577
+ name: "GET_EMAILS",
578
+ description: "Retrieve emails from the AgentMBox mailbox. Can filter by read status and limit results.",
579
+ handler: async (runtime, message, state, options, callback) => {
580
+ const service = runtime.getService("agentmbox");
581
+ if (!service) {
582
+ throw new Error("AgentMBox service not initialized");
583
+ }
584
+ const limit = options.limit || 10;
585
+ const offset = options.offset || 0;
586
+ const emailId = options.emailId;
587
+ try {
588
+ if (emailId) {
589
+ const emailDetail = await service.getEmail(emailId);
590
+ if (callback) {
591
+ await callback({
592
+ text: `Retrieved email: ${emailDetail.email.subject}`,
593
+ values: {
594
+ email: emailDetail.email
595
+ }
596
+ });
597
+ }
598
+ return {
599
+ success: true,
600
+ values: {
601
+ email: emailDetail.email
602
+ }
603
+ };
604
+ }
605
+ const emailList = await service.listEmails(limit, offset);
606
+ let emails = emailList.emails;
607
+ const unreadOnly = options.unreadOnly;
608
+ if (unreadOnly) {
609
+ emails = emails.filter((email) => !email.isRead);
610
+ }
611
+ if (callback) {
612
+ const preview = emails.slice(0, 5).map((e) => `- ${e.subject} from ${e.from[0]?.email}`).join("\n");
613
+ await callback({
614
+ text: `Found ${emails.length} emails:
615
+ ${preview}`,
616
+ values: {
617
+ emails,
618
+ total: emailList.emails.length,
619
+ unread: emailList.emails.filter((e) => !e.isRead).length
620
+ }
621
+ });
622
+ }
623
+ return {
624
+ success: true,
625
+ values: {
626
+ emails,
627
+ total: emailList.emails.length,
628
+ limit: emailList.limit,
629
+ offset: emailList.offset
630
+ }
631
+ };
632
+ } catch (error) {
633
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
634
+ logger.error("Failed to get emails", { error: errorMessage });
635
+ if (callback) {
636
+ await callback({
637
+ text: `Failed to get emails: ${errorMessage}`,
638
+ values: {
639
+ success: false,
640
+ error: errorMessage
641
+ }
642
+ });
643
+ }
644
+ return {
645
+ success: false,
646
+ error: errorMessage
647
+ };
648
+ }
649
+ },
650
+ validate: async (runtime) => {
651
+ try {
652
+ const service = runtime.getService("agentmbox");
653
+ return !!service;
654
+ } catch {
655
+ return false;
656
+ }
657
+ },
658
+ examples: [
659
+ [
660
+ {
661
+ name: "user",
662
+ content: "Check my inbox for any new emails"
663
+ },
664
+ {
665
+ name: "assistant",
666
+ content: "Let me check your inbox for new emails."
667
+ }
668
+ ],
669
+ [
670
+ {
671
+ name: "user",
672
+ content: "Show me the last 5 emails I received"
673
+ },
674
+ {
675
+ name: "assistant",
676
+ content: "I'll retrieve your recent emails."
677
+ }
678
+ ],
679
+ [
680
+ {
681
+ name: "user",
682
+ content: "Get the details of that email about the meeting"
683
+ },
684
+ {
685
+ name: "assistant",
686
+ content: "Let me fetch that email for you."
687
+ }
688
+ ]
689
+ ]
690
+ };
691
+
692
+ // src/providers/emailProvider.ts
693
+ var emailProvider = {
694
+ name: "email",
695
+ description: "Provides email context from AgentMBox including unread counts and recent messages",
696
+ get: async (runtime, message, _state) => {
697
+ try {
698
+ const service = runtime.getService("agentmbox");
699
+ if (!service) {
700
+ return {
701
+ text: "Email service not available",
702
+ values: {
703
+ available: false
704
+ }
705
+ };
706
+ }
707
+ const emailList = await service.listEmails(10, 0);
708
+ const unreadCount = emailList.emails.filter((e) => !e.isRead).length;
709
+ const recentEmails = emailList.emails.slice(0, 5);
710
+ const recentEmailsText = recentEmails.map(
711
+ (email) => `- From: ${email.from[0]?.name || email.from[0]?.email || "Unknown"} | Subject: ${email.subject}${!email.isRead ? " [UNREAD]" : ""}`
712
+ ).join("\n");
713
+ return {
714
+ text: `Email Status: ${unreadCount} unread of ${emailList.emails.length} total${recentEmails.length > 0 ? `
715
+
716
+ Recent Emails:
717
+ ${recentEmailsText}` : "\n\nNo recent emails."}`,
718
+ values: {
719
+ available: true,
720
+ unreadCount,
721
+ totalEmails: emailList.emails.length,
722
+ recentEmails: recentEmails.map((e) => ({
723
+ id: e.id,
724
+ from: e.from[0],
725
+ subject: e.subject,
726
+ preview: e.preview,
727
+ isRead: e.isRead,
728
+ receivedAt: e.receivedAt
729
+ }))
730
+ }
731
+ };
732
+ } catch (error) {
733
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
734
+ return {
735
+ text: `Email service error: ${errorMessage}`,
736
+ values: {
737
+ available: false,
738
+ error: errorMessage
739
+ }
740
+ };
741
+ }
742
+ }
743
+ };
744
+
745
+ // src/index.ts
746
+ var agentMBoxPlugin = {
747
+ name: "agentmbox",
748
+ description: "AgentMBox email integration plugin for ElizaOS - enables AI agents to send/receive emails with autonomous onboarding",
749
+ actions: [sendEmailAction, getEmailsAction],
750
+ providers: [emailProvider],
751
+ services: [AgentMBoxService, AgentMBoxOnboardingService],
752
+ init: async (config, runtime) => {
753
+ logger4.info("AgentMBox plugin initializing");
754
+ const existingApiKey = runtime.getSetting("AGENTMBOX_API_KEY");
755
+ const skipOnboarding = runtime.getSetting("AGENTMBOX_SKIP_ONBOARDING") === "true";
756
+ if (!existingApiKey && !skipOnboarding) {
757
+ logger4.info("Starting AgentMBox autonomous onboarding...");
758
+ try {
759
+ const onboardingService = runtime.getService(
760
+ "agentmbox-onboarding"
761
+ );
762
+ if (onboardingService) {
763
+ const status = await onboardingService.startOnboarding(runtime);
764
+ if (status.stage === "complete" && status.mailbox) {
765
+ const apiKey = onboardingService.getApiKey();
766
+ const mailbox = onboardingService.getMailbox();
767
+ if (apiKey) {
768
+ runtime.setSetting("AGENTMBOX_API_KEY", apiKey, true);
769
+ }
770
+ if (mailbox) {
771
+ runtime.setSetting("AGENTMBOX_MAILBOX", mailbox);
772
+ }
773
+ logger4.info("Onboarding complete! Mailbox: " + status.mailbox);
774
+ } else if (status.stage === "awaiting_payment" && status.paymentAddress) {
775
+ logger4.warn(
776
+ "Payment required. Please fund: " + status.paymentAddress
777
+ );
778
+ logger4.info("Required: 5 USDC on Solana + ~0.01 SOL for fees");
779
+ }
780
+ }
781
+ } catch (error) {
782
+ const errorMsg = error instanceof Error ? error.message : "Unknown error";
783
+ logger4.error("Onboarding failed: " + errorMsg);
784
+ }
785
+ } else if (existingApiKey) {
786
+ logger4.info("Using existing AgentMBox configuration");
787
+ } else {
788
+ logger4.info("Onboarding skipped per configuration");
789
+ }
790
+ const emailService = runtime.getService("agentmbox");
791
+ if (emailService) {
792
+ try {
793
+ await emailService.initialize(runtime);
794
+ } catch (error) {
795
+ const errorMsg = error instanceof Error ? error.message : "Unknown error";
796
+ logger4.error(
797
+ "Failed to initialize AgentMBox email service: " + errorMsg
798
+ );
799
+ }
800
+ }
801
+ }
802
+ };
803
+ var index_default = agentMBoxPlugin;
804
+ export {
805
+ AgentMBoxOnboardingService,
806
+ AgentMBoxService,
807
+ agentMBoxPlugin,
808
+ index_default as default,
809
+ isAgentMBoxError
810
+ };
811
+ //# sourceMappingURL=index.js.map