forked from doctly/switchboard
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlocal-transcript-activity.js
More file actions
53 lines (44 loc) · 2.06 KB
/
Copy pathlocal-transcript-activity.js
File metadata and controls
53 lines (44 loc) · 2.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// see .ai/contexts/session-state.md
'use strict';
const { subagentParentFromParts } = require('./subagent-attribution');
const SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const DEFAULT_IPC_MIN_MS = 1000;
// top-level transcript only, a subagent leg is out of scope — see .ai/contexts/session-state.md
function sessionIdFromWatchParts(parts) {
if (!Array.isArray(parts) || parts.length !== 2) return null;
const basename = parts[1];
if (typeof basename !== 'string' || !basename.endsWith('.jsonl')) return null;
const sessionId = basename.slice(0, -'.jsonl'.length);
return SESSION_ID_RE.test(sessionId) ? sessionId : null;
}
// hasPty() gates out a row the OSC path already owns — see .ai/contexts/session-state.md
function createLocalTranscriptTracker(opts = {}) {
const ipcMinMs = opts.ipcMinMs || DEFAULT_IPC_MIN_MS;
const now = opts.now || Date.now;
const hasPty = typeof opts.hasPty === 'function' ? opts.hasPty : () => false;
const ipcAt = new Map();
function record(parts) {
const sessionId = sessionIdFromWatchParts(parts);
if (sessionId) {
if (hasPty(sessionId)) return null;
const t = now();
const last = ipcAt.has(sessionId) ? ipcAt.get(sessionId) : -Infinity;
if (t - last < ipcMinMs) return null;
ipcAt.set(sessionId, t);
return { sessionId, at: t };
}
// subagent leg fallback (issue #247) — see .ai/contexts/subagent-observability.md
const attribution = subagentParentFromParts(parts);
if (!attribution) return null;
const { parentSessionId, agentId } = attribution;
if (hasPty(parentSessionId)) return null;
const key = 'sub:' + parentSessionId; // distinct namespace: never collides with a UUID sessionId key
const t = now();
const last = ipcAt.has(key) ? ipcAt.get(key) : -Infinity;
if (t - last < ipcMinMs) return null;
ipcAt.set(key, t);
return { parentSessionId, agentId, at: t, kind: 'subagent' };
}
return { record };
}
module.exports = { createLocalTranscriptTracker, sessionIdFromWatchParts, SESSION_ID_RE };