teleton 0.8.4 → 0.8.6
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/README.md +40 -17
- package/dist/{bootstrap-NNEI3Z5H.js → bootstrap-PFBH6ALD.js} +11 -8
- package/dist/bridge-guards-HZTNH7IB.js +9 -0
- package/dist/{chunk-NH2CNRKJ.js → chunk-2UUGRY5B.js} +151 -159
- package/dist/{chunk-UMUONAD6.js → chunk-4MFN75ZK.js} +5941 -2716
- package/dist/{chunk-LC4TV3KL.js → chunk-4MG2AROG.js} +5 -7
- package/dist/{chunk-LZQOX6YY.js → chunk-6IFNQWIM.js} +7714 -8748
- package/dist/chunk-7KI25UJU.js +215 -0
- package/dist/chunk-AX5NBEHX.js +12 -0
- package/dist/{chunk-5LOHRZYY.js → chunk-BLUES3FJ.js} +80 -101
- package/dist/{chunk-CUE4UZXR.js → chunk-BT2I3ETV.js} +3 -3
- package/dist/chunk-CXTZPOTA.js +107 -0
- package/dist/{chunk-LVTKJQ7O.js → chunk-D3GT6YIY.js} +59 -7
- package/dist/chunk-EKCXKL5M.js +53 -0
- package/dist/{chunk-XDZDOKIF.js → chunk-F6S3L3OV.js} +3 -3
- package/dist/{chunk-C4NKJT2Z.js → chunk-J4WDJ7XS.js} +1 -1
- package/dist/{chunk-G7PCW63M.js → chunk-JYF2MM5I.js} +147 -113
- package/dist/{chunk-NVKBBTI6.js → chunk-K3QSIIMZ.js} +9 -6
- package/dist/{chunk-EYWNOHMJ.js → chunk-L653KKCR.js} +1 -0
- package/dist/chunk-OMQIAWEU.js +273 -0
- package/dist/chunk-PCT7GYBP.js +274 -0
- package/dist/chunk-QYZBWU2D.js +139 -0
- package/dist/{chunk-WTDAICGT.js → chunk-R6W4DJRK.js} +7 -7
- package/dist/{chunk-5SEMA47R.js → chunk-RILOEIK6.js} +1 -1
- package/dist/{chunk-6OOHHJ4N.js → chunk-TFTNZZDH.js} +20 -20
- package/dist/chunk-TTOZCZWE.js +96 -0
- package/dist/chunk-UJ54YT2T.js +12 -0
- package/dist/{chunk-GHMXWAXI.js → chunk-ULVL2W3D.js} +211 -445
- package/dist/{chunk-NQ6FZKCE.js → chunk-V3S3NXBQ.js} +3 -1
- package/dist/{chunk-H7MFXJZK.js → chunk-WSL4KIOI.js} +31 -26
- package/dist/{chunk-35MX4ZUI.js → chunk-Z5WY7BSB.js} +5 -5
- package/dist/{chunk-ALKAAG4O.js → chunk-ZGKE3OTA.js} +112 -49
- package/dist/{chunk-JROBTXWY.js → chunk-ZHRDETCX.js} +38 -4
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +272 -159
- package/dist/{client-5KD25NOP.js → client-S5UIK6OG.js} +10 -8
- package/dist/daily-logs-3WXGYAQF.js +25 -0
- package/dist/{get-my-gifts-Y7EN7RK4.js → get-my-gifts-3YSYM3LI.js} +3 -2
- package/dist/harden-permissions-PV5SGV5D.js +100 -0
- package/dist/index.d.ts +923 -0
- package/dist/index.js +29 -20
- package/dist/knowledge-RRWUIO3G.js +19 -0
- package/dist/{local-IHKJFQJS.js → local-MSZAXWUL.js} +3 -3
- package/dist/mcp-loader-OELDFR63.js +15 -0
- package/dist/{memory-QMJRM3XJ.js → memory-6U6HGRK2.js} +23 -12
- package/dist/memory-hook-T7Y235KY.js +19 -0
- package/dist/messages-KV5ADNJB.js +17 -0
- package/dist/{migrate-5VBAP52B.js → migrate-AX3HOKOO.js} +10 -7
- package/dist/{paths-XA2RJH4S.js → paths-WMVV7ZAJ.js} +1 -1
- package/dist/{server-WWGVDFPW.js → server-MFRYOGHR.js} +21 -23
- package/dist/{server-AJCOURH7.js → server-SFLCAZFR.js} +221 -27
- package/dist/{setup-server-VDY64CWW.js → setup-server-YWAPKZVE.js} +26 -26
- package/dist/{store-BY7S6IFN.js → store-PGHQASBC.js} +11 -8
- package/dist/{task-dependency-resolver-L6UUMTHK.js → task-dependency-resolver-YQKADDEU.js} +24 -10
- package/dist/{task-executor-XBNJLUCS.js → task-executor-LWAWD225.js} +4 -4
- package/dist/{tool-adapter-IVX2XQJE.js → tool-adapter-VKLUZSQS.js} +1 -1
- package/dist/{tool-index-FTERJSZK.js → tool-index-YEWDF5CK.js} +5 -5
- package/dist/{transcript-IM7G25OS.js → transcript-4Y3Z2BJ3.js} +3 -3
- package/dist/web/assets/Config-MNxA69ib.js +1 -0
- package/dist/web/assets/Conversations-Dk958paA.js +1 -0
- package/dist/web/assets/Dashboard-dM18fGOm.js +1 -0
- package/dist/web/assets/Hooks-D2griQnI.js +1 -0
- package/dist/web/assets/Mcp-CtWNzwsz.js +1 -0
- package/dist/web/assets/Memory-CfLwH45G.js +1 -0
- package/dist/web/assets/Plugins-3hoJprFo.js +1 -0
- package/dist/web/assets/SearchInput-CpcETdpE.js +1 -0
- package/dist/web/assets/Soul-BSxE73aK.js +1 -0
- package/dist/web/assets/Tasks-DkCkfu3A.js +1 -0
- package/dist/web/assets/TelegramSettingsPanel-BRzc5G6e.js +1 -0
- package/dist/web/assets/Tools-Du8B8Mb4.js +1 -0
- package/dist/web/assets/Wallet-BLILP2Gn.js +1 -0
- package/dist/web/assets/Workspace-qklcXpXV.js +1 -0
- package/dist/web/assets/index-BwEPTTKp.js +90 -0
- package/dist/web/assets/index-noejUsK7.css +1 -0
- package/dist/web/assets/{index.es-DitvF-9H.js → index.es-DdpKlnGb.js} +1 -1
- package/dist/web/assets/useToolManager-tdxkKn3H.js +1 -0
- package/dist/web/assets/utils-CnsbSMo4.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +7 -12
- package/src/templates/HEARTBEAT.md +5 -0
- package/dist/memory-hook-VUNWZ3NY.js +0 -19
- package/dist/web/assets/index-BfYCdwLI.js +0 -80
- package/dist/web/assets/index-DmlyQVhR.css +0 -1
- package/dist/{chunk-WFTC3JJW.js → chunk-3NO7QU7W.js} +1 -1
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getClient
|
|
3
|
+
} from "./chunk-EKCXKL5M.js";
|
|
1
4
|
import {
|
|
2
5
|
getErrorMessage
|
|
3
6
|
} from "./chunk-3UFPFWYP.js";
|
|
4
7
|
import {
|
|
5
8
|
createLogger
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-V3S3NXBQ.js";
|
|
7
10
|
|
|
8
11
|
// src/agent/tools/telegram/gifts/get-my-gifts.ts
|
|
9
12
|
import { Type } from "@sinclair/typebox";
|
|
@@ -12,12 +15,12 @@ var log = createLogger("Tools");
|
|
|
12
15
|
var giftCatalogCache = null;
|
|
13
16
|
var CATALOG_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
14
17
|
function extractEmoji(sticker) {
|
|
15
|
-
if (!sticker
|
|
18
|
+
if (!("attributes" in sticker)) return null;
|
|
16
19
|
const attr = sticker.attributes.find(
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS API response is untyped
|
|
18
20
|
(a) => a.className === "DocumentAttributeSticker" || a.className === "DocumentAttributeCustomEmoji"
|
|
19
21
|
);
|
|
20
|
-
|
|
22
|
+
if (!attr) return null;
|
|
23
|
+
return "alt" in attr ? attr.alt || null : null;
|
|
21
24
|
}
|
|
22
25
|
var telegramGetMyGiftsTool = {
|
|
23
26
|
name: "telegram_get_my_gifts",
|
|
@@ -58,6 +61,15 @@ var telegramGetMyGiftsTool = {
|
|
|
58
61
|
}),
|
|
59
62
|
category: "data-bearing"
|
|
60
63
|
};
|
|
64
|
+
function extractAttrSummary(attr) {
|
|
65
|
+
if (!attr || !("name" in attr) || !("rarity" in attr)) return null;
|
|
66
|
+
const rarity = attr.rarity;
|
|
67
|
+
const permille = "permille" in rarity ? rarity.permille : null;
|
|
68
|
+
return {
|
|
69
|
+
name: attr.name,
|
|
70
|
+
rarityPercent: permille ? (Number(permille) / 10).toFixed(1) + "%" : null
|
|
71
|
+
};
|
|
72
|
+
}
|
|
61
73
|
var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
62
74
|
try {
|
|
63
75
|
const {
|
|
@@ -68,7 +80,7 @@ var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
|
68
80
|
excludeSaved,
|
|
69
81
|
sortByValue = false
|
|
70
82
|
} = params;
|
|
71
|
-
const gramJsClient = context.bridge
|
|
83
|
+
const gramJsClient = getClient(context.bridge);
|
|
72
84
|
const targetUserId = viewSender ? context.senderId.toString() : userId;
|
|
73
85
|
const peer = targetUserId ? await gramJsClient.getEntity(targetUserId) : new Api.InputPeerSelf();
|
|
74
86
|
let catalogMap;
|
|
@@ -76,12 +88,11 @@ var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
|
76
88
|
catalogMap = giftCatalogCache.map;
|
|
77
89
|
} else {
|
|
78
90
|
const prevHash = giftCatalogCache?.hash ?? 0;
|
|
79
|
-
const catalog = await gramJsClient.invoke(
|
|
80
|
-
|
|
81
|
-
);
|
|
82
|
-
if (catalog.gifts && catalog.gifts.length > 0) {
|
|
91
|
+
const catalog = await gramJsClient.invoke(new Api.payments.GetStarGifts({ hash: prevHash }));
|
|
92
|
+
if (catalog.className === "payments.StarGifts" && catalog.gifts.length > 0) {
|
|
83
93
|
catalogMap = /* @__PURE__ */ new Map();
|
|
84
94
|
for (const catalogGift of catalog.gifts) {
|
|
95
|
+
if (catalogGift.className !== "StarGift") continue;
|
|
85
96
|
const id = catalogGift.id?.toString();
|
|
86
97
|
if (id) {
|
|
87
98
|
catalogMap.set(id, {
|
|
@@ -102,7 +113,7 @@ var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
|
102
113
|
catalogMap = giftCatalogCache?.map ?? /* @__PURE__ */ new Map();
|
|
103
114
|
giftCatalogCache = {
|
|
104
115
|
map: catalogMap,
|
|
105
|
-
hash: catalog.hash ?? giftCatalogCache?.hash ?? 0,
|
|
116
|
+
hash: catalog.className === "payments.StarGifts" ? catalog.hash ?? 0 : giftCatalogCache?.hash ?? 0,
|
|
106
117
|
expiresAt: Date.now() + CATALOG_CACHE_TTL_MS
|
|
107
118
|
};
|
|
108
119
|
}
|
|
@@ -119,19 +130,15 @@ var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
|
119
130
|
);
|
|
120
131
|
const gifts = (result.gifts || []).map((savedGift) => {
|
|
121
132
|
const gift = savedGift.gift;
|
|
122
|
-
const isCollectible = gift
|
|
133
|
+
const isCollectible = gift.className === "StarGiftUnique";
|
|
123
134
|
const lookupId = isCollectible ? gift.giftId?.toString() : gift.id?.toString();
|
|
124
135
|
const catalogInfo = catalogMap.get(lookupId);
|
|
125
136
|
const isLimited = isCollectible || catalogInfo?.limited === true;
|
|
126
|
-
const extractAttrSummary = (attr) => attr ? {
|
|
127
|
-
name: attr.name,
|
|
128
|
-
rarityPercent: attr.rarityPermille ? (attr.rarityPermille / 10).toFixed(1) + "%" : null
|
|
129
|
-
} : null;
|
|
130
137
|
const compactGift = {
|
|
131
138
|
date: savedGift.date,
|
|
132
139
|
isLimited,
|
|
133
140
|
isCollectible,
|
|
134
|
-
stars: gift
|
|
141
|
+
stars: isCollectible ? void 0 : gift.stars?.toString(),
|
|
135
142
|
emoji: catalogInfo?.emoji || null,
|
|
136
143
|
msgId: savedGift.msgId,
|
|
137
144
|
savedId: savedGift.savedId?.toString(),
|
|
@@ -143,30 +150,29 @@ var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
|
143
150
|
compactGift.num = gift.num;
|
|
144
151
|
compactGift.slug = gift.slug;
|
|
145
152
|
compactGift.nftLink = `t.me/nft/${gift.slug}`;
|
|
146
|
-
const modelAttr = gift.attributes
|
|
147
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS API response is untyped
|
|
153
|
+
const modelAttr = gift.attributes.find(
|
|
148
154
|
(a) => a.className === "StarGiftAttributeModel"
|
|
149
155
|
);
|
|
150
|
-
const patternAttr = gift.attributes
|
|
151
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS API response is untyped
|
|
156
|
+
const patternAttr = gift.attributes.find(
|
|
152
157
|
(a) => a.className === "StarGiftAttributePattern"
|
|
153
158
|
);
|
|
154
|
-
const backdropAttr = gift.attributes
|
|
155
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS API response is untyped
|
|
159
|
+
const backdropAttr = gift.attributes.find(
|
|
156
160
|
(a) => a.className === "StarGiftAttributeBackdrop"
|
|
157
161
|
);
|
|
158
162
|
compactGift.model = extractAttrSummary(modelAttr);
|
|
159
163
|
compactGift.pattern = extractAttrSummary(patternAttr);
|
|
160
164
|
compactGift.backdrop = extractAttrSummary(backdropAttr);
|
|
161
165
|
} else {
|
|
166
|
+
const regularGift = gift;
|
|
162
167
|
compactGift.canUpgrade = savedGift.canUpgrade || false;
|
|
163
168
|
if (savedGift.canUpgrade) {
|
|
164
|
-
compactGift.upgradeStars =
|
|
169
|
+
compactGift.upgradeStars = regularGift.upgradeStars?.toString();
|
|
165
170
|
}
|
|
166
171
|
}
|
|
167
172
|
if (isLimited && !isCollectible) {
|
|
168
|
-
|
|
169
|
-
compactGift.
|
|
173
|
+
const regularGift = gift;
|
|
174
|
+
compactGift.availabilityRemains = catalogInfo?.availabilityRemains || regularGift.availabilityRemains;
|
|
175
|
+
compactGift.availabilityTotal = catalogInfo?.availabilityTotal || regularGift.availabilityTotal;
|
|
170
176
|
}
|
|
171
177
|
return compactGift;
|
|
172
178
|
});
|
|
@@ -187,7 +193,6 @@ var telegramGetMyGiftsExecutor = async (params, context) => {
|
|
|
187
193
|
limited: limited.length,
|
|
188
194
|
unlimited: unlimited.length,
|
|
189
195
|
collectibles: collectibles.length,
|
|
190
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS API response is untyped
|
|
191
196
|
canUpgrade: gifts.filter((g) => g.canUpgrade).length
|
|
192
197
|
},
|
|
193
198
|
totalCount: result.count
|
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
EMBEDDING_CACHE_MAX_ENTRIES,
|
|
8
8
|
EMBEDDING_CACHE_TTL_DAYS,
|
|
9
9
|
VOYAGE_BATCH_SIZE
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-J4WDJ7XS.js";
|
|
11
11
|
import {
|
|
12
12
|
fetchWithTimeout
|
|
13
13
|
} from "./chunk-XQUHC3JZ.js";
|
|
14
14
|
import {
|
|
15
15
|
LocalEmbeddingProvider
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-BT2I3ETV.js";
|
|
17
17
|
import {
|
|
18
18
|
createLogger
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-V3S3NXBQ.js";
|
|
20
20
|
|
|
21
21
|
// src/memory/embeddings/provider.ts
|
|
22
22
|
var NoopEmbeddingProvider = class {
|
|
@@ -229,8 +229,8 @@ var CachedEmbeddingProvider = class _CachedEmbeddingProvider {
|
|
|
229
229
|
`Embedding cache eviction: removed ${toDelete} entries (${count} total)`
|
|
230
230
|
);
|
|
231
231
|
}
|
|
232
|
-
} catch (
|
|
233
|
-
_CachedEmbeddingProvider.log.warn({ err }, "Embedding cache eviction error");
|
|
232
|
+
} catch (error) {
|
|
233
|
+
_CachedEmbeddingProvider.log.warn({ err: error }, "Embedding cache eviction error");
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
};
|
|
@@ -13,16 +13,17 @@ import {
|
|
|
13
13
|
SESSION_SLUG_MAX_TOKENS,
|
|
14
14
|
SESSION_SLUG_RECENT_MESSAGES,
|
|
15
15
|
TOKEN_ESTIMATE_SAFETY_MARGIN
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-J4WDJ7XS.js";
|
|
17
17
|
import {
|
|
18
18
|
getUtilityModel
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-D3GT6YIY.js";
|
|
20
20
|
import {
|
|
21
21
|
createLogger
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-V3S3NXBQ.js";
|
|
23
23
|
|
|
24
24
|
// src/session/memory-hook.ts
|
|
25
|
-
import { writeFile, mkdir, readdir, readFile
|
|
25
|
+
import { writeFile, mkdir, readdir, readFile } from "fs/promises";
|
|
26
|
+
import { mkdirSync, renameSync } from "fs";
|
|
26
27
|
import { join } from "path";
|
|
27
28
|
import { complete as complete2 } from "@mariozechner/pi-ai";
|
|
28
29
|
|
|
@@ -259,9 +260,7 @@ async function summarizeWithFallback(params) {
|
|
|
259
260
|
utilityModel: params.utilityModel
|
|
260
261
|
});
|
|
261
262
|
} catch (fullError) {
|
|
262
|
-
log.warn(
|
|
263
|
-
`Full summarization failed: ${fullError instanceof Error ? fullError.message : String(fullError)}`
|
|
264
|
-
);
|
|
263
|
+
log.warn(`Full summarization failed: ${getErrorMessage(fullError)}`);
|
|
265
264
|
}
|
|
266
265
|
const smallMessages = [];
|
|
267
266
|
const oversizedNotes = [];
|
|
@@ -299,9 +298,7 @@ ${oversizedNotes.join("\n")}` : "";
|
|
|
299
298
|
chunksProcessed: result.chunksProcessed
|
|
300
299
|
};
|
|
301
300
|
} catch (partialError) {
|
|
302
|
-
log.warn(
|
|
303
|
-
`Partial summarization also failed: ${partialError instanceof Error ? partialError.message : String(partialError)}`
|
|
304
|
-
);
|
|
301
|
+
log.warn(`Partial summarization also failed: ${getErrorMessage(partialError)}`);
|
|
305
302
|
}
|
|
306
303
|
}
|
|
307
304
|
const note = `Context contained ${params.messages.length} messages (${oversizedNotes.length} were oversized). AI summarization unavailable due to size constraints. Recent conversation history was preserved.`;
|
|
@@ -352,7 +349,7 @@ Slug:`,
|
|
|
352
349
|
}
|
|
353
350
|
async function saveSessionMemory(params) {
|
|
354
351
|
try {
|
|
355
|
-
const { TELETON_ROOT } = await import("./paths-
|
|
352
|
+
const { TELETON_ROOT } = await import("./paths-WMVV7ZAJ.js");
|
|
356
353
|
const memoryDir = join(TELETON_ROOT, "memory");
|
|
357
354
|
await mkdir(memoryDir, { recursive: true });
|
|
358
355
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -405,6 +402,11 @@ This session was compacted and migrated to a new session ID. The summary above p
|
|
|
405
402
|
*Generated automatically by Teleton-AI session memory hook*
|
|
406
403
|
`;
|
|
407
404
|
await writeFile(filepath, content, "utf-8");
|
|
405
|
+
const { writeSessionEndSummary } = await import("./daily-logs-3WXGYAQF.js");
|
|
406
|
+
writeSessionEndSummary(summary, "compaction");
|
|
407
|
+
const { getKnowledgeIndexer } = await import("./knowledge-RRWUIO3G.js");
|
|
408
|
+
getKnowledgeIndexer()?.indexFile(filepath).catch(() => {
|
|
409
|
+
});
|
|
408
410
|
const relPath = filepath.replace(TELETON_ROOT, "~/.teleton");
|
|
409
411
|
log2.info(`Session memory saved: ${relPath}`);
|
|
410
412
|
} catch (error) {
|
|
@@ -412,53 +414,111 @@ This session was compacted and migrated to a new session ID. The summary above p
|
|
|
412
414
|
}
|
|
413
415
|
}
|
|
414
416
|
var CONSOLIDATION_THRESHOLD = 20;
|
|
415
|
-
var
|
|
417
|
+
var CONSOLIDATION_AGE_DAYS = 7;
|
|
418
|
+
var CONSOLIDATION_FALLBACK_BATCH = 10;
|
|
419
|
+
var CONSOLIDATION_MAX_TOKENS = 4e3;
|
|
420
|
+
var CONSOLIDATION_MIN_CLUSTER_SIZE = 2;
|
|
416
421
|
async function consolidateOldMemoryFiles(params) {
|
|
417
422
|
try {
|
|
418
|
-
const { TELETON_ROOT } = await import("./paths-
|
|
423
|
+
const { TELETON_ROOT } = await import("./paths-WMVV7ZAJ.js");
|
|
419
424
|
const memoryDir = join(TELETON_ROOT, "memory");
|
|
425
|
+
const archiveDir = join(memoryDir, "archived");
|
|
420
426
|
let entries;
|
|
421
427
|
try {
|
|
422
428
|
entries = await readdir(memoryDir);
|
|
423
429
|
} catch {
|
|
424
430
|
return { consolidated: 0 };
|
|
425
431
|
}
|
|
426
|
-
const
|
|
432
|
+
const cutoff = /* @__PURE__ */ new Date();
|
|
433
|
+
cutoff.setDate(cutoff.getDate() - CONSOLIDATION_AGE_DAYS);
|
|
434
|
+
const cutoffStr = cutoff.toISOString().split("T")[0];
|
|
435
|
+
const sessionFiles = entries.filter(
|
|
436
|
+
(f) => /^\d{4}-\d{2}-\d{2}-.+\.md$/.test(f) && !f.startsWith("consolidated-") && f.slice(0, 10) < cutoffStr
|
|
437
|
+
).sort();
|
|
427
438
|
if (sessionFiles.length < CONSOLIDATION_THRESHOLD) {
|
|
428
439
|
return { consolidated: 0 };
|
|
429
440
|
}
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
441
|
+
const fileKeywords = [];
|
|
442
|
+
for (const file of sessionFiles) {
|
|
443
|
+
const slug = file.slice(11).replace(/\.md$/, "");
|
|
444
|
+
const slugWords = slug.split("-").filter((w) => w.length > 3);
|
|
445
|
+
let headingWords = [];
|
|
446
|
+
try {
|
|
447
|
+
const text = await readFile(join(memoryDir, file), "utf-8");
|
|
448
|
+
const firstHeading = text.split("\n").find((l) => l.startsWith("#")) ?? "";
|
|
449
|
+
headingWords = firstHeading.replace(/^#+\s*/, "").toLowerCase().split(/\W+/).filter((w) => w.length > 3);
|
|
450
|
+
} catch {
|
|
451
|
+
}
|
|
452
|
+
fileKeywords.push({ file, keywords: /* @__PURE__ */ new Set([...slugWords, ...headingWords]) });
|
|
437
453
|
}
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
455
|
+
const clusters = [];
|
|
456
|
+
for (let i = 0; i < fileKeywords.length; i++) {
|
|
457
|
+
if (assigned.has(fileKeywords[i].file)) continue;
|
|
458
|
+
const cluster = [fileKeywords[i].file];
|
|
459
|
+
assigned.add(fileKeywords[i].file);
|
|
460
|
+
for (let j = i + 1; j < fileKeywords.length; j++) {
|
|
461
|
+
if (assigned.has(fileKeywords[j].file)) continue;
|
|
462
|
+
const hasOverlap = [...fileKeywords[i].keywords].some(
|
|
463
|
+
(k) => fileKeywords[j].keywords.has(k)
|
|
464
|
+
);
|
|
465
|
+
if (hasOverlap) {
|
|
466
|
+
cluster.push(fileKeywords[j].file);
|
|
467
|
+
assigned.add(fileKeywords[j].file);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (cluster.length >= CONSOLIDATION_MIN_CLUSTER_SIZE) {
|
|
471
|
+
clusters.push(cluster);
|
|
472
|
+
}
|
|
454
473
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
474
|
+
if (clusters.length === 0) {
|
|
475
|
+
log2.info("No thematic clusters found, falling back to chronological grouping");
|
|
476
|
+
clusters.push(sessionFiles.slice(0, CONSOLIDATION_FALLBACK_BATCH));
|
|
477
|
+
}
|
|
478
|
+
mkdirSync(archiveDir, { recursive: true });
|
|
479
|
+
let totalConsolidated = 0;
|
|
480
|
+
for (const cluster of clusters) {
|
|
481
|
+
log2.info(
|
|
482
|
+
`Consolidating cluster of ${cluster.length} files: ${cluster.slice(0, 3).join(", ")}${cluster.length > 3 ? "\u2026" : ""}`
|
|
483
|
+
);
|
|
484
|
+
const contents = [];
|
|
485
|
+
for (const file of cluster) {
|
|
486
|
+
const text = await readFile(join(memoryDir, file), "utf-8");
|
|
487
|
+
contents.push(`--- ${file} ---
|
|
488
|
+
${text}`);
|
|
489
|
+
}
|
|
490
|
+
const combined = contents.join("\n\n");
|
|
491
|
+
const sourceList = cluster.map((f) => `- ${f}`).join("\n");
|
|
492
|
+
let summary;
|
|
493
|
+
try {
|
|
494
|
+
const result = await summarizeWithFallback({
|
|
495
|
+
messages: [{ role: "user", content: combined, timestamp: Date.now() }],
|
|
496
|
+
apiKey: params.apiKey,
|
|
497
|
+
contextWindow: DEFAULT_CONTEXT_WINDOW,
|
|
498
|
+
maxSummaryTokens: CONSOLIDATION_MAX_TOKENS,
|
|
499
|
+
customInstructions: `Consolidate these session memories into a single comprehensive summary.
|
|
500
|
+
Source files:
|
|
501
|
+
${sourceList}
|
|
502
|
+
|
|
503
|
+
Preserve key facts, decisions, patterns, and important context. Remove redundancy. Organize by topic. You may reference source file names when relevant.`,
|
|
504
|
+
provider: params.provider,
|
|
505
|
+
utilityModel: params.utilityModel
|
|
506
|
+
});
|
|
507
|
+
summary = result.summary;
|
|
508
|
+
} catch (error) {
|
|
509
|
+
log2.warn({ err: error }, "Consolidation summary failed for cluster, skipping");
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
const dateOf = (f) => f.slice(0, 10);
|
|
513
|
+
const dateRange = `${dateOf(cluster[0])}_to_${dateOf(cluster[cluster.length - 1])}`;
|
|
514
|
+
const outFile = `consolidated-${dateRange}.md`;
|
|
515
|
+
const outContent = `# Consolidated Session Memories
|
|
459
516
|
|
|
460
|
-
##
|
|
461
|
-
|
|
517
|
+
## Metadata
|
|
518
|
+
|
|
519
|
+
- **Period**: ${cluster[0]} \u2192 ${cluster[cluster.length - 1]}
|
|
520
|
+
- **Source Files** (${cluster.length}):
|
|
521
|
+
${sourceList}
|
|
462
522
|
|
|
463
523
|
## Summary
|
|
464
524
|
|
|
@@ -466,14 +526,16 @@ ${summary}
|
|
|
466
526
|
|
|
467
527
|
---
|
|
468
528
|
|
|
469
|
-
*Consolidated from ${
|
|
529
|
+
*Consolidated from ${cluster.length} session files. Originals archived in memory/archived/.*
|
|
470
530
|
`;
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
531
|
+
await writeFile(join(memoryDir, outFile), outContent, "utf-8");
|
|
532
|
+
for (const file of cluster) {
|
|
533
|
+
renameSync(join(memoryDir, file), join(archiveDir, file));
|
|
534
|
+
}
|
|
535
|
+
totalConsolidated += cluster.length;
|
|
536
|
+
log2.info(`Consolidated ${cluster.length} files \u2192 ${outFile}`);
|
|
474
537
|
}
|
|
475
|
-
|
|
476
|
-
return { consolidated: batch.length };
|
|
538
|
+
return { consolidated: totalConsolidated };
|
|
477
539
|
} catch (error) {
|
|
478
540
|
log2.error({ err: error }, "Memory consolidation failed");
|
|
479
541
|
return { consolidated: 0 };
|
|
@@ -481,6 +543,7 @@ ${summary}
|
|
|
481
543
|
}
|
|
482
544
|
|
|
483
545
|
export {
|
|
546
|
+
summarizeViaClaude,
|
|
484
547
|
summarizeWithFallback,
|
|
485
548
|
saveSessionMemory,
|
|
486
549
|
consolidateOldMemoryFiles
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConfigSchema,
|
|
3
3
|
expandPath
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2UUGRY5B.js";
|
|
5
5
|
import {
|
|
6
6
|
COINGECKO_API_URL,
|
|
7
7
|
tonapiFetch
|
|
8
8
|
} from "./chunk-VFA7QMCZ.js";
|
|
9
9
|
import {
|
|
10
10
|
getSupportedProviders
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-TFTNZZDH.js";
|
|
12
12
|
import {
|
|
13
13
|
fetchWithTimeout
|
|
14
14
|
} from "./chunk-XQUHC3JZ.js";
|
|
15
15
|
import {
|
|
16
16
|
TELETON_ROOT
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-L653KKCR.js";
|
|
18
18
|
import {
|
|
19
19
|
createLogger
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-V3S3NXBQ.js";
|
|
21
21
|
|
|
22
22
|
// src/ton/endpoint.ts
|
|
23
23
|
var ENDPOINT_CACHE_TTL_MS = 6e4;
|
|
@@ -807,6 +807,40 @@ var CONFIGURABLE_KEYS = {
|
|
|
807
807
|
mask: identity,
|
|
808
808
|
parse: identity
|
|
809
809
|
},
|
|
810
|
+
// ─── Heartbeat ─────────────────────────────────────────────────────
|
|
811
|
+
"heartbeat.enabled": {
|
|
812
|
+
type: "boolean",
|
|
813
|
+
category: "Agent",
|
|
814
|
+
label: "Heartbeat Enabled",
|
|
815
|
+
description: "Enable periodic heartbeat timer",
|
|
816
|
+
sensitive: false,
|
|
817
|
+
hotReload: "instant",
|
|
818
|
+
validate: enumValidator(["true", "false"]),
|
|
819
|
+
mask: identity,
|
|
820
|
+
parse: (v) => v === "true"
|
|
821
|
+
},
|
|
822
|
+
"heartbeat.interval_ms": {
|
|
823
|
+
type: "number",
|
|
824
|
+
category: "Agent",
|
|
825
|
+
label: "Heartbeat Interval (ms)",
|
|
826
|
+
description: "Heartbeat interval in milliseconds (min 60000)",
|
|
827
|
+
sensitive: false,
|
|
828
|
+
hotReload: "restart",
|
|
829
|
+
validate: numberInRange(6e4, 864e5),
|
|
830
|
+
mask: identity,
|
|
831
|
+
parse: (v) => Number(v)
|
|
832
|
+
},
|
|
833
|
+
"heartbeat.self_configurable": {
|
|
834
|
+
type: "boolean",
|
|
835
|
+
category: "Agent",
|
|
836
|
+
label: "Heartbeat Self-Configurable",
|
|
837
|
+
description: "Allow agent to modify heartbeat config at runtime",
|
|
838
|
+
sensitive: false,
|
|
839
|
+
hotReload: "instant",
|
|
840
|
+
validate: enumValidator(["true", "false"]),
|
|
841
|
+
mask: identity,
|
|
842
|
+
parse: (v) => v === "true"
|
|
843
|
+
},
|
|
810
844
|
// ─── Developer ─────────────────────────────────────────────────────
|
|
811
845
|
"dev.hot_reload": {
|
|
812
846
|
type: "boolean",
|