@jungjaehoon/mama-os 0.25.0 → 0.27.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 (123) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +37 -17
  3. package/dist/agent/agent-loop.d.ts.map +1 -1
  4. package/dist/agent/agent-loop.js +8 -0
  5. package/dist/agent/agent-loop.js.map +1 -1
  6. package/dist/agent/attachment-text-extractor.d.ts +2 -0
  7. package/dist/agent/attachment-text-extractor.d.ts.map +1 -0
  8. package/dist/agent/attachment-text-extractor.js +128 -0
  9. package/dist/agent/attachment-text-extractor.js.map +1 -0
  10. package/dist/agent/code-act/constants.d.ts.map +1 -1
  11. package/dist/agent/code-act/constants.js +17 -2
  12. package/dist/agent/code-act/constants.js.map +1 -1
  13. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  14. package/dist/agent/code-act/host-bridge.js +107 -0
  15. package/dist/agent/code-act/host-bridge.js.map +1 -1
  16. package/dist/agent/code-act/tool-policy.d.ts +9 -1
  17. package/dist/agent/code-act/tool-policy.d.ts.map +1 -1
  18. package/dist/agent/code-act/tool-policy.js +30 -1
  19. package/dist/agent/code-act/tool-policy.js.map +1 -1
  20. package/dist/agent/codex-app-server-process.d.ts +1 -0
  21. package/dist/agent/codex-app-server-process.d.ts.map +1 -1
  22. package/dist/agent/codex-app-server-process.js +16 -0
  23. package/dist/agent/codex-app-server-process.js.map +1 -1
  24. package/dist/agent/drive-tools.d.ts +55 -0
  25. package/dist/agent/drive-tools.d.ts.map +1 -0
  26. package/dist/agent/drive-tools.js +263 -0
  27. package/dist/agent/drive-tools.js.map +1 -0
  28. package/dist/agent/gateway-tool-executor.d.ts +11 -3
  29. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  30. package/dist/agent/gateway-tool-executor.js +249 -19
  31. package/dist/agent/gateway-tool-executor.js.map +1 -1
  32. package/dist/agent/gateway-tools.md +9 -0
  33. package/dist/agent/image-translation-tools.d.ts +48 -0
  34. package/dist/agent/image-translation-tools.d.ts.map +1 -0
  35. package/dist/agent/image-translation-tools.js +274 -0
  36. package/dist/agent/image-translation-tools.js.map +1 -0
  37. package/dist/agent/role-manager.d.ts.map +1 -1
  38. package/dist/agent/role-manager.js +9 -1
  39. package/dist/agent/role-manager.js.map +1 -1
  40. package/dist/agent/tool-registry.d.ts.map +1 -1
  41. package/dist/agent/tool-registry.js +53 -0
  42. package/dist/agent/tool-registry.js.map +1 -1
  43. package/dist/agent/types.d.ts +22 -33
  44. package/dist/agent/types.d.ts.map +1 -1
  45. package/dist/agent/types.js.map +1 -1
  46. package/dist/cli/commands/start.d.ts.map +1 -1
  47. package/dist/cli/commands/start.js +18 -8
  48. package/dist/cli/commands/start.js.map +1 -1
  49. package/dist/cli/config/types.d.ts.map +1 -1
  50. package/dist/cli/config/types.js +12 -4
  51. package/dist/cli/config/types.js.map +1 -1
  52. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
  53. package/dist/cli/runtime/envelope-bootstrap.js +8 -1
  54. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
  55. package/dist/connectors/drive/index.d.ts +1 -1
  56. package/dist/connectors/drive/index.d.ts.map +1 -1
  57. package/dist/connectors/drive/index.js +100 -56
  58. package/dist/connectors/drive/index.js.map +1 -1
  59. package/dist/connectors/framework/gws-utils.d.ts +3 -0
  60. package/dist/connectors/framework/gws-utils.d.ts.map +1 -1
  61. package/dist/connectors/framework/gws-utils.js +17 -0
  62. package/dist/connectors/framework/gws-utils.js.map +1 -1
  63. package/dist/envelope/enforcer.d.ts.map +1 -1
  64. package/dist/envelope/enforcer.js +18 -3
  65. package/dist/envelope/enforcer.js.map +1 -1
  66. package/dist/envelope/reactive-config.d.ts +1 -1
  67. package/dist/envelope/reactive-config.d.ts.map +1 -1
  68. package/dist/envelope/reactive-config.js +10 -2
  69. package/dist/envelope/reactive-config.js.map +1 -1
  70. package/dist/envelope/types.d.ts +1 -1
  71. package/dist/envelope/types.d.ts.map +1 -1
  72. package/dist/envelope/types.js.map +1 -1
  73. package/dist/gateways/message-router.d.ts +4 -0
  74. package/dist/gateways/message-router.d.ts.map +1 -1
  75. package/dist/gateways/message-router.js +433 -335
  76. package/dist/gateways/message-router.js.map +1 -1
  77. package/dist/gateways/session-store.d.ts +2 -0
  78. package/dist/gateways/session-store.d.ts.map +1 -1
  79. package/dist/gateways/session-store.js +41 -1
  80. package/dist/gateways/session-store.js.map +1 -1
  81. package/dist/gateways/telegram-media.d.ts +41 -0
  82. package/dist/gateways/telegram-media.d.ts.map +1 -0
  83. package/dist/gateways/telegram-media.js +242 -0
  84. package/dist/gateways/telegram-media.js.map +1 -0
  85. package/dist/gateways/telegram-message-ledger.d.ts +49 -0
  86. package/dist/gateways/telegram-message-ledger.d.ts.map +1 -0
  87. package/dist/gateways/telegram-message-ledger.js +266 -0
  88. package/dist/gateways/telegram-message-ledger.js.map +1 -0
  89. package/dist/gateways/telegram-response-presenter.d.ts +41 -0
  90. package/dist/gateways/telegram-response-presenter.d.ts.map +1 -0
  91. package/dist/gateways/telegram-response-presenter.js +250 -0
  92. package/dist/gateways/telegram-response-presenter.js.map +1 -0
  93. package/dist/gateways/telegram.d.ts +30 -7
  94. package/dist/gateways/telegram.d.ts.map +1 -1
  95. package/dist/gateways/telegram.js +444 -124
  96. package/dist/gateways/telegram.js.map +1 -1
  97. package/dist/gateways/types.d.ts +4 -2
  98. package/dist/gateways/types.d.ts.map +1 -1
  99. package/dist/operator/operator-interfaces.d.ts +1 -1
  100. package/dist/operator/operator-interfaces.d.ts.map +1 -1
  101. package/dist/operator/operator-trigger-loop.d.ts +12 -0
  102. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  103. package/dist/operator/operator-trigger-loop.js +184 -38
  104. package/dist/operator/operator-trigger-loop.js.map +1 -1
  105. package/dist/operator/pending-report-store.d.ts +35 -0
  106. package/dist/operator/pending-report-store.d.ts.map +1 -0
  107. package/dist/operator/pending-report-store.js +155 -0
  108. package/dist/operator/pending-report-store.js.map +1 -0
  109. package/dist/operator/runtime-config.d.ts +10 -0
  110. package/dist/operator/runtime-config.d.ts.map +1 -0
  111. package/dist/operator/runtime-config.js +21 -0
  112. package/dist/operator/runtime-config.js.map +1 -0
  113. package/dist/operator/situation-report.d.ts +37 -0
  114. package/dist/operator/situation-report.d.ts.map +1 -1
  115. package/dist/operator/situation-report.js +122 -9
  116. package/dist/operator/situation-report.js.map +1 -1
  117. package/package.json +3 -1
  118. package/scripts/attachment/extract-office-text.js +179 -0
  119. package/scripts/attachment/extract-pdf-text.swift +36 -0
  120. package/scripts/image/fb-overlay.py +128 -0
  121. package/scripts/image/ocr-image.py +38 -0
  122. package/scripts/setup-ocr.js +120 -0
  123. package/templates/skills/image-translate.md +17 -22
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pruneTelegramMediaRoot = pruneTelegramMediaRoot;
4
+ exports.downloadTelegramMedia = downloadTelegramMedia;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const promises_1 = require("node:fs/promises");
7
+ const node_path_1 = require("node:path");
8
+ const TELEGRAM_HOSTED_DOWNLOAD_LIMIT_BYTES = 20 * 1024 * 1024;
9
+ const DEFAULT_ATTACHMENT_LIMIT_BYTES = 25 * 1024 * 1024;
10
+ const DEFAULT_DOWNLOAD_TIMEOUT_MS = 30_000;
11
+ const DEFAULT_MEDIA_TTL_MS = 24 * 60 * 60_000;
12
+ const DEFAULT_MEDIA_QUOTA_BYTES = 256 * 1024 * 1024;
13
+ const activeFinalPaths = new Set();
14
+ class TelegramMediaError extends Error {
15
+ }
16
+ function configuredPositiveNumber(name, fallback) {
17
+ const configured = Number(process.env[name]);
18
+ return Number.isFinite(configured) && configured > 0 ? configured : fallback;
19
+ }
20
+ /**
21
+ * Bound retained Telegram media across turns. Non-regular entries are removed,
22
+ * expired files are deleted, then the oldest remaining files are evicted until
23
+ * the cumulative quota is met. A just-downloaded file may be preserved while
24
+ * older files are reclaimed.
25
+ */
26
+ async function pruneTelegramMediaRoot(mediaRoot, options = {}) {
27
+ const root = (0, node_path_1.resolve)(mediaRoot);
28
+ await (0, promises_1.mkdir)(root, { recursive: true, mode: 0o700 });
29
+ const nowMs = options.nowMs ?? Date.now();
30
+ const ttlMs = options.ttlMs ?? configuredPositiveNumber('MAMA_TELEGRAM_MEDIA_TTL_MS', DEFAULT_MEDIA_TTL_MS);
31
+ const maxTotalBytes = options.maxTotalBytes ??
32
+ configuredPositiveNumber('MAMA_TELEGRAM_MEDIA_MAX_TOTAL_BYTES', DEFAULT_MEDIA_QUOTA_BYTES);
33
+ const preservePath = options.preservePath ? (0, node_path_1.resolve)(options.preservePath) : null;
34
+ if (preservePath)
35
+ assertWithinRoot(root, preservePath);
36
+ const retained = [];
37
+ for (const name of await (0, promises_1.readdir)(root)) {
38
+ const path = (0, node_path_1.resolve)(root, name);
39
+ assertWithinRoot(root, path);
40
+ let info;
41
+ try {
42
+ info = await (0, promises_1.lstat)(path);
43
+ }
44
+ catch {
45
+ continue;
46
+ }
47
+ if (name.endsWith('.part') && nowMs - info.mtimeMs <= DEFAULT_DOWNLOAD_TIMEOUT_MS * 2) {
48
+ continue;
49
+ }
50
+ if (!info.isFile() || info.isSymbolicLink()) {
51
+ await (0, promises_1.unlink)(path).catch(() => { });
52
+ continue;
53
+ }
54
+ if (path !== preservePath && !activeFinalPaths.has(path) && nowMs - info.mtimeMs > ttlMs) {
55
+ await (0, promises_1.unlink)(path).catch(() => { });
56
+ continue;
57
+ }
58
+ retained.push({ path, size: info.size, mtimeMs: info.mtimeMs });
59
+ }
60
+ let totalBytes = retained.reduce((total, file) => total + file.size, 0);
61
+ for (const file of retained.sort((left, right) => left.mtimeMs - right.mtimeMs)) {
62
+ if (totalBytes <= maxTotalBytes)
63
+ break;
64
+ if (file.path === preservePath || activeFinalPaths.has(file.path))
65
+ continue;
66
+ try {
67
+ await (0, promises_1.unlink)(file.path);
68
+ }
69
+ catch (error) {
70
+ if (!error || typeof error !== 'object' || !('code' in error) || error.code !== 'ENOENT') {
71
+ throw error;
72
+ }
73
+ // Another overlapping sweep already evicted this exact file. It is no
74
+ // longer part of the actual quota even though this sweep counted it.
75
+ }
76
+ totalBytes -= file.size;
77
+ }
78
+ if (totalBytes > maxTotalBytes) {
79
+ throw new TelegramMediaError('Telegram media storage quota exceeded');
80
+ }
81
+ }
82
+ async function withDownloadTimeout(promise, timeoutMs) {
83
+ let timer;
84
+ try {
85
+ return await Promise.race([
86
+ promise,
87
+ new Promise((_resolve, reject) => {
88
+ timer = setTimeout(() => reject(new TelegramMediaError('Telegram media download timed out')), timeoutMs);
89
+ }),
90
+ ]);
91
+ }
92
+ finally {
93
+ if (timer)
94
+ clearTimeout(timer);
95
+ }
96
+ }
97
+ function configuredAttachmentLimit() {
98
+ const configured = Number(process.env.MAMA_ATTACHMENT_MAX_DOWNLOAD_BYTES);
99
+ return Number.isFinite(configured) && configured > 0
100
+ ? configured
101
+ : DEFAULT_ATTACHMENT_LIMIT_BYTES;
102
+ }
103
+ function effectiveLimit(requested) {
104
+ const base = requested && requested > 0 ? requested : configuredAttachmentLimit();
105
+ return Math.min(base, TELEGRAM_HOSTED_DOWNLOAD_LIMIT_BYTES);
106
+ }
107
+ function safeOpaqueId(value) {
108
+ const sanitized = value.replace(/[^a-zA-Z0-9_-]/g, '_').slice(0, 120);
109
+ return sanitized || (0, node_crypto_1.randomUUID)();
110
+ }
111
+ function safeFilename(request) {
112
+ const opaqueId = safeOpaqueId(request.fileUniqueId);
113
+ const fallback = request.kind === 'photo' ? `photo-${opaqueId}.jpg` : `document-${opaqueId}.bin`;
114
+ const raw = request.filename ? (0, node_path_1.basename)(request.filename.replace(/\\/g, '/')) : fallback;
115
+ const sanitized = raw.replace(/[^a-zA-Z0-9._-]/g, '_').replace(/^\.+/, '');
116
+ if (!sanitized) {
117
+ return fallback;
118
+ }
119
+ if (request.kind === 'photo' && !(0, node_path_1.extname)(sanitized)) {
120
+ return `${sanitized}.jpg`;
121
+ }
122
+ if (request.kind === 'document' && !(0, node_path_1.extname)(sanitized)) {
123
+ return `${sanitized}.bin`;
124
+ }
125
+ return sanitized;
126
+ }
127
+ function assertSafeTelegramPath(filePath) {
128
+ if (!filePath) {
129
+ throw new TelegramMediaError('Telegram media path is unavailable');
130
+ }
131
+ const normalized = filePath.replace(/\\/g, '/');
132
+ const segments = normalized.split('/');
133
+ if (normalized.startsWith('/') ||
134
+ normalized.includes('\0') ||
135
+ segments.some((segment) => segment === '..' || segment === '')) {
136
+ throw new TelegramMediaError('Telegram media path is invalid');
137
+ }
138
+ return normalized;
139
+ }
140
+ function assertWithinRoot(root, candidate) {
141
+ const resolvedRoot = (0, node_path_1.resolve)(root);
142
+ const resolvedCandidate = (0, node_path_1.resolve)(candidate);
143
+ if (!resolvedCandidate.startsWith(`${resolvedRoot}${node_path_1.sep}`)) {
144
+ throw new TelegramMediaError('Telegram media storage path is invalid');
145
+ }
146
+ }
147
+ function downloadUrl(botToken, filePath) {
148
+ const encodedPath = filePath.split('/').map(encodeURIComponent).join('/');
149
+ return `https://api.telegram.org/file/bot${botToken}/${encodedPath}`;
150
+ }
151
+ async function downloadTelegramMedia(request) {
152
+ const limit = effectiveLimit(request.maxBytes);
153
+ const timeoutMs = request.timeoutMs && request.timeoutMs > 0 ? request.timeoutMs : DEFAULT_DOWNLOAD_TIMEOUT_MS;
154
+ if (request.declaredSize !== undefined && request.declaredSize > limit) {
155
+ throw new TelegramMediaError('Telegram media exceeds the download limit');
156
+ }
157
+ const metadata = await withDownloadTimeout(request.getFile(request.fileId), timeoutMs);
158
+ if (metadata.file_size !== undefined && metadata.file_size > limit) {
159
+ throw new TelegramMediaError('Telegram media exceeds the download limit');
160
+ }
161
+ const filePath = assertSafeTelegramPath(metadata.file_path);
162
+ const root = (0, node_path_1.resolve)(request.mediaRoot);
163
+ await (0, promises_1.mkdir)(root, { recursive: true, mode: 0o700 });
164
+ await (0, promises_1.chmod)(root, 0o700);
165
+ await pruneTelegramMediaRoot(root);
166
+ const fetchImpl = request.fetchImpl ?? fetch;
167
+ let response;
168
+ try {
169
+ response = await withDownloadTimeout(fetchImpl(downloadUrl(request.botToken, filePath), {
170
+ signal: AbortSignal.timeout(timeoutMs),
171
+ }), timeoutMs);
172
+ }
173
+ catch (error) {
174
+ if (error instanceof TelegramMediaError) {
175
+ throw error;
176
+ }
177
+ throw new TelegramMediaError('Telegram media download failed');
178
+ }
179
+ if (!response.ok || !response.body) {
180
+ throw new TelegramMediaError('Telegram media download failed');
181
+ }
182
+ const contentLength = Number(response.headers.get('content-length'));
183
+ if (Number.isFinite(contentLength) && contentLength > limit) {
184
+ throw new TelegramMediaError('Telegram media exceeds the download limit');
185
+ }
186
+ const filename = safeFilename(request);
187
+ const id = (0, node_crypto_1.randomUUID)();
188
+ const tempPath = (0, node_path_1.resolve)(root, `.${id}.part`);
189
+ const finalPath = (0, node_path_1.resolve)(root, `${id}-${filename}`);
190
+ assertWithinRoot(root, tempPath);
191
+ assertWithinRoot(root, finalPath);
192
+ let handle = null;
193
+ let totalBytes = 0;
194
+ activeFinalPaths.add(finalPath);
195
+ try {
196
+ handle = await (0, promises_1.open)(tempPath, 'wx', 0o600);
197
+ const reader = response.body.getReader();
198
+ let streamComplete = false;
199
+ while (!streamComplete) {
200
+ const { done, value } = await withDownloadTimeout(reader.read(), timeoutMs);
201
+ if (done) {
202
+ streamComplete = true;
203
+ continue;
204
+ }
205
+ totalBytes += value.byteLength;
206
+ if (totalBytes > limit) {
207
+ await reader.cancel();
208
+ throw new TelegramMediaError('Telegram media exceeds the download limit');
209
+ }
210
+ await handle.write(value);
211
+ }
212
+ await handle.close();
213
+ handle = null;
214
+ await (0, promises_1.chmod)(tempPath, 0o600);
215
+ await (0, promises_1.rename)(tempPath, finalPath);
216
+ await (0, promises_1.chmod)(finalPath, 0o600);
217
+ await pruneTelegramMediaRoot(root, { preservePath: finalPath });
218
+ }
219
+ catch (error) {
220
+ if (handle) {
221
+ await handle.close().catch(() => { });
222
+ }
223
+ await (0, promises_1.unlink)(tempPath).catch(() => { });
224
+ await (0, promises_1.unlink)(finalPath).catch(() => { });
225
+ if (error instanceof TelegramMediaError) {
226
+ throw error;
227
+ }
228
+ throw new TelegramMediaError('Telegram media download failed');
229
+ }
230
+ finally {
231
+ activeFinalPaths.delete(finalPath);
232
+ }
233
+ return {
234
+ localPath: finalPath,
235
+ sourceRef: `telegram:${safeOpaqueId(request.fileUniqueId)}`,
236
+ filename,
237
+ mimeType: request.mimeType || (request.kind === 'photo' ? 'image/jpeg' : 'application/octet-stream'),
238
+ size: totalBytes,
239
+ kind: request.kind,
240
+ };
241
+ }
242
+ //# sourceMappingURL=telegram-media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-media.js","sourceRoot":"","sources":["../../src/gateways/telegram-media.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export type TelegramMessageState = 'processing' | 'ready' | 'delivered';
2
+ export interface TelegramMessageLedgerEntry {
3
+ key: string;
4
+ state: TelegramMessageState;
5
+ updatedAt: number;
6
+ ownerId: string;
7
+ response?: string;
8
+ nextChunkIndex?: number;
9
+ deliveryUncertain?: boolean;
10
+ }
11
+ export interface TelegramMessageLedgerOptions {
12
+ ttlMs?: number;
13
+ maxEntries?: number;
14
+ now?: () => number;
15
+ log?: (line: string) => void;
16
+ ownerId?: string;
17
+ }
18
+ export declare class TelegramMessageLedger {
19
+ private readonly path;
20
+ private readonly entries;
21
+ private readonly ttlMs;
22
+ private readonly maxEntries;
23
+ private readonly now;
24
+ private readonly log;
25
+ private readonly ownerId;
26
+ constructor(path: string, options?: TelegramMessageLedgerOptions);
27
+ get(key: string): TelegramMessageLedgerEntry | null;
28
+ has(key: string): boolean;
29
+ listUndelivered(): TelegramMessageLedgerEntry[];
30
+ isOwnedByCurrentProcess(entry: TelegramMessageLedgerEntry): boolean;
31
+ claim(key: string): {
32
+ claimed: boolean;
33
+ entry: TelegramMessageLedgerEntry;
34
+ };
35
+ markReady(key: string, response: string): void;
36
+ markDeliveryProgress(key: string, nextChunkIndex: number, deliveryUncertain: boolean): void;
37
+ markDelivered(key: string): void;
38
+ /** Compatibility alias for the original completed-ID ledger API. */
39
+ record(key: string): void;
40
+ private requireEntry;
41
+ private enforceEntryLimit;
42
+ private load;
43
+ private prune;
44
+ private save;
45
+ private serialize;
46
+ private evictOldestDelivered;
47
+ private commit;
48
+ }
49
+ //# sourceMappingURL=telegram-message-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-message-ledger.d.ts","sourceRoot":"","sources":["../../src/gateways/telegram-message-ledger.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,OAAO,GAAG,WAAW,CAAC;AAExE,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,oBAAoB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAYD,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,qBAAa,qBAAqB;IAS9B,OAAO,CAAC,QAAQ,CAAC,IAAI;IARvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiD;IACzE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGd,IAAI,EAAE,MAAM,EAC7B,OAAO,GAAE,4BAAiC;IAU5C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI;IAMnD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,eAAe,IAAI,0BAA0B,EAAE;IAO/C,uBAAuB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO;IAInE,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,0BAA0B,CAAA;KAAE;IAiB3E,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAkB9C,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAG,IAAI;IAmB3F,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAahC,oEAAoE;IACpE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,IAAI;IA2CZ,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,MAAM;CAWf"}
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelegramMessageLedger = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const DEFAULT_TTL_MS = 7 * 24 * 60 * 60_000;
8
+ const DEFAULT_MAX_ENTRIES = 10_000;
9
+ const MAX_RESPONSE_CHARS = 1_000_000;
10
+ const MAX_LEDGER_FILE_BYTES = 8 * 1024 * 1024;
11
+ class TelegramMessageLedger {
12
+ path;
13
+ entries = new Map();
14
+ ttlMs;
15
+ maxEntries;
16
+ now;
17
+ log;
18
+ ownerId;
19
+ constructor(path, options = {}) {
20
+ this.path = path;
21
+ this.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
22
+ this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
23
+ this.now = options.now ?? Date.now;
24
+ this.log = options.log ?? (() => { });
25
+ this.ownerId = options.ownerId ?? (0, node_crypto_1.randomUUID)();
26
+ this.load();
27
+ }
28
+ get(key) {
29
+ this.prune();
30
+ const entry = this.entries.get(key);
31
+ return entry ? { ...entry } : null;
32
+ }
33
+ has(key) {
34
+ return this.get(key) !== null;
35
+ }
36
+ listUndelivered() {
37
+ this.prune();
38
+ return [...this.entries.values()]
39
+ .filter((entry) => entry.state !== 'delivered')
40
+ .map((entry) => ({ ...entry }));
41
+ }
42
+ isOwnedByCurrentProcess(entry) {
43
+ return entry.ownerId === this.ownerId;
44
+ }
45
+ claim(key) {
46
+ this.prune();
47
+ const existing = this.entries.get(key);
48
+ if (existing)
49
+ return { claimed: false, entry: { ...existing } };
50
+ const entry = {
51
+ key,
52
+ state: 'processing',
53
+ updatedAt: this.now(),
54
+ ownerId: this.ownerId,
55
+ };
56
+ this.commit(() => {
57
+ this.entries.set(key, entry);
58
+ this.enforceEntryLimit();
59
+ });
60
+ return { claimed: true, entry: { ...entry } };
61
+ }
62
+ markReady(key, response) {
63
+ if (response.length > MAX_RESPONSE_CHARS) {
64
+ throw new Error('Telegram durable response exceeds its size limit');
65
+ }
66
+ const entry = this.requireEntry(key);
67
+ this.commit(() => {
68
+ this.entries.set(key, {
69
+ ...entry,
70
+ state: 'ready',
71
+ response,
72
+ nextChunkIndex: 0,
73
+ deliveryUncertain: false,
74
+ updatedAt: this.now(),
75
+ ownerId: this.ownerId,
76
+ });
77
+ });
78
+ }
79
+ markDeliveryProgress(key, nextChunkIndex, deliveryUncertain) {
80
+ if (!Number.isSafeInteger(nextChunkIndex) || nextChunkIndex < 0) {
81
+ throw new Error('Telegram delivery progress must be a non-negative integer');
82
+ }
83
+ const entry = this.requireEntry(key);
84
+ if (entry.state !== 'ready' || entry.response === undefined) {
85
+ throw new Error(`Telegram message ${key} is not ready for delivery`);
86
+ }
87
+ this.commit(() => {
88
+ this.entries.set(key, {
89
+ ...entry,
90
+ nextChunkIndex,
91
+ deliveryUncertain,
92
+ updatedAt: this.now(),
93
+ ownerId: this.ownerId,
94
+ });
95
+ });
96
+ }
97
+ markDelivered(key) {
98
+ this.commit(() => {
99
+ this.entries.delete(key);
100
+ this.entries.set(key, {
101
+ key,
102
+ state: 'delivered',
103
+ updatedAt: this.now(),
104
+ ownerId: this.ownerId,
105
+ });
106
+ this.enforceEntryLimit();
107
+ });
108
+ }
109
+ /** Compatibility alias for the original completed-ID ledger API. */
110
+ record(key) {
111
+ this.markDelivered(key);
112
+ }
113
+ requireEntry(key) {
114
+ const entry = this.entries.get(key);
115
+ if (!entry)
116
+ throw new Error(`Telegram message ${key} has not been claimed`);
117
+ return entry;
118
+ }
119
+ enforceEntryLimit() {
120
+ while (this.entries.size > this.maxEntries) {
121
+ if (!this.evictOldestDelivered()) {
122
+ throw new Error('Telegram message ledger entry limit is full of undelivered work');
123
+ }
124
+ }
125
+ }
126
+ load() {
127
+ if (!(0, node_fs_1.existsSync)(this.path))
128
+ return;
129
+ if ((0, node_fs_1.statSync)(this.path).size > MAX_LEDGER_FILE_BYTES) {
130
+ const error = new Error(`Telegram message ledger exceeds ${MAX_LEDGER_FILE_BYTES} bytes`);
131
+ this.log(`[Telegram] message ledger rejected without modification: ${error.message}`);
132
+ throw error;
133
+ }
134
+ try {
135
+ const parsed = JSON.parse((0, node_fs_1.readFileSync)(this.path, 'utf8'));
136
+ if (isLedgerStateV2(parsed, this.maxEntries)) {
137
+ for (const entry of parsed.entries) {
138
+ if (entry.state === 'delivered') {
139
+ const { response: _response, ...delivered } = entry;
140
+ this.entries.set(entry.key, delivered);
141
+ }
142
+ else {
143
+ this.entries.set(entry.key, entry);
144
+ }
145
+ }
146
+ }
147
+ else if (isLedgerStateV1(parsed, this.maxEntries)) {
148
+ for (const entry of parsed.entries) {
149
+ this.entries.set(entry.key, {
150
+ key: entry.key,
151
+ state: 'delivered',
152
+ updatedAt: entry.completedAt,
153
+ ownerId: 'legacy',
154
+ });
155
+ }
156
+ }
157
+ else {
158
+ throw new Error('invalid Telegram message ledger');
159
+ }
160
+ this.prune();
161
+ }
162
+ catch (error) {
163
+ const quarantinePath = `${this.path}.corrupt-${this.now()}-${process.pid}`;
164
+ (0, node_fs_1.renameSync)(this.path, quarantinePath);
165
+ this.entries.clear();
166
+ this.log(`[Telegram] invalid message ledger quarantined at ${quarantinePath}: ${error instanceof Error ? error.message : String(error)}`);
167
+ }
168
+ }
169
+ prune() {
170
+ const cutoff = this.now() - this.ttlMs;
171
+ for (const [key, entry] of this.entries) {
172
+ if (entry.state === 'delivered' && entry.updatedAt < cutoff)
173
+ this.entries.delete(key);
174
+ }
175
+ }
176
+ save() {
177
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.path), { recursive: true, mode: 0o700 });
178
+ const temporaryPath = `${this.path}.tmp`;
179
+ let serialized = this.serialize();
180
+ while (Buffer.byteLength(serialized, 'utf8') > MAX_LEDGER_FILE_BYTES) {
181
+ if (!this.evictOldestDelivered()) {
182
+ throw new Error('Telegram message ledger exceeds its durable size limit');
183
+ }
184
+ serialized = this.serialize();
185
+ }
186
+ (0, node_fs_1.writeFileSync)(temporaryPath, serialized, { mode: 0o600 });
187
+ (0, node_fs_1.chmodSync)(temporaryPath, 0o600);
188
+ (0, node_fs_1.renameSync)(temporaryPath, this.path);
189
+ }
190
+ serialize() {
191
+ const state = { version: 2, entries: [...this.entries.values()] };
192
+ return `${JSON.stringify(state)}\n`;
193
+ }
194
+ evictOldestDelivered() {
195
+ for (const [key, entry] of this.entries) {
196
+ if (entry.state === 'delivered') {
197
+ this.entries.delete(key);
198
+ return true;
199
+ }
200
+ }
201
+ return false;
202
+ }
203
+ commit(change) {
204
+ const snapshot = new Map(this.entries);
205
+ try {
206
+ change();
207
+ this.save();
208
+ }
209
+ catch (error) {
210
+ this.entries.clear();
211
+ for (const [key, entry] of snapshot)
212
+ this.entries.set(key, entry);
213
+ throw error;
214
+ }
215
+ }
216
+ }
217
+ exports.TelegramMessageLedger = TelegramMessageLedger;
218
+ function isLedgerStateV1(value, maxEntries) {
219
+ if (!value || typeof value !== 'object')
220
+ return false;
221
+ const record = value;
222
+ if (record.version !== 1 ||
223
+ !Array.isArray(record.entries) ||
224
+ record.entries.length > maxEntries) {
225
+ return false;
226
+ }
227
+ return record.entries.every((entry) => {
228
+ if (!entry || typeof entry !== 'object')
229
+ return false;
230
+ const item = entry;
231
+ return isKey(item.key) && isTimestamp(item.completedAt);
232
+ });
233
+ }
234
+ function isLedgerStateV2(value, maxEntries) {
235
+ if (!value || typeof value !== 'object')
236
+ return false;
237
+ const record = value;
238
+ if (record.version !== 2 ||
239
+ !Array.isArray(record.entries) ||
240
+ record.entries.length > maxEntries) {
241
+ return false;
242
+ }
243
+ return record.entries.every((entry) => {
244
+ if (!entry || typeof entry !== 'object')
245
+ return false;
246
+ const item = entry;
247
+ return (isKey(item.key) &&
248
+ (item.state === 'processing' || item.state === 'ready' || item.state === 'delivered') &&
249
+ isTimestamp(item.updatedAt) &&
250
+ typeof item.ownerId === 'string' &&
251
+ item.ownerId.length > 0 &&
252
+ item.ownerId.length <= 128 &&
253
+ (item.response === undefined ||
254
+ (typeof item.response === 'string' && item.response.length <= MAX_RESPONSE_CHARS)) &&
255
+ (item.nextChunkIndex === undefined ||
256
+ (Number.isSafeInteger(item.nextChunkIndex) && item.nextChunkIndex >= 0)) &&
257
+ (item.deliveryUncertain === undefined || typeof item.deliveryUncertain === 'boolean'));
258
+ });
259
+ }
260
+ function isKey(value) {
261
+ return typeof value === 'string' && value.length > 0 && value.length <= 256;
262
+ }
263
+ function isTimestamp(value) {
264
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
265
+ }
266
+ //# sourceMappingURL=telegram-message-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-message-ledger.js","sourceRoot":"","sources":["../../src/gateways/telegram-message-ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { StreamCallbacks } from '../agent/types.js';
2
+ export interface TelegramResponseAdapter {
3
+ send(text: string): Promise<string | null>;
4
+ edit(handle: string, text: string): Promise<void>;
5
+ delete(handle: string): Promise<void>;
6
+ }
7
+ export interface TelegramResponsePresenterOptions {
8
+ throttleMs?: number;
9
+ maxLength?: number;
10
+ chunkRetryCount?: number;
11
+ resumeFromChunk?: number;
12
+ onChunkProgress?: (nextIndex: number, uncertain: boolean) => void | Promise<void>;
13
+ }
14
+ export declare function splitTelegramMessage(text: string, maxLength: number): string[];
15
+ export declare class TelegramResponsePresenter {
16
+ private readonly adapter;
17
+ private readonly throttleMs;
18
+ private readonly maxLength;
19
+ private handle;
20
+ private accumulatedText;
21
+ private toolStatus;
22
+ private editTimer;
23
+ private inFlightEdit;
24
+ private finalized;
25
+ private finalizing;
26
+ private readonly chunkRetryCount;
27
+ private readonly resumeFromChunk;
28
+ private readonly onChunkProgress?;
29
+ constructor(adapter: TelegramResponseAdapter, options?: TelegramResponsePresenterOptions);
30
+ start(): Promise<void>;
31
+ callbacks(): StreamCallbacks;
32
+ markQueued(): void;
33
+ finalize(rawResponse: string): Promise<void>;
34
+ fail(message: string): Promise<void>;
35
+ private scheduleEdit;
36
+ private flushStreamingEdit;
37
+ private cancelPendingEdit;
38
+ private sendChunks;
39
+ private recordChunkProgress;
40
+ }
41
+ //# sourceMappingURL=telegram-response-presenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-response-presenter.d.ts","sourceRoot":"","sources":["../../src/gateways/telegram-response-presenter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,gCAAgC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF;AA4CD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB9E;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAsD;gBAE3E,OAAO,EAAE,uBAAuB,EAAE,OAAO,GAAE,gCAAqC;IAStF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,SAAS,IAAI,eAAe;IA0B5B,UAAU,IAAI,IAAI;IAQZ,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyD5C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,YAAY;YAUN,kBAAkB;IAoBhC,OAAO,CAAC,iBAAiB;YAOX,UAAU;YAqBV,mBAAmB;CAGlC"}