pim-agent 0.16.0 → 0.17.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 (98) hide show
  1. package/package.json +2 -2
  2. package/packages/core/src/attachments/AttachmentSweep.ts +155 -0
  3. package/packages/core/src/shared/SendFile.ts +6 -6
  4. package/packages/daemon/src/WebSurface.ts +8 -0
  5. package/packages/server/src/SendFileTool.ts +2 -1
  6. package/packages/telegram/src/SendFileSchema.ts +2 -0
  7. package/packages/telegram/src/SendFileTool.ts +7 -2
  8. package/packages/web/dist/client/assets/{abnfDiagram-O67JEVCF-DjiNWKul.js → abnfDiagram-O67JEVCF-B4ao97J5.js} +1 -1
  9. package/packages/web/dist/client/assets/{arc-L-qgUA9f.js → arc-HZuXlVfX.js} +1 -1
  10. package/packages/web/dist/client/assets/architecture-7GRP2DOG-BaQg4oWZ.js +1 -0
  11. package/packages/web/dist/client/assets/{architectureDiagram-NJMV4G6O-BSgBjV0C.js → architectureDiagram-NJMV4G6O-BZqhLHK9.js} +1 -1
  12. package/packages/web/dist/client/assets/{blockDiagram-BEXU5L5S-D93Ll9Dw.js → blockDiagram-BEXU5L5S-5ochYYPm.js} +1 -1
  13. package/packages/web/dist/client/assets/{c4Diagram-YGBWAQC7-Cso9YWgM.js → c4Diagram-YGBWAQC7-BgStajT_.js} +1 -1
  14. package/packages/web/dist/client/assets/channel-DRF8CC9n.js +1 -0
  15. package/packages/web/dist/client/assets/{chunk-3FUC2YCW-DBEKoKZF.js → chunk-3FUC2YCW-Cbkbpir-.js} +1 -1
  16. package/packages/web/dist/client/assets/{chunk-5DYCD2WN-Cbw5WlJE.js → chunk-5DYCD2WN-KYJ9p28-.js} +1 -1
  17. package/packages/web/dist/client/assets/{chunk-742MDFTN-CbGMGJSz.js → chunk-742MDFTN-CY6r8GHY.js} +1 -1
  18. package/packages/web/dist/client/assets/{chunk-7INBJB4K-SPvc4azf.js → chunk-7INBJB4K-YvVslvm4.js} +1 -1
  19. package/packages/web/dist/client/assets/{chunk-7M6MHVWA-C7fjnYS0.js → chunk-7M6MHVWA-CmwYem9b.js} +1 -1
  20. package/packages/web/dist/client/assets/{chunk-7PRAP22T-uozWTkjM.js → chunk-7PRAP22T-Q_VzqxZ7.js} +1 -1
  21. package/packages/web/dist/client/assets/{chunk-GTNCS2PH-B0QMH9-t.js → chunk-GTNCS2PH-COgfn7h_.js} +1 -1
  22. package/packages/web/dist/client/assets/{chunk-GWA4HPMP-hz0kwYNQ.js → chunk-GWA4HPMP-Dkl0qWY7.js} +1 -1
  23. package/packages/web/dist/client/assets/{chunk-MBY4JIJT-C15Cngrs.js → chunk-MBY4JIJT-3oOv9l78.js} +1 -1
  24. package/packages/web/dist/client/assets/{chunk-NETBCI7D-DBtUA5X-.js → chunk-NETBCI7D-BnP8A4h6.js} +1 -1
  25. package/packages/web/dist/client/assets/{chunk-O7XYJQB3-CgAoHDzj.js → chunk-O7XYJQB3-CpP8GDfI.js} +1 -1
  26. package/packages/web/dist/client/assets/{chunk-UA2S7LBM-DFxDogqX.js → chunk-UA2S7LBM-BcpQNY-v.js} +1 -1
  27. package/packages/web/dist/client/assets/{chunk-WEXAMYUT-CWZQAlYC.js → chunk-WEXAMYUT-Bkv7PaZI.js} +1 -1
  28. package/packages/web/dist/client/assets/{chunk-XXDRQBXY-C5xGs6Rc.js → chunk-XXDRQBXY-CqD07f_K.js} +1 -1
  29. package/packages/web/dist/client/assets/{chunk-Z7XXMR3K-CHcw5vr_.js → chunk-Z7XXMR3K-BXjPwmop.js} +1 -1
  30. package/packages/web/dist/client/assets/{chunk-ZIGJFQKS-BtHD8Zy8.js → chunk-ZIGJFQKS-Cbk5pa_t.js} +1 -1
  31. package/packages/web/dist/client/assets/{classDiagram-v2-NBCMYWYE-Dw3ROQG-.js → classDiagram-v2-NBCMYWYE-DpBVeBWg.js} +1 -1
  32. package/packages/web/dist/client/assets/{core-CeOhpnl2.js → core-Cvs_9RJz.js} +1 -1
  33. package/packages/web/dist/client/assets/{cose-bilkent-JH36ORCC-BM6rvX_q.js → cose-bilkent-JH36ORCC-B_YvsYOh.js} +1 -1
  34. package/packages/web/dist/client/assets/{cynefin-OW5HDTMX-smBcMKQm.js → cynefin-OW5HDTMX-B-Y-z4sL.js} +1 -1
  35. package/packages/web/dist/client/assets/{cynefinDiagram-VND7K2PF-Xo8uWpc_.js → cynefinDiagram-VND7K2PF-Bj2WQjgi.js} +1 -1
  36. package/packages/web/dist/client/assets/{dagre-6A5THRUB-BFbnP-g2.js → dagre-6A5THRUB-WPkxgM-5.js} +1 -1
  37. package/packages/web/dist/client/assets/{diagram-22UHCM2B-C-IfNBdK.js → diagram-22UHCM2B-PS2w4FaD.js} +1 -1
  38. package/packages/web/dist/client/assets/{diagram-3UASUU5V-B0c7MTxl.js → diagram-3UASUU5V-CqJNdFX6.js} +1 -1
  39. package/packages/web/dist/client/assets/{diagram-ATOU4E4O-B000aNmc.js → diagram-ATOU4E4O-B1nuEyfD.js} +1 -1
  40. package/packages/web/dist/client/assets/{diagram-CDSNMT55-DIlix5yU.js → diagram-CDSNMT55-DRfsoWX1.js} +1 -1
  41. package/packages/web/dist/client/assets/{diagram-MLGK6HIB-BZi63Dr-.js → diagram-MLGK6HIB-C7w-hWaD.js} +1 -1
  42. package/packages/web/dist/client/assets/{diagram-MPIPVDR6-Bbeeq0Au.js → diagram-MPIPVDR6-RQnZL4U8.js} +1 -1
  43. package/packages/web/dist/client/assets/{dist-BRnpNqza.js → dist-DwuZbYWF.js} +1 -1
  44. package/packages/web/dist/client/assets/{ebnfDiagram-ZINNZB2B-BsXd4VIv.js → ebnfDiagram-ZINNZB2B-Bf0N2o7E.js} +1 -1
  45. package/packages/web/dist/client/assets/{elk-276RUBZZ-D4QDfO3S.js → elk-276RUBZZ-BwYvvLGH.js} +1 -1
  46. package/packages/web/dist/client/assets/{erDiagram-OPXOYQCR-C6arxXyP.js → erDiagram-OPXOYQCR-D86v_u2J.js} +1 -1
  47. package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-hStKK_8v.js +1 -0
  48. package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-XsshF7Ug.js +1 -0
  49. package/packages/web/dist/client/assets/{ganttDiagram-FUAMR5RP-DpfbQ0_7.js → ganttDiagram-FUAMR5RP-Cjs1qbLy.js} +1 -1
  50. package/packages/web/dist/client/assets/{gitGraph-4MIJSDKK-D69loz0z.js → gitGraph-4MIJSDKK-Bc13p8zX.js} +1 -1
  51. package/packages/web/dist/client/assets/{gitGraphDiagram-X574FWY7-DPTNIBdx.js → gitGraphDiagram-X574FWY7-BxVbbDdP.js} +1 -1
  52. package/packages/web/dist/client/assets/{index-CY4YRMsv.js → index-CtGY-Cm3.js} +27 -27
  53. package/packages/web/dist/client/assets/{index-BIRI2JUA.css → index-DrjifxY-.css} +1 -1
  54. package/packages/web/dist/client/assets/{info-A6RAGUB7-0ypbrrGR.js → info-A6RAGUB7-CdEqlLjc.js} +1 -1
  55. package/packages/web/dist/client/assets/{infoDiagram-VRGFBTTK-CT4qjd2X.js → infoDiagram-VRGFBTTK-COZGVp4i.js} +1 -1
  56. package/packages/web/dist/client/assets/{ishikawaDiagram-OU5B5YK6-Ds-pffvh.js → ishikawaDiagram-OU5B5YK6-C4mA15UE.js} +1 -1
  57. package/packages/web/dist/client/assets/{journeyDiagram-ZHPQQLJL-fNWD9i15.js → journeyDiagram-ZHPQQLJL-DccWKZjV.js} +1 -1
  58. package/packages/web/dist/client/assets/{kanban-definition-PNTS6WVX-DoA1ow-i.js → kanban-definition-PNTS6WVX-DZcKdngS.js} +1 -1
  59. package/packages/web/dist/client/assets/{line-3HHp4UkM.js → line-B-YKG-pl.js} +1 -1
  60. package/packages/web/dist/client/assets/{linear-DIzOXsHI.js → linear-DUHhBKe5.js} +1 -1
  61. package/packages/web/dist/client/assets/{mermaid-parser.core-B9OBpC9v.js → mermaid-parser.core-wDQNVyH2.js} +3 -3
  62. package/packages/web/dist/client/assets/{mermaid.core-CkifwY3w.js → mermaid.core-CCCjLDlv.js} +4 -4
  63. package/packages/web/dist/client/assets/{mindmap-definition-NLK3R4M7-Cnar9-Py.js → mindmap-definition-NLK3R4M7-CYwUQEqm.js} +1 -1
  64. package/packages/web/dist/client/assets/{packet-AYTQ26CC-Jns1LUBO.js → packet-AYTQ26CC-C2bMiUpm.js} +1 -1
  65. package/packages/web/dist/client/assets/{pegDiagram-GJSIUBJH-nFP7dozy.js → pegDiagram-GJSIUBJH-Cv_La8KB.js} +1 -1
  66. package/packages/web/dist/client/assets/{pie-WAS4IAKB-BjmmQ763.js → pie-WAS4IAKB-GSgte-Tp.js} +1 -1
  67. package/packages/web/dist/client/assets/{pieDiagram-5QR66LMP-_Ol4YM7C.js → pieDiagram-5QR66LMP-CNKMkwPL.js} +1 -1
  68. package/packages/web/dist/client/assets/{quadrantDiagram-O4NWA36T-CSfIDrCe.js → quadrantDiagram-O4NWA36T-ozFB_Gtw.js} +1 -1
  69. package/packages/web/dist/client/assets/{radar-RG4KPBEZ-DeDV4Ozw.js → radar-RG4KPBEZ-C06n3HBo.js} +1 -1
  70. package/packages/web/dist/client/assets/{railroad-74A4TZTK-BjYITqPl.js → railroad-74A4TZTK-iwFqldsv.js} +1 -1
  71. package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-CKcb7zlw.js +1 -0
  72. package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-DUSbbj3X.js +1 -0
  73. package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-CiRWyr5W.js +1 -0
  74. package/packages/web/dist/client/assets/{railroadDiagram-XR7U4H2S-cQsJHXYd.js → railroadDiagram-XR7U4H2S-DCsjUIAB.js} +1 -1
  75. package/packages/web/dist/client/assets/{requirementDiagram-PLB6GJNP-D8iL2cTl.js → requirementDiagram-PLB6GJNP-BTuJXWf6.js} +1 -1
  76. package/packages/web/dist/client/assets/{sankeyDiagram-IPEJSGJF-DHbIjJtD.js → sankeyDiagram-IPEJSGJF-l4le-Pip.js} +1 -1
  77. package/packages/web/dist/client/assets/{sequenceDiagram-PO4LG4MO-IgI9FWmD.js → sequenceDiagram-PO4LG4MO-j9BiRar8.js} +1 -1
  78. package/packages/web/dist/client/assets/{src-CvUW7nT-.js → src--BYodu-T.js} +1 -1
  79. package/packages/web/dist/client/assets/{stateDiagram-v2-GCMORJYK-CUdbTd8Z.js → stateDiagram-v2-GCMORJYK-BIKdfY3K.js} +1 -1
  80. package/packages/web/dist/client/assets/{swimlanes-2SLR337P-DjGv-iIk.js → swimlanes-2SLR337P-C2oViSaw.js} +1 -1
  81. package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-C1E9GbeJ.js +8 -0
  82. package/packages/web/dist/client/assets/{timeline-definition-EJHVYXUP-D3--MIhr.js → timeline-definition-EJHVYXUP-DMbaSuZn.js} +1 -1
  83. package/packages/web/dist/client/assets/{treeView-Q6P3EWNA-Bp6MU1OS.js → treeView-Q6P3EWNA-FIQsi5if.js} +1 -1
  84. package/packages/web/dist/client/assets/{treemap-WGGIJYW6-_oQZ7eAW.js → treemap-WGGIJYW6-IUw9niAH.js} +1 -1
  85. package/packages/web/dist/client/assets/{usecaseDiagram-POWQR4AR-fBSgWqU6.js → usecaseDiagram-POWQR4AR-Bfrdtg6T.js} +1 -1
  86. package/packages/web/dist/client/assets/{vennDiagram-UO4OBE2U-DDlGnf8X.js → vennDiagram-UO4OBE2U-BhyhJCpG.js} +1 -1
  87. package/packages/web/dist/client/assets/{wardley-WFR3VGLG-CQOVh6Bi.js → wardley-WFR3VGLG-rCMSB-Cm.js} +1 -1
  88. package/packages/web/dist/client/assets/{wardleyDiagram-VNRHLVJA-CCe1EWES.js → wardleyDiagram-VNRHLVJA-CrEmdoqa.js} +1 -1
  89. package/packages/web/dist/client/assets/{xychartDiagram-PMCCYNJV-BD2EkyDp.js → xychartDiagram-PMCCYNJV-Bm-6zbYF.js} +1 -1
  90. package/packages/web/dist/client/index.html +2 -2
  91. package/packages/web/dist/client/assets/architecture-7GRP2DOG-C-Cc8ZGz.js +0 -1
  92. package/packages/web/dist/client/assets/channel-BT3dJIQT.js +0 -1
  93. package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-BfxrKIKV.js +0 -1
  94. package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-KhkDuqWr.js +0 -1
  95. package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-Bko8bqdm.js +0 -1
  96. package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-Bctn0Z-b.js +0 -1
  97. package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-9IigqOyn.js +0 -1
  98. package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-3fthS15x.js +0 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pim-agent",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "A batteries-included distro of Pi, accessible in your terminal, browser and Telegram.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -76,7 +76,7 @@
