@agenticmail/api 0.9.25 → 0.9.26

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 (2) hide show
  1. package/dist/index.js +72 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -282,6 +282,30 @@ function closeAllSystemEventListeners() {
282
282
  }
283
283
  function createSystemEventRoutes() {
284
284
  const router = Router2();
285
+ router.get("/system/operator-email", requireMaster, async (_req, res) => {
286
+ try {
287
+ const { getOperatorEmail } = await import("@agenticmail/core");
288
+ res.json({ email: getOperatorEmail() });
289
+ } catch (err) {
290
+ res.status(500).json({ error: err.message });
291
+ }
292
+ });
293
+ router.patch("/system/operator-email", requireMaster, async (req, res) => {
294
+ try {
295
+ const { setOperatorEmail } = await import("@agenticmail/core");
296
+ const raw = req.body && typeof req.body === "object" ? req.body.email : null;
297
+ const email = typeof raw === "string" ? raw : null;
298
+ const stored = setOperatorEmail(email);
299
+ res.json({ email: stored });
300
+ } catch (err) {
301
+ const msg = err.message;
302
+ if (msg.includes("must contain an @")) {
303
+ res.status(400).json({ error: msg });
304
+ return;
305
+ }
306
+ res.status(500).json({ error: msg });
307
+ }
308
+ });
285
309
  router.get("/system/events", requireMaster, (req, res) => {
286
310
  res.setHeader("Content-Type", "text/event-stream");
287
311
  res.setHeader("Cache-Control", "no-cache");
@@ -5326,7 +5350,7 @@ var skipped = [];
5326
5350
  var SKIPPED_CAP = 100;
5327
5351
  var SKIPPED_TTL_MS = 5 * 60 * 1e3;
5328
5352
  var processState = null;
5329
- function createDispatcherActivityRoutes() {
5353
+ function createDispatcherActivityRoutes(deps = {}) {
5330
5354
  const router = Router13();
5331
5355
  router.post("/dispatcher/worker-started", requireMaster, (req, res) => {
5332
5356
  const body = req.body ?? {};
@@ -5490,7 +5514,7 @@ function createDispatcherActivityRoutes() {
5490
5514
  });
5491
5515
  res.json({ ok: true });
5492
5516
  });
5493
- router.post("/dispatcher/bridge-escalation", requireMaster, (req, res) => {
5517
+ router.post("/dispatcher/bridge-escalation", requireMaster, async (req, res) => {
5494
5518
  const body = req.body ?? {};
5495
5519
  const event = {
5496
5520
  type: "bridge_escalation",
@@ -5505,7 +5529,43 @@ function createDispatcherActivityRoutes() {
5505
5529
  atMs: Date.now()
5506
5530
  };
5507
5531
  pushSystemEvent(event);
5508
- res.json({ ok: true, escalated: true });
5532
+ let forwarded = false;
5533
+ try {
5534
+ const { getOperatorEmail } = await import("@agenticmail/core");
5535
+ const operatorEmail = getOperatorEmail();
5536
+ if (operatorEmail && deps.gatewayManager && deps.accountManager && event.agentName) {
5537
+ const bridge = await deps.accountManager.getByName(event.agentName);
5538
+ if (bridge) {
5539
+ const subjectLine = `[AgenticMail Alert] Sub-agent needs your attention \u2014 ${event.subject ?? "(no subject)"}`;
5540
+ const lines = [
5541
+ `A sub-agent mailed your ${event.agentName}@localhost bridge inbox and the dispatcher could not resume a host session to handle it on your behalf.`,
5542
+ "",
5543
+ `Reason: ${event.reason}${event.errorMessage ? ` \u2014 ${event.errorMessage.slice(0, 160)}` : ""}`,
5544
+ "",
5545
+ `From: ${event.from ?? "unknown"}`,
5546
+ `Subject: ${event.subject ?? "(no subject)"}`,
5547
+ `UID: ${event.uid ?? "?"}`,
5548
+ "",
5549
+ event.preview ? `Preview:
5550
+ ${event.preview.slice(0, 800)}` : "",
5551
+ "",
5552
+ `Open ${event.agentName} in the AgenticMail web UI, or run \`claude\` / \`codex\` and the next hook fire will surface this thread.`,
5553
+ "",
5554
+ `\u2014 AgenticMail (this address is set via setup_operator_email; reply does nothing)`
5555
+ ].filter(Boolean).join("\n");
5556
+ await deps.gatewayManager.routeOutbound(bridge.name, {
5557
+ from: bridge.email,
5558
+ to: operatorEmail,
5559
+ subject: subjectLine,
5560
+ text: lines
5561
+ });
5562
+ forwarded = true;
5563
+ }
5564
+ }
5565
+ } catch (err) {
5566
+ console.warn("[bridge-escalation] forward to operator email failed:", err.message);
5567
+ }
5568
+ res.json({ ok: true, escalated: true, forwarded });
5509
5569
  });
5510
5570
  router.post("/dispatcher/worker-skipped", requireMaster, (req, res) => {
5511
5571
  const body = req.body ?? {};
@@ -5765,7 +5825,15 @@ function createApp(configOverrides) {
5765
5825
  app2.use("/api/agenticmail", createSmsRoutes(db, accountManager, config, gatewayManager));
5766
5826
  app2.use("/api/agenticmail", createStorageRoutes(db, accountManager, config));
5767
5827
  app2.use("/api/agenticmail", createSystemEventRoutes());
5768
- app2.use("/api/agenticmail", createDispatcherActivityRoutes());
5828
+ app2.use("/api/agenticmail", createDispatcherActivityRoutes({
5829
+ // Wire the gateway + account manager so /dispatcher/bridge-escalation
5830
+ // can forward a digest to the operator's notification email when
5831
+ // no host session is available for a headless resume. See
5832
+ // packages/core/src/operator-prefs.ts for the address source and
5833
+ // the setup_operator_email MCP tool for how it gets configured.
5834
+ gatewayManager,
5835
+ accountManager
5836
+ }));
5769
5837
  app2.use("/api/agenticmail", createAgentMemoryRoutes(config));
5770
5838
  app2.use("/api/agenticmail", (_req, res) => {
5771
5839
  res.status(404).json({ error: "Not found" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/api",
3
- "version": "0.9.25",
3
+ "version": "0.9.26",
4
4
  "description": "REST API server for AgenticMail — email and SMS endpoints for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",