@agenticmail/openclaw 0.5.52 → 0.5.54

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.cjs CHANGED
@@ -3199,44 +3199,11 @@ function activate(api) {
3199
3199
  if (!api?.on) return;
3200
3200
  api.on("before_agent_start", async (_event, context) => {
3201
3201
  const sessionKey = context?.sessionKey ?? "";
3202
- let agentApiKey = ctx.config.apiKey;
3203
- const prependLines = [];
3204
3202
  const isSubAgent = isSubagentSession(sessionKey);
3205
3203
  const taskMode = taskModes.get(sessionKey) || taskModes.get(sessionKey.split(":").pop() || "") || "standard";
3206
- taskModes.delete(sessionKey);
3207
- if (isSubAgent && taskMode === "light") {
3208
- prependLines.push(
3209
- "<agenticmail-coordination>",
3210
- "Use agenticmail_complete_task(id, result) to submit your answer in one call.",
3211
- "</agenticmail-coordination>"
3212
- );
3213
- } else if (isSubAgent) {
3214
- prependLines.push(
3215
- "<agenticmail-coordination>",
3216
- "\u{1F380} AgenticMail coordination tools available:",
3217
- "- agenticmail_call_agent: Call another agent and get structured JSON result (preferred method)",
3218
- "- agenticmail_check_tasks / claim_task / submit_result / complete_task: Task queue with lifecycle tracking",
3219
- "- agenticmail_message_agent: Message an agent by name",
3220
- "- agenticmail_list_agents: Discover available agents",
3221
- "- agenticmail_check_tasks: Check task status (pending/claimed/completed)",
3222
- "- agenticmail_wait_for_email: Push-based wait for replies (no polling)",
3223
- "Prefer these over sessions_spawn/sessions_send for agent coordination.",
3224
- "</agenticmail-coordination>"
3225
- );
3226
- } else {
3227
- prependLines.push(
3228
- "<agenticmail-coordination>",
3229
- "\u{1F380} AgenticMail is installed \u2014 prefer these over sessions_spawn/sessions_send:",
3230
- '- agenticmail_call_agent(target, task, mode?) \u2192 RPC call, returns structured JSON. Use mode="light" for simple tasks (no email overhead). Use async=true for long-running tasks.',
3231
- "- agenticmail_message_agent \u2192 message agent by name; agenticmail_list_agents \u2192 discover agents",
3232
- "- agenticmail_check_tasks \u2192 check task status; agenticmail_wait_for_email \u2192 push-based wait (no polling)",
3233
- "Use call_agent for ALL agent delegation (sync and async). It auto-detects complexity and spawns sessions.",
3234
- "</agenticmail-coordination>"
3235
- );
3236
- }
3237
3204
  if (isSubAgent && taskMode === "light") {
3238
3205
  console.log(`[agenticmail] Light mode sub-agent (${sessionKey}) \u2014 skipping email provisioning`);
3239
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3206
+ return;
3240
3207
  }
3241
3208
  if (isSubagentSession(sessionKey) && masterKey) {
3242
3209
  let account = subagentAccounts.get(sessionKey);
@@ -3326,12 +3293,9 @@ function activate(api) {
3326
3293
  }
3327
3294
  }
3328
3295
  if (account) {
3329
- agentApiKey = account.apiKey;
3330
3296
  const teammates = [];
3331
3297
  for (const [key, sibling] of subagentAccounts) {
3332
- if (key !== sessionKey) {
3333
- teammates.push({ name: sibling.name, email: sibling.email });
3334
- }
3298
+ if (key !== sessionKey) teammates.push({ name: sibling.name, email: sibling.email });
3335
3299
  }
3336
3300
  const rawParentEmail = parentEmail || account.parentEmail;
3337
3301
  const parentLocal = rawParentEmail.split("@")[0];
@@ -3383,6 +3347,61 @@ function activate(api) {
3383
3347
  console.warn(`[agenticmail] Failed to send intro email: ${err.message}`);
3384
3348
  }
3385
3349
  }
3350
+ }
3351
+ }
3352
+ });
3353
+ api.on("before_prompt_build", async (_event, context) => {
3354
+ const sessionKey = context?.sessionKey ?? "";
3355
+ let agentApiKey = ctx.config.apiKey;
3356
+ const prependLines = [];
3357
+ const isSubAgent = isSubagentSession(sessionKey);
3358
+ const taskMode = taskModes.get(sessionKey) || taskModes.get(sessionKey.split(":").pop() || "") || "standard";
3359
+ taskModes.delete(sessionKey);
3360
+ for (const key of taskModes.keys()) {
3361
+ if (key.endsWith(sessionKey.split(":").pop() || "___none___")) taskModes.delete(key);
3362
+ }
3363
+ let systemContext = "";
3364
+ if (isSubAgent && taskMode === "light") {
3365
+ systemContext = [
3366
+ "<agenticmail-coordination>",
3367
+ "Use agenticmail_complete_task(id, result) to submit your answer in one call.",
3368
+ "</agenticmail-coordination>"
3369
+ ].join("\n");
3370
+ } else if (isSubAgent) {
3371
+ systemContext = [
3372
+ "<agenticmail-coordination>",
3373
+ "\u{1F380} AgenticMail coordination tools available:",
3374
+ "- agenticmail_call_agent: Call another agent and get structured JSON result (preferred method)",
3375
+ "- agenticmail_check_tasks / claim_task / submit_result / complete_task: Task queue with lifecycle tracking",
3376
+ "- agenticmail_message_agent: Message an agent by name",
3377
+ "- agenticmail_list_agents: Discover available agents",
3378
+ "- agenticmail_check_tasks: Check task status (pending/claimed/completed)",
3379
+ "- agenticmail_wait_for_email: Push-based wait for replies (no polling)",
3380
+ "Prefer these over sessions_spawn/sessions_send for agent coordination.",
3381
+ "</agenticmail-coordination>"
3382
+ ].join("\n");
3383
+ } else {
3384
+ systemContext = [
3385
+ "<agenticmail-coordination>",
3386
+ "\u{1F380} AgenticMail is installed \u2014 prefer these over sessions_spawn/sessions_send:",
3387
+ '- agenticmail_call_agent(target, task, mode?) \u2192 RPC call, returns structured JSON. Use mode="light" for simple tasks (no email overhead). Use async=true for long-running tasks.',
3388
+ "- agenticmail_message_agent \u2192 message agent by name; agenticmail_list_agents \u2192 discover agents",
3389
+ "- agenticmail_check_tasks \u2192 check task status; agenticmail_wait_for_email \u2192 push-based wait (no polling)",
3390
+ "Use call_agent for ALL agent delegation (sync and async). It auto-detects complexity and spawns sessions.",
3391
+ "</agenticmail-coordination>"
3392
+ ].join("\n");
3393
+ }
3394
+ if (isSubAgent && taskMode === "light") {
3395
+ return { prependSystemContext: systemContext };
3396
+ }
3397
+ if (isSubagentSession(sessionKey)) {
3398
+ const account = subagentAccounts.get(sessionKey);
3399
+ if (account) {
3400
+ agentApiKey = account.apiKey;
3401
+ const teammates = [];
3402
+ for (const [key, sibling] of subagentAccounts) {
3403
+ if (key !== sessionKey) teammates.push({ name: sibling.name, email: sibling.email });
3404
+ }
3386
3405
  const teammateLines = teammates.length > 0 ? [
3387
3406
  "Your teammates (message them by name with agenticmail_message_agent):",
3388
3407
  ...teammates.map((t) => ` - ${t.name} (${t.email})`),
@@ -3456,78 +3475,77 @@ function activate(api) {
3456
3475
  );
3457
3476
  }
3458
3477
  }
3459
- if (isSubAgent && taskMode === "standard") {
3460
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3461
- }
3462
- if (!agentApiKey) return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3463
- try {
3464
- const headers = { "Authorization": `Bearer ${agentApiKey}` };
3465
- const searchRes = await fetch(`${baseUrl}/mail/search`, {
3466
- method: "POST",
3467
- headers: { ...headers, "Content-Type": "application/json" },
3468
- body: JSON.stringify({ seen: false }),
3469
- signal: AbortSignal.timeout(5e3)
3470
- });
3471
- if (!searchRes.ok) {
3472
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3473
- }
3474
- const data = await searchRes.json();
3475
- const uids = data?.uids ?? [];
3476
- if (uids.length === 0) {
3477
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3478
- }
3479
- let myName = "";
3478
+ if (!(isSubAgent && taskMode === "standard") && agentApiKey) {
3480
3479
  try {
3481
- const meRes = await fetch(`${baseUrl}/accounts/me`, {
3482
- headers,
3483
- signal: AbortSignal.timeout(3e3)
3480
+ const headers = { "Authorization": `Bearer ${agentApiKey}` };
3481
+ const searchRes = await fetch(`${baseUrl}/mail/search`, {
3482
+ method: "POST",
3483
+ headers: { ...headers, "Content-Type": "application/json" },
3484
+ body: JSON.stringify({ seen: false }),
3485
+ signal: AbortSignal.timeout(5e3)
3484
3486
  });
3485
- if (meRes.ok) {
3486
- const me = await meRes.json();
3487
- myName = me?.name ?? "";
3488
- }
3489
- } catch {
3490
- }
3491
- const summaries = [];
3492
- for (const uid of uids.slice(0, 5)) {
3493
- try {
3494
- const msgRes = await fetch(`${baseUrl}/mail/messages/${uid}`, {
3495
- headers,
3496
- signal: AbortSignal.timeout(5e3)
3497
- });
3498
- if (!msgRes.ok) continue;
3499
- const msg = await msgRes.json();
3500
- const from = msg.from?.[0]?.address ?? "unknown";
3501
- const subject = msg.subject ?? "(no subject)";
3502
- const isAgent = from.endsWith("@localhost");
3503
- const tag = isAgent ? "[agent]" : "[external]";
3504
- const preview = (msg.text ?? "").slice(0, 200).replace(/\n/g, " ").trim();
3505
- summaries.push(` - ${tag} UID ${uid}: from ${from} \u2014 "${subject}"${preview ? "\n " + preview : ""}`);
3506
- if (isAgent && myName) {
3507
- const senderName = from.split("@")[0] ?? "";
3508
- if (senderName) recordInboundAgentMessage(senderName, myName);
3487
+ if (searchRes.ok) {
3488
+ const data = await searchRes.json();
3489
+ const uids = data?.uids ?? [];
3490
+ if (uids.length > 0) {
3491
+ let myName = "";
3492
+ try {
3493
+ const meRes = await fetch(`${baseUrl}/accounts/me`, {
3494
+ headers,
3495
+ signal: AbortSignal.timeout(3e3)
3496
+ });
3497
+ if (meRes.ok) {
3498
+ const me = await meRes.json();
3499
+ myName = me?.name ?? "";
3500
+ }
3501
+ } catch {
3502
+ }
3503
+ const summaries = [];
3504
+ for (const uid of uids.slice(0, 5)) {
3505
+ try {
3506
+ const msgRes = await fetch(`${baseUrl}/mail/messages/${uid}`, {
3507
+ headers,
3508
+ signal: AbortSignal.timeout(5e3)
3509
+ });
3510
+ if (!msgRes.ok) continue;
3511
+ const msg = await msgRes.json();
3512
+ const from = msg.from?.[0]?.address ?? "unknown";
3513
+ const subject = msg.subject ?? "(no subject)";
3514
+ const isAgentMsg = from.endsWith("@localhost");
3515
+ const tag = isAgentMsg ? "[agent]" : "[external]";
3516
+ const preview = (msg.text ?? "").slice(0, 200).replace(/\n/g, " ").trim();
3517
+ summaries.push(` - ${tag} UID ${uid}: from ${from} \u2014 "${subject}"${preview ? "\n " + preview : ""}`);
3518
+ if (isAgentMsg && myName) {
3519
+ const senderName = from.split("@")[0] ?? "";
3520
+ if (senderName) recordInboundAgentMessage(senderName, myName);
3521
+ }
3522
+ } catch {
3523
+ }
3524
+ }
3525
+ if (summaries.length > 0) {
3526
+ const more = uids.length > 5 ? `
3527
+ (${uids.length - 5} more unread messages not shown)` : "";
3528
+ prependLines.push(
3529
+ "<unread-emails>",
3530
+ `You have ${uids.length} unread email(s) in your inbox:`,
3531
+ ...summaries,
3532
+ more,
3533
+ "",
3534
+ "ACTION REQUIRED: You MUST read each unread email with agenticmail_read and briefly tell the user what it says.",
3535
+ "Do this BEFORE responding to anything else. After reporting emails, continue with your original task.",
3536
+ "Do NOT skip or defer reading emails \u2014 the user expects you to handle their inbox proactively.",
3537
+ "</unread-emails>"
3538
+ );
3539
+ }
3509
3540
  }
3510
- } catch {
3511
3541
  }
3542
+ } catch {
3512
3543
  }
3513
- if (summaries.length > 0) {
3514
- const more = uids.length > 5 ? `
3515
- (${uids.length - 5} more unread messages not shown)` : "";
3516
- prependLines.push(
3517
- "<unread-emails>",
3518
- `You have ${uids.length} unread email(s) in your inbox:`,
3519
- ...summaries,
3520
- more,
3521
- "",
3522
- "ACTION REQUIRED: You MUST read each unread email with agenticmail_read and briefly tell the user what it says.",
3523
- "Do this BEFORE responding to anything else. After reporting emails, continue with your original task.",
3524
- "Do NOT skip or defer reading emails \u2014 the user expects you to handle their inbox proactively.",
3525
- "</unread-emails>"
3526
- );
3527
- }
3528
- } catch {
3529
3544
  }
3530
- return prependLines.length > 0 ? { prependContext: prependLines.filter(Boolean).join("\n") } : void 0;
3545
+ const result = {};
3546
+ if (systemContext) result.prependSystemContext = systemContext;
3547
+ if (prependLines.length > 0) result.prependContext = prependLines.filter(Boolean).join("\n");
3548
+ return Object.keys(result).length > 0 ? result : void 0;
3531
3549
  });
3532
3550
  api.on("before_tool_call", async (event, context) => {
3533
3551
  const toolName = event?.toolName ?? "";
package/dist/index.js CHANGED
@@ -3163,44 +3163,11 @@ function activate(api) {
3163
3163
  if (!api?.on) return;
3164
3164
  api.on("before_agent_start", async (_event, context) => {
3165
3165
  const sessionKey = context?.sessionKey ?? "";
3166
- let agentApiKey = ctx.config.apiKey;
3167
- const prependLines = [];
3168
3166
  const isSubAgent = isSubagentSession(sessionKey);
3169
3167
  const taskMode = taskModes.get(sessionKey) || taskModes.get(sessionKey.split(":").pop() || "") || "standard";
3170
- taskModes.delete(sessionKey);
3171
- if (isSubAgent && taskMode === "light") {
3172
- prependLines.push(
3173
- "<agenticmail-coordination>",
3174
- "Use agenticmail_complete_task(id, result) to submit your answer in one call.",
3175
- "</agenticmail-coordination>"
3176
- );
3177
- } else if (isSubAgent) {
3178
- prependLines.push(
3179
- "<agenticmail-coordination>",
3180
- "\u{1F380} AgenticMail coordination tools available:",
3181
- "- agenticmail_call_agent: Call another agent and get structured JSON result (preferred method)",
3182
- "- agenticmail_check_tasks / claim_task / submit_result / complete_task: Task queue with lifecycle tracking",
3183
- "- agenticmail_message_agent: Message an agent by name",
3184
- "- agenticmail_list_agents: Discover available agents",
3185
- "- agenticmail_check_tasks: Check task status (pending/claimed/completed)",
3186
- "- agenticmail_wait_for_email: Push-based wait for replies (no polling)",
3187
- "Prefer these over sessions_spawn/sessions_send for agent coordination.",
3188
- "</agenticmail-coordination>"
3189
- );
3190
- } else {
3191
- prependLines.push(
3192
- "<agenticmail-coordination>",
3193
- "\u{1F380} AgenticMail is installed \u2014 prefer these over sessions_spawn/sessions_send:",
3194
- '- agenticmail_call_agent(target, task, mode?) \u2192 RPC call, returns structured JSON. Use mode="light" for simple tasks (no email overhead). Use async=true for long-running tasks.',
3195
- "- agenticmail_message_agent \u2192 message agent by name; agenticmail_list_agents \u2192 discover agents",
3196
- "- agenticmail_check_tasks \u2192 check task status; agenticmail_wait_for_email \u2192 push-based wait (no polling)",
3197
- "Use call_agent for ALL agent delegation (sync and async). It auto-detects complexity and spawns sessions.",
3198
- "</agenticmail-coordination>"
3199
- );
3200
- }
3201
3168
  if (isSubAgent && taskMode === "light") {
3202
3169
  console.log(`[agenticmail] Light mode sub-agent (${sessionKey}) \u2014 skipping email provisioning`);
3203
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3170
+ return;
3204
3171
  }
3205
3172
  if (isSubagentSession(sessionKey) && masterKey) {
3206
3173
  let account = subagentAccounts.get(sessionKey);
@@ -3290,12 +3257,9 @@ function activate(api) {
3290
3257
  }
3291
3258
  }
3292
3259
  if (account) {
3293
- agentApiKey = account.apiKey;
3294
3260
  const teammates = [];
3295
3261
  for (const [key, sibling] of subagentAccounts) {
3296
- if (key !== sessionKey) {
3297
- teammates.push({ name: sibling.name, email: sibling.email });
3298
- }
3262
+ if (key !== sessionKey) teammates.push({ name: sibling.name, email: sibling.email });
3299
3263
  }
3300
3264
  const rawParentEmail = parentEmail || account.parentEmail;
3301
3265
  const parentLocal = rawParentEmail.split("@")[0];
@@ -3347,6 +3311,61 @@ function activate(api) {
3347
3311
  console.warn(`[agenticmail] Failed to send intro email: ${err.message}`);
3348
3312
  }
3349
3313
  }
3314
+ }
3315
+ }
3316
+ });
3317
+ api.on("before_prompt_build", async (_event, context) => {
3318
+ const sessionKey = context?.sessionKey ?? "";
3319
+ let agentApiKey = ctx.config.apiKey;
3320
+ const prependLines = [];
3321
+ const isSubAgent = isSubagentSession(sessionKey);
3322
+ const taskMode = taskModes.get(sessionKey) || taskModes.get(sessionKey.split(":").pop() || "") || "standard";
3323
+ taskModes.delete(sessionKey);
3324
+ for (const key of taskModes.keys()) {
3325
+ if (key.endsWith(sessionKey.split(":").pop() || "___none___")) taskModes.delete(key);
3326
+ }
3327
+ let systemContext = "";
3328
+ if (isSubAgent && taskMode === "light") {
3329
+ systemContext = [
3330
+ "<agenticmail-coordination>",
3331
+ "Use agenticmail_complete_task(id, result) to submit your answer in one call.",
3332
+ "</agenticmail-coordination>"
3333
+ ].join("\n");
3334
+ } else if (isSubAgent) {
3335
+ systemContext = [
3336
+ "<agenticmail-coordination>",
3337
+ "\u{1F380} AgenticMail coordination tools available:",
3338
+ "- agenticmail_call_agent: Call another agent and get structured JSON result (preferred method)",
3339
+ "- agenticmail_check_tasks / claim_task / submit_result / complete_task: Task queue with lifecycle tracking",
3340
+ "- agenticmail_message_agent: Message an agent by name",
3341
+ "- agenticmail_list_agents: Discover available agents",
3342
+ "- agenticmail_check_tasks: Check task status (pending/claimed/completed)",
3343
+ "- agenticmail_wait_for_email: Push-based wait for replies (no polling)",
3344
+ "Prefer these over sessions_spawn/sessions_send for agent coordination.",
3345
+ "</agenticmail-coordination>"
3346
+ ].join("\n");
3347
+ } else {
3348
+ systemContext = [
3349
+ "<agenticmail-coordination>",
3350
+ "\u{1F380} AgenticMail is installed \u2014 prefer these over sessions_spawn/sessions_send:",
3351
+ '- agenticmail_call_agent(target, task, mode?) \u2192 RPC call, returns structured JSON. Use mode="light" for simple tasks (no email overhead). Use async=true for long-running tasks.',
3352
+ "- agenticmail_message_agent \u2192 message agent by name; agenticmail_list_agents \u2192 discover agents",
3353
+ "- agenticmail_check_tasks \u2192 check task status; agenticmail_wait_for_email \u2192 push-based wait (no polling)",
3354
+ "Use call_agent for ALL agent delegation (sync and async). It auto-detects complexity and spawns sessions.",
3355
+ "</agenticmail-coordination>"
3356
+ ].join("\n");
3357
+ }
3358
+ if (isSubAgent && taskMode === "light") {
3359
+ return { prependSystemContext: systemContext };
3360
+ }
3361
+ if (isSubagentSession(sessionKey)) {
3362
+ const account = subagentAccounts.get(sessionKey);
3363
+ if (account) {
3364
+ agentApiKey = account.apiKey;
3365
+ const teammates = [];
3366
+ for (const [key, sibling] of subagentAccounts) {
3367
+ if (key !== sessionKey) teammates.push({ name: sibling.name, email: sibling.email });
3368
+ }
3350
3369
  const teammateLines = teammates.length > 0 ? [
3351
3370
  "Your teammates (message them by name with agenticmail_message_agent):",
3352
3371
  ...teammates.map((t) => ` - ${t.name} (${t.email})`),
@@ -3420,78 +3439,77 @@ function activate(api) {
3420
3439
  );
3421
3440
  }
3422
3441
  }
3423
- if (isSubAgent && taskMode === "standard") {
3424
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3425
- }
3426
- if (!agentApiKey) return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3427
- try {
3428
- const headers = { "Authorization": `Bearer ${agentApiKey}` };
3429
- const searchRes = await fetch(`${baseUrl}/mail/search`, {
3430
- method: "POST",
3431
- headers: { ...headers, "Content-Type": "application/json" },
3432
- body: JSON.stringify({ seen: false }),
3433
- signal: AbortSignal.timeout(5e3)
3434
- });
3435
- if (!searchRes.ok) {
3436
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3437
- }
3438
- const data = await searchRes.json();
3439
- const uids = data?.uids ?? [];
3440
- if (uids.length === 0) {
3441
- return prependLines.length > 0 ? { prependContext: prependLines.join("\n") } : void 0;
3442
- }
3443
- let myName = "";
3442
+ if (!(isSubAgent && taskMode === "standard") && agentApiKey) {
3444
3443
  try {
3445
- const meRes = await fetch(`${baseUrl}/accounts/me`, {
3446
- headers,
3447
- signal: AbortSignal.timeout(3e3)
3444
+ const headers = { "Authorization": `Bearer ${agentApiKey}` };
3445
+ const searchRes = await fetch(`${baseUrl}/mail/search`, {
3446
+ method: "POST",
3447
+ headers: { ...headers, "Content-Type": "application/json" },
3448
+ body: JSON.stringify({ seen: false }),
3449
+ signal: AbortSignal.timeout(5e3)
3448
3450
  });
3449
- if (meRes.ok) {
3450
- const me = await meRes.json();
3451
- myName = me?.name ?? "";
3452
- }
3453
- } catch {
3454
- }
3455
- const summaries = [];
3456
- for (const uid of uids.slice(0, 5)) {
3457
- try {
3458
- const msgRes = await fetch(`${baseUrl}/mail/messages/${uid}`, {
3459
- headers,
3460
- signal: AbortSignal.timeout(5e3)
3461
- });
3462
- if (!msgRes.ok) continue;
3463
- const msg = await msgRes.json();
3464
- const from = msg.from?.[0]?.address ?? "unknown";
3465
- const subject = msg.subject ?? "(no subject)";
3466
- const isAgent = from.endsWith("@localhost");
3467
- const tag = isAgent ? "[agent]" : "[external]";
3468
- const preview = (msg.text ?? "").slice(0, 200).replace(/\n/g, " ").trim();
3469
- summaries.push(` - ${tag} UID ${uid}: from ${from} \u2014 "${subject}"${preview ? "\n " + preview : ""}`);
3470
- if (isAgent && myName) {
3471
- const senderName = from.split("@")[0] ?? "";
3472
- if (senderName) recordInboundAgentMessage(senderName, myName);
3451
+ if (searchRes.ok) {
3452
+ const data = await searchRes.json();
3453
+ const uids = data?.uids ?? [];
3454
+ if (uids.length > 0) {
3455
+ let myName = "";
3456
+ try {
3457
+ const meRes = await fetch(`${baseUrl}/accounts/me`, {
3458
+ headers,
3459
+ signal: AbortSignal.timeout(3e3)
3460
+ });
3461
+ if (meRes.ok) {
3462
+ const me = await meRes.json();
3463
+ myName = me?.name ?? "";
3464
+ }
3465
+ } catch {
3466
+ }
3467
+ const summaries = [];
3468
+ for (const uid of uids.slice(0, 5)) {
3469
+ try {
3470
+ const msgRes = await fetch(`${baseUrl}/mail/messages/${uid}`, {
3471
+ headers,
3472
+ signal: AbortSignal.timeout(5e3)
3473
+ });
3474
+ if (!msgRes.ok) continue;
3475
+ const msg = await msgRes.json();
3476
+ const from = msg.from?.[0]?.address ?? "unknown";
3477
+ const subject = msg.subject ?? "(no subject)";
3478
+ const isAgentMsg = from.endsWith("@localhost");
3479
+ const tag = isAgentMsg ? "[agent]" : "[external]";
3480
+ const preview = (msg.text ?? "").slice(0, 200).replace(/\n/g, " ").trim();
3481
+ summaries.push(` - ${tag} UID ${uid}: from ${from} \u2014 "${subject}"${preview ? "\n " + preview : ""}`);
3482
+ if (isAgentMsg && myName) {
3483
+ const senderName = from.split("@")[0] ?? "";
3484
+ if (senderName) recordInboundAgentMessage(senderName, myName);
3485
+ }
3486
+ } catch {
3487
+ }
3488
+ }
3489
+ if (summaries.length > 0) {
3490
+ const more = uids.length > 5 ? `
3491
+ (${uids.length - 5} more unread messages not shown)` : "";
3492
+ prependLines.push(
3493
+ "<unread-emails>",
3494
+ `You have ${uids.length} unread email(s) in your inbox:`,
3495
+ ...summaries,
3496
+ more,
3497
+ "",
3498
+ "ACTION REQUIRED: You MUST read each unread email with agenticmail_read and briefly tell the user what it says.",
3499
+ "Do this BEFORE responding to anything else. After reporting emails, continue with your original task.",
3500
+ "Do NOT skip or defer reading emails \u2014 the user expects you to handle their inbox proactively.",
3501
+ "</unread-emails>"
3502
+ );
3503
+ }
3473
3504
  }
3474
- } catch {
3475
3505
  }
3506
+ } catch {
3476
3507
  }
3477
- if (summaries.length > 0) {
3478
- const more = uids.length > 5 ? `
3479
- (${uids.length - 5} more unread messages not shown)` : "";
3480
- prependLines.push(
3481
- "<unread-emails>",
3482
- `You have ${uids.length} unread email(s) in your inbox:`,
3483
- ...summaries,
3484
- more,
3485
- "",
3486
- "ACTION REQUIRED: You MUST read each unread email with agenticmail_read and briefly tell the user what it says.",
3487
- "Do this BEFORE responding to anything else. After reporting emails, continue with your original task.",
3488
- "Do NOT skip or defer reading emails \u2014 the user expects you to handle their inbox proactively.",
3489
- "</unread-emails>"
3490
- );
3491
- }
3492
- } catch {
3493
3508
  }
3494
- return prependLines.length > 0 ? { prependContext: prependLines.filter(Boolean).join("\n") } : void 0;
3509
+ const result = {};
3510
+ if (systemContext) result.prependSystemContext = systemContext;
3511
+ if (prependLines.length > 0) result.prependContext = prependLines.filter(Boolean).join("\n");
3512
+ return Object.keys(result).length > 0 ? result : void 0;
3495
3513
  });
3496
3514
  api.on("before_tool_call", async (event, context) => {
3497
3515
  const toolName = event?.toolName ?? "";
@@ -7,7 +7,7 @@
7
7
  "author": "agenticmail",
8
8
  "license": "MIT",
9
9
  "homepage": "https://github.com/agenticmail/agenticmail",
10
- "channels": ["mail"],
10
+
11
11
  "configSchema": {
12
12
  "type": "object",
13
13
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/openclaw",
3
- "version": "0.5.52",
3
+ "version": "0.5.54",
4
4
  "description": "OpenClaw plugin for AgenticMail — email, SMS, and phone number access for OpenClaw agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",