@agenticmail/api 0.7.3 → 0.7.4

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 (3) hide show
  1. package/README.md +5 -1
  2. package/dist/index.js +103 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # @agenticmail/api
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/agenticmail/agenticmail/main/docs/images/logo-200.png" alt="AgenticMail logo (pink bow)" width="180" />
3
+ </p>
4
+
5
+ <h1 align="center">@agenticmail/api</h1>
2
6
 
3
7
  The API server for [AgenticMail](https://github.com/agenticmail/agenticmail) — the part that lets AI agents (and humans) talk to the email and SMS system over the network.
4
8
 
package/dist/index.js CHANGED
@@ -4590,6 +4590,108 @@ function createStorageRoutes(rawDb, accountManager, config, dialect = "sqlite")
4590
4590
  return router;
4591
4591
  }
4592
4592
 
4593
+ // src/routes/dispatcher-activity.ts
4594
+ import { Router as Router13 } from "express";
4595
+ var ACTIVE_TTL_MS = 30 * 60 * 1e3;
4596
+ var RECENT_TTL_MS = 2 * 60 * 1e3;
4597
+ var HARD_CAP = 256;
4598
+ var active = /* @__PURE__ */ new Map();
4599
+ var recent = /* @__PURE__ */ new Map();
4600
+ function prune(nowMs) {
4601
+ for (const [id, w] of active) {
4602
+ if (nowMs - w.startedAtMs > ACTIVE_TTL_MS) active.delete(id);
4603
+ }
4604
+ for (const [id, w] of recent) {
4605
+ const t = w.endedAtMs ?? w.startedAtMs;
4606
+ if (nowMs - t > RECENT_TTL_MS) recent.delete(id);
4607
+ }
4608
+ while (active.size > HARD_CAP) {
4609
+ const first = active.keys().next().value;
4610
+ if (!first) break;
4611
+ active.delete(first);
4612
+ }
4613
+ while (recent.size > HARD_CAP) {
4614
+ const first = recent.keys().next().value;
4615
+ if (!first) break;
4616
+ recent.delete(first);
4617
+ }
4618
+ }
4619
+ function createDispatcherActivityRoutes() {
4620
+ const router = Router13();
4621
+ router.post("/dispatcher/worker-started", requireMaster, (req, res) => {
4622
+ const body = req.body ?? {};
4623
+ if (typeof body.workerId !== "string" || typeof body.agentName !== "string") {
4624
+ res.status(400).json({ error: "workerId and agentName are required" });
4625
+ return;
4626
+ }
4627
+ const info = {
4628
+ workerId: body.workerId,
4629
+ agentName: body.agentName,
4630
+ agentEmail: typeof body.agentEmail === "string" ? body.agentEmail : void 0,
4631
+ kind: typeof body.kind === "string" ? body.kind : "unknown",
4632
+ trigger: body.trigger && typeof body.trigger === "object" ? body.trigger : void 0,
4633
+ startedAtMs: Date.now()
4634
+ };
4635
+ prune(info.startedAtMs);
4636
+ active.set(info.workerId, info);
4637
+ try {
4638
+ pushSystemEvent({
4639
+ type: "worker_started",
4640
+ worker: { ...info }
4641
+ });
4642
+ } catch {
4643
+ }
4644
+ res.status(201).json({ ok: true });
4645
+ });
4646
+ router.post("/dispatcher/worker-finished", requireMaster, (req, res) => {
4647
+ const body = req.body ?? {};
4648
+ if (typeof body.workerId !== "string") {
4649
+ res.status(400).json({ error: "workerId is required" });
4650
+ return;
4651
+ }
4652
+ const existing = active.get(body.workerId);
4653
+ const nowMs = Date.now();
4654
+ const info = {
4655
+ ...existing ?? {
4656
+ workerId: body.workerId,
4657
+ agentName: typeof body.agentName === "string" ? body.agentName : "unknown",
4658
+ kind: "unknown",
4659
+ startedAtMs: nowMs
4660
+ },
4661
+ endedAtMs: nowMs,
4662
+ ok: body.ok === false ? false : true,
4663
+ resultPreview: typeof body.resultPreview === "string" ? body.resultPreview.slice(0, 240) : void 0
4664
+ };
4665
+ active.delete(body.workerId);
4666
+ recent.set(body.workerId, info);
4667
+ prune(nowMs);
4668
+ try {
4669
+ pushSystemEvent({
4670
+ type: "worker_finished",
4671
+ worker: { ...info }
4672
+ });
4673
+ } catch {
4674
+ }
4675
+ res.json({ ok: true });
4676
+ });
4677
+ router.get("/dispatcher/activity", requireMaster, (_req, res) => {
4678
+ const nowMs = Date.now();
4679
+ prune(nowMs);
4680
+ res.json({
4681
+ now: nowMs,
4682
+ active: Array.from(active.values()).map((w) => ({
4683
+ ...w,
4684
+ durationMs: nowMs - w.startedAtMs
4685
+ })),
4686
+ recent: Array.from(recent.values()).map((w) => ({
4687
+ ...w,
4688
+ durationMs: (w.endedAtMs ?? nowMs) - w.startedAtMs
4689
+ }))
4690
+ });
4691
+ });
4692
+ return router;
4693
+ }
4694
+
4593
4695
  // src/app.ts
4594
4696
  var integrationRouteFactoryPromise = (async () => {
4595
4697
  try {
@@ -4676,6 +4778,7 @@ function createApp(configOverrides) {
4676
4778
  app2.use("/api/agenticmail", createSmsRoutes(db, accountManager, config, gatewayManager));
4677
4779
  app2.use("/api/agenticmail", createStorageRoutes(db, accountManager, config));
4678
4780
  app2.use("/api/agenticmail", createSystemEventRoutes());
4781
+ app2.use("/api/agenticmail", createDispatcherActivityRoutes());
4679
4782
  app2.use("/api/agenticmail", (_req, res) => {
4680
4783
  res.status(404).json({ error: "Not found" });
4681
4784
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/api",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
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",