76
76
  "vite": "^8.2.2"
77
77
  },
78
78
  "dependencies": {
79
- "@earendil-works/pi-coding-agent": "1.2.0",
79
+ "@earendil-works/pi-coding-agent": "1.3.0",
80
80
  "diff": "^9.0.0",
81
81
  "fzf": "^0.5.2",
82
82
  "grammy": "^1.46.0",
@@ -0,0 +1,155 @@
1
+ import { readdir, rm, rmdir, stat } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+
4
+ import type { SessionMeta } from "../session/SessionMeta";
5
+ import type { SessionRegistry } from "../session/SessionRegistry";
6
+
7
+ export type StoredEntry = {
8
+ readonly scope: string;
9
+ readonly path: string;
10
+ readonly size: number;
11
+ readonly modifiedAt: number;
12
+ };
13
+
14
+ export type SweepPolicy = {
15
+ /** Session ids with a session file; an empty set disables the orphan rule. */
16
+ readonly alive: ReadonlySet<string>;
17
+ readonly archived: ReadonlySet<string>;
18
+ readonly now: number;
19
+ readonly budgetBytes?: number;
20
+ readonly graceMs?: number;
21
+ };
22
+
23
+ export type SweepResult = {
24
+ readonly removed: number;
25
+ readonly freedBytes: number;
26
+ };
27
+
28
+ const BUDGET_BYTES = 5 * 1024 * 1024 * 1024;
29
+ const GRACE_MS = 24 * 60 * 60 * 1000;
30
+ const INTERVAL_MS = 60 * 60 * 1000;
31
+
32
+ /**
33
+ * Files younger than the grace period are untouched and uncounted. Of the
34
+ * rest: orphans and files bigger than the whole budget go, then the oldest —
35
+ * archived sessions first — until the remainder fits the budget.
36
+ */
37
+ function doomed(
38
+ entries: readonly StoredEntry[],
39
+ policy: SweepPolicy
40
+ ): readonly StoredEntry[] {
41
+ const budget = policy.budgetBytes ?? BUDGET_BYTES;
42
+ const cutoff = policy.now - (policy.graceMs ?? GRACE_MS);
43
+ const trustsListing = policy.alive.size > 0;
44
+ const removed: StoredEntry[] = [];
45
+ const kept: StoredEntry[] = [];
46
+ for (const entry of entries) {
47
+ if (entry.modifiedAt >= cutoff) {
48
+ continue;
49
+ }
50
+ const orphaned = trustsListing && !policy.alive.has(entry.scope);
51
+ (orphaned || entry.size > budget ? removed : kept).push(entry);
52
+ }
53
+
54
+ const rank = (entry: StoredEntry) =>
55
+ policy.archived.has(entry.scope) ? 0 : 1;
56
+ kept.sort((a, b) => rank(a) - rank(b) || a.modifiedAt - b.modifiedAt);
57
+ let total = kept.reduce((sum, entry) => sum + entry.size, 0);
58
+ for (const entry of kept) {
59
+ if (total <= budget) {
60
+ break;
61
+ }
62
+ removed.push(entry);
63
+ total -= entry.size;
64
+ }
65
+ return removed;
66
+ }
67
+
68
+ async function scan(root: string): Promise<readonly StoredEntry[]> {
69
+ const scopes = await readdir(root, { withFileTypes: true }).catch(() => []);
70
+ const perScope = await Promise.all(
71
+ scopes
72
+ .filter((scope) => scope.isDirectory())
73
+ .map(async (scope) => {
74
+ const dir = join(root, scope.name);
75
+ const names = await readdir(dir).catch(() => []);
76
+ const entries = await Promise.all(
77
+ names.map(async (name) => {
78
+ const path = join(dir, name);
79
+ const st = await stat(path).catch(() => undefined);
80
+ return st?.isFile()
81
+ ? {
82
+ scope: scope.name,
83
+ path,
84
+ size: st.size,
85
+ modifiedAt: st.mtimeMs,
86
+ }
87
+ : undefined;
88
+ })
89
+ );
90
+ return entries.filter((entry) => entry !== undefined);
91
+ })
92
+ );
93
+ return perScope.flat();
94
+ }
95
+
96
+ async function sweep(root: string, policy: SweepPolicy): Promise<SweepResult> {
97
+ const victims = doomed(await scan(root), policy);
98
+ await Promise.all(victims.map((entry) => rm(entry.path, { force: true })));
99
+ const scopes = new Set(victims.map((entry) => entry.scope));
100
+ await Promise.all(
101
+ [...scopes].map((scope) => rmdir(join(root, scope)).catch(() => {}))
102
+ );
103
+ return {
104
+ removed: victims.length,
105
+ freedBytes: victims.reduce((sum, entry) => sum + entry.size, 0),
106
+ };
107
+ }
108
+
109
+ /** Sweeps now and hourly; returns the stop function. */
110
+ function install(deps: {
111
+ readonly root: string;
112
+ readonly registry: SessionRegistry;
113
+ readonly meta: SessionMeta;
114
+ }): () => void {
115
+ let running: Promise<void> | undefined;
116
+ const run = (): void => {
117
+ running ??= (async () => {
118
+ const [summaries, entries] = await Promise.all([
119
+ deps.registry.list(),
120
+ deps.meta.sessions(),
121
+ ]);
122
+ await sweep(deps.root, {
123
+ alive: new Set(summaries.map((summary) => summary.sessionId)),
124
+ archived: new Set(
125
+ [...entries]
126
+ .filter(([, entry]) => entry.archived === true)
127
+ .map(([sessionId]) => sessionId)
128
+ ),
129
+ now: Date.now(),
130
+ });
131
+ })()
132
+ .catch((error: unknown) => {
133
+ process.stderr.write(
134
+ `attachment sweep failed: ${error instanceof Error ? error.message : String(error)}\n`
135
+ );
136
+ })
137
+ .finally(() => {
138
+ running = undefined;
139
+ });
140
+ };
141
+ run();
142
+ const timer = setInterval(run, INTERVAL_MS);
143
+ timer.unref?.();
144
+ return () => {
145
+ clearInterval(timer);
146
+ };
147
+ }
148
+
149
+ export const AttachmentSweep = {
150
+ BUDGET_BYTES,
151
+ GRACE_MS,
152
+ doomed,
153
+ sweep,
154
+ install,
155
+ };
@@ -1,23 +1,23 @@
1
+ import { Format } from "./Format";
1
2
  import { FsErrors } from "./FsErrors";
2
3
  import { Paths } from "./Paths";
3
4
 
4
- const MAX_BYTES = 50 * 1024 * 1024;
5
-
6
5
  async function validate(
7
6
  rawPath: string,
8
- cwd: string
7
+ cwd: string,
8
+ maxBytes = Number.POSITIVE_INFINITY
9
9
  ): Promise<{ readonly path: string; readonly size: number }> {
10
10
  const path = Paths.resolve(rawPath, cwd);
11
11
  const st = await FsErrors.statOrThrow(path);
12
12
  if (!st.isFile()) {
13
13
  throw new Error(`${rawPath} is not a regular file.`);
14
14
  }
15
- if (st.size > MAX_BYTES) {
15
+ if (st.size > maxBytes) {
16
16
  throw new Error(
17
- `${rawPath} is ${st.size} bytes; max allowed is ${MAX_BYTES}.`
17
+ `${rawPath} is ${Format.bytes(st.size)}; max allowed is ${Format.bytes(maxBytes)}.`
18
18
  );
19
19
  }
20
20
  return { path, size: st.size };
21
21
  }
22
22
 
23
- export const SendFile = { MAX_BYTES, validate };
23
+ export const SendFile = { validate };
@@ -1,7 +1,9 @@
1
1
  import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
2
2
 
3
3
  import { AttachmentStore } from "#core/attachments/AttachmentStore";
4
+ import { AttachmentSweep } from "#core/attachments/AttachmentSweep";
4
5
  import type { AgentRuntime } from "#core/session/AgentRuntime";
6
+ import { SessionMeta } from "#core/session/SessionMeta";
5
7
  import { SessionRegistry } from "#core/session/SessionRegistry";
6
8
  import { Tools } from "#core/shared/Tools";
7
9
  import { defaultAttachmentsRoot } from "#server/AttachmentEndpoint";
@@ -39,12 +41,18 @@ function create(args: ReadonlyArray<string>, runtime: AgentRuntime): Surface {
39
41
  : { clientDir: options.clientDir }),
40
42
  });
