agentgui 1.0.718 → 1.0.720
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/lib/jsonl-watcher.js +46 -18
- package/package.json +1 -1
package/lib/jsonl-watcher.js
CHANGED
|
@@ -12,7 +12,7 @@ export class JsonlWatcher {
|
|
|
12
12
|
this._owned = ownedSessionIds;
|
|
13
13
|
this._tails = new Map();
|
|
14
14
|
this._convMap = new Map();
|
|
15
|
-
this.
|
|
15
|
+
this._emitted = new Map();
|
|
16
16
|
this._timers = new Map();
|
|
17
17
|
this._seqs = new Map();
|
|
18
18
|
this._streaming = new Set();
|
|
@@ -42,7 +42,7 @@ export class JsonlWatcher {
|
|
|
42
42
|
this._convMap.delete(sid);
|
|
43
43
|
this._seqs.delete(sid);
|
|
44
44
|
this._streaming.delete(sid);
|
|
45
|
-
for (const key of [...this.
|
|
45
|
+
for (const key of [...this._emitted.keys()]) if (key.startsWith(`${sid}:`)) this._emitted.delete(key);
|
|
46
46
|
for (const [fp, s] of this._tails.entries()) {
|
|
47
47
|
if (!fp.includes(sid)) continue;
|
|
48
48
|
if (s.fd !== null) try { fs.closeSync(s.fd); } catch (_) {}
|
|
@@ -56,7 +56,7 @@ export class JsonlWatcher {
|
|
|
56
56
|
removeAllConversations() {
|
|
57
57
|
for (const s of this._tails.values()) if (s.fd !== null) try { fs.closeSync(s.fd); } catch (_) {}
|
|
58
58
|
for (const t of this._timers.values()) clearTimeout(t);
|
|
59
|
-
this._tails.clear(); this._convMap.clear(); this.
|
|
59
|
+
this._tails.clear(); this._convMap.clear(); this._emitted.clear();
|
|
60
60
|
this._timers.clear(); this._seqs.clear(); this._streaming.clear();
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -114,7 +114,8 @@ export class JsonlWatcher {
|
|
|
114
114
|
if (this._convMap.has(sid)) return this._convMap.get(sid);
|
|
115
115
|
const found = this._q.getConversations().find(c => c.claudeSessionId === sid);
|
|
116
116
|
if (found) { this._convMap.set(sid, found.id); return found.id; }
|
|
117
|
-
if (e.type
|
|
117
|
+
if (e.type === 'queue-operation' || e.type === 'last-prompt') return null;
|
|
118
|
+
if (e.type === 'user' && e.isMeta) return null;
|
|
118
119
|
const cwd = e.cwd || process.cwd();
|
|
119
120
|
const branch = e.gitBranch || '';
|
|
120
121
|
const base = path.basename(cwd);
|
|
@@ -132,6 +133,13 @@ export class JsonlWatcher {
|
|
|
132
133
|
this._bc({ type: 'streaming_progress', sessionId: sid, conversationId: cid, block, blockRole: role, seq: this._seq(sid), timestamp: Date.now(), ...extra });
|
|
133
134
|
}
|
|
134
135
|
|
|
136
|
+
_emitBlocks(cid, sid, blocks, role) {
|
|
137
|
+
for (const b of blocks) {
|
|
138
|
+
if (!b || !b.type) continue;
|
|
139
|
+
this._emit(cid, sid, b, role);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
135
143
|
_startStreaming(cid, sid) {
|
|
136
144
|
if (this._streaming.has(sid)) return;
|
|
137
145
|
this._streaming.add(sid);
|
|
@@ -145,11 +153,17 @@ export class JsonlWatcher {
|
|
|
145
153
|
}
|
|
146
154
|
|
|
147
155
|
_route(cid, sid, e) {
|
|
148
|
-
if (e.type === 'queue-operation' || (e.type === 'user' && e.isMeta)) return;
|
|
156
|
+
if (e.type === 'queue-operation' || e.type === 'last-prompt' || (e.type === 'user' && e.isMeta)) return;
|
|
157
|
+
|
|
158
|
+
if (e.isApiErrorMessage && e.error === 'rate_limit') {
|
|
159
|
+
this._bc({ type: 'streaming_error', sessionId: sid, conversationId: cid, error: 'Rate limit hit', recoverable: true, timestamp: Date.now() });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
149
162
|
|
|
150
163
|
if (e.type === 'system') {
|
|
151
164
|
if (e.subtype === 'init') { this._startStreaming(cid, sid); return; }
|
|
152
165
|
if (e.subtype === 'turn_duration' || e.subtype === 'stop_hook_summary') { this._endStreaming(cid, sid); return; }
|
|
166
|
+
this._startStreaming(cid, sid);
|
|
153
167
|
this._emit(cid, sid, { type: 'system', subtype: e.subtype, model: e.model, cwd: e.cwd, tools: e.tools, preTokens: e.compactMetadata?.preTokens }, 'system');
|
|
154
168
|
return;
|
|
155
169
|
}
|
|
@@ -157,11 +171,14 @@ export class JsonlWatcher {
|
|
|
157
171
|
if (e.type === 'assistant' && e.message?.content) {
|
|
158
172
|
this._startStreaming(cid, sid);
|
|
159
173
|
const key = `${sid}:${e.message.id}`;
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
174
|
+
const prev = this._emitted.get(key) || 0;
|
|
175
|
+
const content = e.message.content;
|
|
176
|
+
const newBlocks = content.slice(prev);
|
|
177
|
+
if (newBlocks.length > 0) {
|
|
178
|
+
this._emitted.set(key, content.length);
|
|
179
|
+
this._emitBlocks(cid, sid, newBlocks, 'assistant');
|
|
180
|
+
}
|
|
181
|
+
if (e.message.stop_reason) this._emitted.delete(key);
|
|
165
182
|
return;
|
|
166
183
|
}
|
|
167
184
|
|
|
@@ -175,14 +192,25 @@ export class JsonlWatcher {
|
|
|
175
192
|
|
|
176
193
|
if (e.type === 'progress') {
|
|
177
194
|
this._startStreaming(cid, sid);
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
195
|
+
const d = e.data || {};
|
|
196
|
+
if (d.type === 'agent_progress') {
|
|
197
|
+
const inner = d.message?.message || d.message;
|
|
198
|
+
const content = inner?.content;
|
|
199
|
+
if (Array.isArray(content)) {
|
|
200
|
+
const role = inner.role === 'user' ? 'tool_result' : 'assistant';
|
|
201
|
+
this._emitBlocks(cid, sid, content, role);
|
|
202
|
+
}
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (d.type === 'hook_progress') {
|
|
206
|
+
this._emit(cid, sid, { type: 'hook_progress', hookEvent: d.hookEvent, hookName: d.hookName }, 'system');
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (d.type === 'mcp_progress') {
|
|
210
|
+
this._emit(cid, sid, { type: 'mcp_progress', status: d.status, serverName: d.serverName, toolName: d.toolName }, 'system');
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
this._emit(cid, sid, { type: d.type || e.subtype || 'progress', content: e.content || d }, 'progress');
|
|
186
214
|
return;
|
|
187
215
|
}
|
|
188
216
|
|