instar 0.28.77 → 0.28.78
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/dashboard/index.html +184 -4
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +46 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/monitoring/TokenLedger.d.ts +39 -0
- package/dist/monitoring/TokenLedger.d.ts.map +1 -1
- package/dist/monitoring/TokenLedger.js +110 -13
- package/dist/monitoring/TokenLedger.js.map +1 -1
- package/dist/monitoring/TokenLedgerPoller.d.ts.map +1 -1
- package/dist/monitoring/TokenLedgerPoller.js +8 -8
- package/dist/monitoring/TokenLedgerPoller.js.map +1 -1
- package/dist/server/AgentServer.d.ts +4 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +14 -1
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +8 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +98 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/BackfillCore.d.ts +70 -0
- package/dist/threadline/BackfillCore.d.ts.map +1 -0
- package/dist/threadline/BackfillCore.js +117 -0
- package/dist/threadline/BackfillCore.js.map +1 -0
- package/dist/threadline/ListenerSessionManager.d.ts +35 -0
- package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
- package/dist/threadline/ListenerSessionManager.js +41 -0
- package/dist/threadline/ListenerSessionManager.js.map +1 -1
- package/dist/threadline/TelegramBridge.d.ts +140 -0
- package/dist/threadline/TelegramBridge.d.ts.map +1 -0
- package/dist/threadline/TelegramBridge.js +224 -0
- package/dist/threadline/TelegramBridge.js.map +1 -0
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.js +5 -0
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
- package/dist/threadline/ThreadlineObservability.d.ts +95 -0
- package/dist/threadline/ThreadlineObservability.d.ts.map +1 -0
- package/dist/threadline/ThreadlineObservability.js +310 -0
- package/dist/threadline/ThreadlineObservability.js.map +1 -0
- package/package.json +1 -1
- package/scripts/threadline-bridge-backfill.mjs +379 -0
- package/src/data/builtin-manifest.json +47 -47
- package/upgrades/0.28.78.md +90 -0
- package/upgrades/side-effects/threadline-bridge-backfill.md +203 -0
- package/upgrades/side-effects/threadline-observability-tab.md +206 -0
- package/upgrades/side-effects/threadline-tg-bridge-module.md +196 -0
- package/upgrades/side-effects/token-ledger-bounded-scan.md +230 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadlineObservability — read-only views over the canonical threadline
|
|
3
|
+
* inbox + outbox + bridge bindings, powering the dashboard "Threadline" tab.
|
|
4
|
+
*
|
|
5
|
+
* Sources of truth (single source per class of data — no duplication):
|
|
6
|
+
* - .instar/threadline/inbox.jsonl.active — every inbound message (PR #113).
|
|
7
|
+
* - .instar/threadline/outbox.jsonl.active — every outbound message (this PR).
|
|
8
|
+
* - .instar/threadline/telegram-bridge-bindings.json — thread → topic links (PR #117).
|
|
9
|
+
* - .instar/threadline/known-agents.json — fingerprint → display name.
|
|
10
|
+
*
|
|
11
|
+
* This class is **observational only** — it reads files, computes summaries,
|
|
12
|
+
* and answers queries. It never writes, mutates, blocks, or gates.
|
|
13
|
+
*
|
|
14
|
+
* Performance: reads are lazy and stream-friendly. The inbox and outbox
|
|
15
|
+
* files are append-only JSONL, so we do a full-file scan with line parsing
|
|
16
|
+
* on every query. For agents with millions of messages this becomes
|
|
17
|
+
* slow — at that point the right answer is to add an FTS5 index, but
|
|
18
|
+
* today every agent in production has <10K threadline messages and
|
|
19
|
+
* sub-100ms scans are fine.
|
|
20
|
+
*/
|
|
21
|
+
import fs from 'node:fs';
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
export class ThreadlineObservability {
|
|
24
|
+
stateDir;
|
|
25
|
+
nameCache = null; // fingerprint → display name
|
|
26
|
+
nameCacheReadAt = 0;
|
|
27
|
+
constructor(opts) {
|
|
28
|
+
this.stateDir = opts.stateDir;
|
|
29
|
+
}
|
|
30
|
+
// ── Public API ─────────────────────────────────────────────────
|
|
31
|
+
listThreads(filters) {
|
|
32
|
+
const inbox = this.readJsonl(this.inboxPath());
|
|
33
|
+
const outbox = this.readJsonl(this.outboxPath());
|
|
34
|
+
const bindings = this.loadBindings();
|
|
35
|
+
const resume = this.loadThreadResume();
|
|
36
|
+
const byThread = new Map();
|
|
37
|
+
for (const entry of inbox) {
|
|
38
|
+
if (!entry.threadId)
|
|
39
|
+
continue;
|
|
40
|
+
const slot = byThread.get(entry.threadId) ?? { in: [], out: [] };
|
|
41
|
+
slot.in.push(entry);
|
|
42
|
+
byThread.set(entry.threadId, slot);
|
|
43
|
+
}
|
|
44
|
+
for (const entry of outbox) {
|
|
45
|
+
if (!entry.threadId)
|
|
46
|
+
continue;
|
|
47
|
+
const slot = byThread.get(entry.threadId) ?? { in: [], out: [] };
|
|
48
|
+
slot.out.push(entry);
|
|
49
|
+
byThread.set(entry.threadId, slot);
|
|
50
|
+
}
|
|
51
|
+
const summaries = [];
|
|
52
|
+
for (const [threadId, slot] of byThread) {
|
|
53
|
+
const allTimes = [...slot.in.map(e => e.timestamp), ...slot.out.map(e => e.timestamp)].sort();
|
|
54
|
+
if (allTimes.length === 0)
|
|
55
|
+
continue;
|
|
56
|
+
const firstSeen = allTimes[0];
|
|
57
|
+
const lastSeen = allTimes[allTimes.length - 1];
|
|
58
|
+
// Counterparty: inbound senders > outbound recipients > unknown
|
|
59
|
+
const counterpartyId = slot.in[0]?.from
|
|
60
|
+
?? slot.out[0]?.to
|
|
61
|
+
?? '(unknown)';
|
|
62
|
+
// Prefer the senderName/recipientName the message itself carried;
|
|
63
|
+
// fall back to known-agents.json lookup when the message-side name
|
|
64
|
+
// is missing.
|
|
65
|
+
const inlineName = slot.in[0]?.senderName || slot.out[0]?.recipientName;
|
|
66
|
+
const counterpartyName = inlineName && inlineName.length > 0
|
|
67
|
+
? inlineName
|
|
68
|
+
: this.resolveAgentName(counterpartyId);
|
|
69
|
+
const binding = bindings.get(threadId) ?? null;
|
|
70
|
+
const hasSpawnedSession = !!resume[threadId];
|
|
71
|
+
const avgLatency = this.computeAvgResponseLatencyMs(slot.in, slot.out);
|
|
72
|
+
summaries.push({
|
|
73
|
+
threadId,
|
|
74
|
+
remoteAgent: counterpartyId,
|
|
75
|
+
remoteAgentName: counterpartyName,
|
|
76
|
+
messageCount: slot.in.length + slot.out.length,
|
|
77
|
+
inboundCount: slot.in.length,
|
|
78
|
+
outboundCount: slot.out.length,
|
|
79
|
+
firstSeen,
|
|
80
|
+
lastSeen,
|
|
81
|
+
avgResponseLatencyMs: avgLatency,
|
|
82
|
+
bridge: binding
|
|
83
|
+
? { topicId: binding.topicId, topicName: binding.topicName, createdAt: binding.createdAt, lastMessageAt: binding.lastMessageAt }
|
|
84
|
+
: null,
|
|
85
|
+
hasSpawnedSession,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Apply filters
|
|
89
|
+
let filtered = summaries;
|
|
90
|
+
if (filters?.remoteAgent) {
|
|
91
|
+
const needle = filters.remoteAgent.toLowerCase();
|
|
92
|
+
filtered = filtered.filter(t => t.remoteAgent.toLowerCase().includes(needle) || t.remoteAgentName.toLowerCase().includes(needle));
|
|
93
|
+
}
|
|
94
|
+
if (filters?.sinceIso) {
|
|
95
|
+
filtered = filtered.filter(t => t.lastSeen >= filters.sinceIso);
|
|
96
|
+
}
|
|
97
|
+
if (filters?.untilIso) {
|
|
98
|
+
filtered = filtered.filter(t => t.firstSeen <= filters.untilIso);
|
|
99
|
+
}
|
|
100
|
+
if (filters?.hasTopic === 'yes') {
|
|
101
|
+
filtered = filtered.filter(t => t.bridge !== null);
|
|
102
|
+
}
|
|
103
|
+
else if (filters?.hasTopic === 'no') {
|
|
104
|
+
filtered = filtered.filter(t => t.bridge === null);
|
|
105
|
+
}
|
|
106
|
+
// Sort: most recent activity first
|
|
107
|
+
filtered.sort((a, b) => b.lastSeen.localeCompare(a.lastSeen));
|
|
108
|
+
return filtered;
|
|
109
|
+
}
|
|
110
|
+
getThread(threadId) {
|
|
111
|
+
const summaries = this.listThreads();
|
|
112
|
+
const summary = summaries.find(t => t.threadId === threadId);
|
|
113
|
+
if (!summary)
|
|
114
|
+
return null;
|
|
115
|
+
const inbox = this.readJsonl(this.inboxPath()).filter(e => e.threadId === threadId);
|
|
116
|
+
const outbox = this.readJsonl(this.outboxPath()).filter(e => e.threadId === threadId);
|
|
117
|
+
const messages = [
|
|
118
|
+
...inbox.map(e => this.mapInbound(e)),
|
|
119
|
+
...outbox.map(e => this.mapOutbound(e)),
|
|
120
|
+
];
|
|
121
|
+
messages.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
122
|
+
return { ...summary, messages };
|
|
123
|
+
}
|
|
124
|
+
searchMessages(query, limit = 50) {
|
|
125
|
+
const q = query.trim();
|
|
126
|
+
if (!q)
|
|
127
|
+
return [];
|
|
128
|
+
const inbox = this.readJsonl(this.inboxPath());
|
|
129
|
+
const outbox = this.readJsonl(this.outboxPath());
|
|
130
|
+
const all = [
|
|
131
|
+
...inbox.map(e => this.mapInbound(e)),
|
|
132
|
+
...outbox.map(e => this.mapOutbound(e)),
|
|
133
|
+
];
|
|
134
|
+
all.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
135
|
+
const needle = q.toLowerCase();
|
|
136
|
+
const hits = [];
|
|
137
|
+
for (const m of all) {
|
|
138
|
+
const idx = m.text.toLowerCase().indexOf(needle);
|
|
139
|
+
if (idx === -1)
|
|
140
|
+
continue;
|
|
141
|
+
hits.push({ message: m, snippet: makeSnippet(m.text, idx, q.length) });
|
|
142
|
+
if (hits.length >= limit)
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
return hits;
|
|
146
|
+
}
|
|
147
|
+
// ── Internals ──────────────────────────────────────────────────
|
|
148
|
+
inboxPath() {
|
|
149
|
+
return path.join(this.stateDir, 'threadline', 'inbox.jsonl.active');
|
|
150
|
+
}
|
|
151
|
+
outboxPath() {
|
|
152
|
+
return path.join(this.stateDir, 'threadline', 'outbox.jsonl.active');
|
|
153
|
+
}
|
|
154
|
+
bindingsPath() {
|
|
155
|
+
return path.join(this.stateDir, 'threadline', 'telegram-bridge-bindings.json');
|
|
156
|
+
}
|
|
157
|
+
knownAgentsPath() {
|
|
158
|
+
return path.join(this.stateDir, 'threadline', 'known-agents.json');
|
|
159
|
+
}
|
|
160
|
+
threadResumePath() {
|
|
161
|
+
return path.join(this.stateDir, 'threadline', 'thread-resume-map.json');
|
|
162
|
+
}
|
|
163
|
+
readJsonl(filePath) {
|
|
164
|
+
if (!fs.existsSync(filePath))
|
|
165
|
+
return [];
|
|
166
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
167
|
+
const out = [];
|
|
168
|
+
for (const line of raw.split('\n')) {
|
|
169
|
+
const trimmed = line.trim();
|
|
170
|
+
if (!trimmed)
|
|
171
|
+
continue;
|
|
172
|
+
try {
|
|
173
|
+
out.push(JSON.parse(trimmed));
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// skip malformed
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
loadBindings() {
|
|
182
|
+
const map = new Map();
|
|
183
|
+
const file = this.bindingsPath();
|
|
184
|
+
if (!fs.existsSync(file))
|
|
185
|
+
return map;
|
|
186
|
+
try {
|
|
187
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
188
|
+
for (const b of parsed.bindings ?? []) {
|
|
189
|
+
if (b.threadId)
|
|
190
|
+
map.set(b.threadId, b);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch { /* ignore */ }
|
|
194
|
+
return map;
|
|
195
|
+
}
|
|
196
|
+
loadThreadResume() {
|
|
197
|
+
const file = this.threadResumePath();
|
|
198
|
+
if (!fs.existsSync(file))
|
|
199
|
+
return {};
|
|
200
|
+
try {
|
|
201
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
202
|
+
// ThreadResumeMap structure varies; accept any keyed map at the top level.
|
|
203
|
+
if (parsed && typeof parsed === 'object' && parsed.threads && typeof parsed.threads === 'object') {
|
|
204
|
+
return parsed.threads;
|
|
205
|
+
}
|
|
206
|
+
if (parsed && typeof parsed === 'object')
|
|
207
|
+
return parsed;
|
|
208
|
+
}
|
|
209
|
+
catch { /* ignore */ }
|
|
210
|
+
return {};
|
|
211
|
+
}
|
|
212
|
+
resolveAgentName(idOrName) {
|
|
213
|
+
if (!idOrName)
|
|
214
|
+
return '(unknown)';
|
|
215
|
+
// Cheap cache: re-read only when stale (mtime changed). For simplicity
|
|
216
|
+
// re-read every minute in the absence of an mtime-watch.
|
|
217
|
+
const STALE_MS = 60_000;
|
|
218
|
+
if (!this.nameCache || Date.now() - this.nameCacheReadAt > STALE_MS) {
|
|
219
|
+
this.nameCache = this.loadKnownAgentsCache();
|
|
220
|
+
this.nameCacheReadAt = Date.now();
|
|
221
|
+
}
|
|
222
|
+
const cached = this.nameCache.get(idOrName);
|
|
223
|
+
if (cached)
|
|
224
|
+
return cached;
|
|
225
|
+
// Try fingerprint prefix match
|
|
226
|
+
for (const [k, v] of this.nameCache) {
|
|
227
|
+
if (k.startsWith(idOrName) || idOrName.startsWith(k))
|
|
228
|
+
return v;
|
|
229
|
+
}
|
|
230
|
+
// Fingerprint-looking → first 8 chars; else the value itself
|
|
231
|
+
if (/^[a-f0-9]{16,}$/i.test(idOrName))
|
|
232
|
+
return idOrName.slice(0, 8);
|
|
233
|
+
return idOrName;
|
|
234
|
+
}
|
|
235
|
+
loadKnownAgentsCache() {
|
|
236
|
+
const map = new Map();
|
|
237
|
+
const file = this.knownAgentsPath();
|
|
238
|
+
if (!fs.existsSync(file))
|
|
239
|
+
return map;
|
|
240
|
+
try {
|
|
241
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
242
|
+
const list = Array.isArray(parsed) ? parsed : (parsed?.agents ?? []);
|
|
243
|
+
for (const a of list) {
|
|
244
|
+
const id = a.publicKey || a.fingerprint;
|
|
245
|
+
if (id && a.name)
|
|
246
|
+
map.set(id, a.name);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch { /* ignore */ }
|
|
250
|
+
return map;
|
|
251
|
+
}
|
|
252
|
+
mapInbound(e) {
|
|
253
|
+
return {
|
|
254
|
+
direction: 'in',
|
|
255
|
+
id: e.id,
|
|
256
|
+
timestamp: e.timestamp,
|
|
257
|
+
threadId: e.threadId,
|
|
258
|
+
remoteAgent: e.from,
|
|
259
|
+
remoteAgentName: e.senderName || this.resolveAgentName(e.from),
|
|
260
|
+
text: e.text,
|
|
261
|
+
trustLevel: e.trustLevel,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
mapOutbound(e) {
|
|
265
|
+
return {
|
|
266
|
+
direction: 'out',
|
|
267
|
+
id: e.id,
|
|
268
|
+
timestamp: e.timestamp,
|
|
269
|
+
threadId: e.threadId,
|
|
270
|
+
remoteAgent: e.to ?? '(unknown)',
|
|
271
|
+
remoteAgentName: e.recipientName || this.resolveAgentName(e.to ?? ''),
|
|
272
|
+
text: e.text,
|
|
273
|
+
trustLevel: 'self',
|
|
274
|
+
outcome: e.outcome,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
computeAvgResponseLatencyMs(inbound, outbound) {
|
|
278
|
+
if (inbound.length === 0 || outbound.length === 0)
|
|
279
|
+
return null;
|
|
280
|
+
const sortedIn = [...inbound].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
281
|
+
const sortedOut = [...outbound].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
282
|
+
const latencies = [];
|
|
283
|
+
let outIdx = 0;
|
|
284
|
+
for (const inMsg of sortedIn) {
|
|
285
|
+
const inMs = Date.parse(inMsg.timestamp);
|
|
286
|
+
while (outIdx < sortedOut.length && Date.parse(sortedOut[outIdx].timestamp) <= inMs) {
|
|
287
|
+
outIdx++;
|
|
288
|
+
}
|
|
289
|
+
if (outIdx < sortedOut.length) {
|
|
290
|
+
const outMs = Date.parse(sortedOut[outIdx].timestamp);
|
|
291
|
+
latencies.push(outMs - inMs);
|
|
292
|
+
outIdx++;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (latencies.length === 0)
|
|
296
|
+
return null;
|
|
297
|
+
return Math.round(latencies.reduce((a, b) => a + b, 0) / latencies.length);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function makeSnippet(text, matchStart, matchLen) {
|
|
301
|
+
const HEAD = 60;
|
|
302
|
+
const TAIL = 60;
|
|
303
|
+
const start = Math.max(0, matchStart - HEAD);
|
|
304
|
+
const end = Math.min(text.length, matchStart + matchLen + TAIL);
|
|
305
|
+
const left = (start > 0 ? '…' : '') + text.slice(start, matchStart);
|
|
306
|
+
const matched = `«${text.slice(matchStart, matchStart + matchLen)}»`;
|
|
307
|
+
const right = text.slice(matchStart + matchLen, end) + (end < text.length ? '…' : '');
|
|
308
|
+
return left + matched + right;
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=ThreadlineObservability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadlineObservability.js","sourceRoot":"","sources":["../../src/threadline/ThreadlineObservability.ts"],"names":[],"mappings":"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"}
|