41
43
  gateway.start();
44
+ const stopSweep = AttachmentSweep.install({
45
+ root: attachmentsRoot,
46
+ registry,
47
+ meta: new SessionMeta(),
48
+ });
42
49
  process.stderr.write(
43
50
  `pim-server listening on ${gateway.url} (web UI: http://${options.hostname}:${gateway.port})\n`
44
51
  );
45
52
 
46
53
  return {
47
54
  stop: async () => {
55
+ stopSweep();
48
56
  await gateway.stop();
49
57
  await registry.disposeAll();
50
58
  },
@@ -38,7 +38,8 @@ function build(
38
38
  ...defineTool({
39
39
  name: "send_file",
40
40
  label: "send_file",
41
- description: `Send a local file to the user's web browser. Images appear inline. Max ${SendFile.MAX_BYTES / (1024 * 1024)} MB.`,
41
+ description:
42
+ "Send a local file to the user's web browser. Images appear inline. No size limit.",
42
43
  parameters: sendFileSchema,
43
44
  async execute(_id, params) {
44
45
  const { path: rawPath } = params as SendFileInput;
@@ -2,6 +2,8 @@ import { type Static, Type } from "typebox";
2
2
 
3
3
  export const MAX_CAPTION_CHARS = 1024;
4
4
 
5
+ export const MAX_DOCUMENT_BYTES = 50 * 1024 * 1024;
6
+
5
7
  export const sendFileSchema = Type.Object({
6
8
  path: Type.String({
7
9
  minLength: 1,
@@ -7,6 +7,7 @@ import type { PimToolDefinition } from "#core/shared/Tools";
7
7
  import type { ToolView } from "#core/view/ViewBlock";
8
8
  import {
9
9
  MAX_CAPTION_CHARS,
10
+ MAX_DOCUMENT_BYTES,
10
11
  sendFileSchema,
11
12
  type SendFileInput,
12
13
  } from "./SendFileSchema";
@@ -23,11 +24,15 @@ function build(deps: SendFileDeps): PimToolDefinition<typeof sendFileSchema> {
23
24
  ...defineTool({
24
25
  name: "send_file",
25
26
  label: "send_file",
26
- description: `Send a local file to the current Telegram chat/thread as a document. Max ${SendFile.MAX_BYTES / (1024 * 1024)} MB.`,
27
+ description: `Send a local file to the current Telegram chat/thread as a document. Max ${MAX_DOCUMENT_BYTES / (1024 * 1024)} MB.`,
27
28
  parameters: sendFileSchema,
28
29
  async execute(_id, params) {
29
30
  const { path: rawPath, caption } = params as SendFileInput;
30
- const resolved = await SendFile.validate(rawPath, deps.cwd);
31
+ const resolved = await SendFile.validate(
32
+ rawPath,
33
+ deps.cwd,
34
+ MAX_DOCUMENT_BYTES
35
+ );
31
36
  const trimmedCaption = caption?.slice(0, MAX_CAPTION_CHARS);
32
37
  await send(deps.api, deps.sessionId, resolved.path, trimmedCaption);
33
38
  return {
@@ -1 +1 @@
1
- import{m as e,t}from"./mermaid-parser.core-B9OBpC9v.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-CvUW7nT-.js";import"./chunk-O7XYJQB3-CgAoHDzj.js";import{n as i,r as a,t as o}from"./chunk-GTNCS2PH-B0QMH9-t.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-CkifwY3w.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{m as e,t}from"./mermaid-parser.core-wDQNVyH2.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src--BYodu-T.js";import"./chunk-O7XYJQB3-CpP8GDfI.js";import{n as i,r as a,t as o}from"./chunk-GTNCS2PH-COgfn7h_.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-CCCjLDlv.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
@@ -1 +1 @@
1
- import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-BRnpNqza.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
1
+ import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-DwuZbYWF.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -0,0 +1 @@
1
+ import"./chunk-FOHPRMQF-CoA4358r.js";import{M as e}from"./mermaid-parser.core-wDQNVyH2.js";export{e as createArchitectureServices};