aicodeman 0.5.2 → 0.5.4
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/dist/ai-checker-base.d.ts.map +1 -1
- package/dist/ai-checker-base.js +3 -2
- package/dist/ai-checker-base.js.map +1 -1
- package/dist/bash-tool-parser.d.ts +6 -0
- package/dist/bash-tool-parser.d.ts.map +1 -1
- package/dist/bash-tool-parser.js +87 -101
- package/dist/bash-tool-parser.js.map +1 -1
- package/dist/file-stream-manager.d.ts.map +1 -1
- package/dist/file-stream-manager.js +2 -1
- package/dist/file-stream-manager.js.map +1 -1
- package/dist/orchestrator-loop.d.ts +2 -0
- package/dist/orchestrator-loop.d.ts.map +1 -1
- package/dist/orchestrator-loop.js +27 -22
- package/dist/orchestrator-loop.js.map +1 -1
- package/dist/orchestrator-verifier.d.ts +1 -1
- package/dist/orchestrator-verifier.d.ts.map +1 -1
- package/dist/orchestrator-verifier.js +3 -2
- package/dist/orchestrator-verifier.js.map +1 -1
- package/dist/plan-orchestrator.d.ts +4 -1
- package/dist/plan-orchestrator.d.ts.map +1 -1
- package/dist/plan-orchestrator.js +66 -88
- package/dist/plan-orchestrator.js.map +1 -1
- package/dist/ralph-status-parser.d.ts +2 -0
- package/dist/ralph-status-parser.d.ts.map +1 -1
- package/dist/ralph-status-parser.js +98 -102
- package/dist/ralph-status-parser.js.map +1 -1
- package/dist/ralph-tracker.d.ts +9 -0
- package/dist/ralph-tracker.d.ts.map +1 -1
- package/dist/ralph-tracker.js +52 -60
- package/dist/ralph-tracker.js.map +1 -1
- package/dist/respawn-controller.d.ts +18 -1
- package/dist/respawn-controller.d.ts.map +1 -1
- package/dist/respawn-controller.js +215 -181
- package/dist/respawn-controller.js.map +1 -1
- package/dist/session-auto-ops.d.ts.map +1 -1
- package/dist/session-auto-ops.js +57 -55
- package/dist/session-auto-ops.js.map +1 -1
- package/dist/session.d.ts +5 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +182 -218
- package/dist/session.js.map +1 -1
- package/dist/state-store.d.ts +6 -0
- package/dist/state-store.d.ts.map +1 -1
- package/dist/state-store.js +67 -79
- package/dist/state-store.js.map +1 -1
- package/dist/subagent-watcher.d.ts +24 -0
- package/dist/subagent-watcher.d.ts.map +1 -1
- package/dist/subagent-watcher.js +215 -220
- package/dist/subagent-watcher.js.map +1 -1
- package/dist/tmux-manager.d.ts +17 -0
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +57 -66
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tunnel-manager.d.ts.map +1 -1
- package/dist/tunnel-manager.js +2 -1
- package/dist/tunnel-manager.js.map +1 -1
- package/dist/web/public/api-client.3adebdc2.js.gz +0 -0
- package/dist/web/public/app.16290ae3.js +26 -0
- package/dist/web/public/app.16290ae3.js.br +0 -0
- package/dist/web/public/app.16290ae3.js.gz +0 -0
- package/dist/web/public/constants.64161167.js.gz +0 -0
- package/dist/web/public/index.html +7 -7
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.88082175.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.9fb81db6.js.gz +0 -0
- package/dist/web/public/mobile-handlers.1e2a8ef8.js.gz +0 -0
- package/dist/web/public/mobile.0b213796.css.gz +0 -0
- package/dist/web/public/notification-manager.2d5ea8ec.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.8204db1e.js → panels-ui.2d5b9703.js} +1 -1
- package/dist/web/public/panels-ui.2d5b9703.js.br +0 -0
- package/dist/web/public/panels-ui.2d5b9703.js.gz +0 -0
- package/dist/web/public/{ralph-panel.a2733fd5.js → ralph-panel.61076370.js} +1 -1
- package/dist/web/public/ralph-panel.61076370.js.br +0 -0
- package/dist/web/public/ralph-panel.61076370.js.gz +0 -0
- package/dist/web/public/ralph-wizard.f31ab90e.js.gz +0 -0
- package/dist/web/public/{respawn-ui.372c6ea7.js → respawn-ui.60be6ef5.js} +1 -1
- package/dist/web/public/respawn-ui.60be6ef5.js.br +0 -0
- package/dist/web/public/respawn-ui.60be6ef5.js.gz +0 -0
- package/dist/web/public/{session-ui.72f2f538.js → session-ui.554092ae.js} +1 -1
- package/dist/web/public/session-ui.554092ae.js.br +0 -0
- package/dist/web/public/session-ui.554092ae.js.gz +0 -0
- package/dist/web/public/{settings-ui.bd3eaadb.js → settings-ui.c58b0b9b.js} +7 -7
- package/dist/web/public/settings-ui.c58b0b9b.js.br +0 -0
- package/dist/web/public/settings-ui.c58b0b9b.js.gz +0 -0
- package/dist/web/public/styles.111ff326.css.gz +0 -0
- package/dist/web/public/subagent-windows.a366a4ad.js.gz +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/terminal-ui.474f79df.js.gz +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/voice-input.085e9e73.js.gz +0 -0
- package/dist/web/respawn-event-wiring.d.ts +51 -0
- package/dist/web/respawn-event-wiring.d.ts.map +1 -0
- package/dist/web/respawn-event-wiring.js +280 -0
- package/dist/web/respawn-event-wiring.js.map +1 -0
- package/dist/web/route-helpers.d.ts +23 -0
- package/dist/web/route-helpers.d.ts.map +1 -1
- package/dist/web/route-helpers.js +53 -0
- package/dist/web/route-helpers.js.map +1 -1
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +2 -11
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +8 -24
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/orchestrator-routes.d.ts.map +1 -1
- package/dist/web/routes/orchestrator-routes.js +23 -30
- package/dist/web/routes/orchestrator-routes.js.map +1 -1
- package/dist/web/routes/system-routes.d.ts.map +1 -1
- package/dist/web/routes/system-routes.js +17 -71
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/server.d.ts +4 -51
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +98 -941
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-listener-wiring.d.ts +89 -0
- package/dist/web/session-listener-wiring.d.ts.map +1 -0
- package/dist/web/session-listener-wiring.js +290 -0
- package/dist/web/session-listener-wiring.js.map +1 -0
- package/dist/web/sse-stream-manager.d.ts +91 -0
- package/dist/web/sse-stream-manager.d.ts.map +1 -0
- package/dist/web/sse-stream-manager.js +426 -0
- package/dist/web/sse-stream-manager.js.map +1 -0
- package/package.json +1 -1
- package/dist/web/public/app.e09fd4a6.js +0 -26
- package/dist/web/public/app.e09fd4a6.js.br +0 -0
- package/dist/web/public/app.e09fd4a6.js.gz +0 -0
- package/dist/web/public/panels-ui.8204db1e.js.br +0 -0
- package/dist/web/public/panels-ui.8204db1e.js.gz +0 -0
- package/dist/web/public/ralph-panel.a2733fd5.js.br +0 -0
- package/dist/web/public/ralph-panel.a2733fd5.js.gz +0 -0
- package/dist/web/public/respawn-ui.372c6ea7.js.br +0 -0
- package/dist/web/public/respawn-ui.372c6ea7.js.gz +0 -0
- package/dist/web/public/session-ui.72f2f538.js.br +0 -0
- package/dist/web/public/session-ui.72f2f538.js.gz +0 -0
- package/dist/web/public/settings-ui.bd3eaadb.js.br +0 -0
- package/dist/web/public/settings-ui.bd3eaadb.js.gz +0 -0
|
@@ -146,6 +146,24 @@ export declare class SubagentWatcher extends EventEmitter {
|
|
|
146
146
|
* Also filters out very short descriptions that are likely internal or malformed.
|
|
147
147
|
*/
|
|
148
148
|
private isInternalAgent;
|
|
149
|
+
/**
|
|
150
|
+
* Mark a subagent as completed: clear PID, set status, clean up pending tool calls, emit event.
|
|
151
|
+
*/
|
|
152
|
+
private markSubagentAsCompleted;
|
|
153
|
+
/**
|
|
154
|
+
* Extract text from message content, handling both string and array formats.
|
|
155
|
+
* For array content, returns the text from the first 'text' block.
|
|
156
|
+
*/
|
|
157
|
+
private extractFirstTextContent;
|
|
158
|
+
/**
|
|
159
|
+
* Process a tool_result content block: look up pending tool call, emit tool_result event.
|
|
160
|
+
*/
|
|
161
|
+
private emitToolResult;
|
|
162
|
+
/**
|
|
163
|
+
* Find the oldest inactive (non-active) agent for LRU eviction.
|
|
164
|
+
* Returns the agent ID of the oldest inactive agent, or null if all are active.
|
|
165
|
+
*/
|
|
166
|
+
private findOldestInactiveAgent;
|
|
149
167
|
/**
|
|
150
168
|
* Extract short model identifier from full model name
|
|
151
169
|
*/
|
|
@@ -294,6 +312,7 @@ export declare class SubagentWatcher extends EventEmitter {
|
|
|
294
312
|
* Aims for ~40-50 chars that convey what the agent is doing
|
|
295
313
|
*/
|
|
296
314
|
private extractSmartTitle;
|
|
315
|
+
private _resolveDescription;
|
|
297
316
|
/**
|
|
298
317
|
* Extract the short description from the parent session's transcript.
|
|
299
318
|
* This is the most reliable method because it reads the actual Task tool result
|
|
@@ -343,6 +362,11 @@ export declare class SubagentWatcher extends EventEmitter {
|
|
|
343
362
|
* Process a transcript entry and emit appropriate events
|
|
344
363
|
*/
|
|
345
364
|
private processEntry;
|
|
365
|
+
private _processModelInfo;
|
|
366
|
+
private _processTokenInfo;
|
|
367
|
+
private _processDescription;
|
|
368
|
+
private _processAssistantContent;
|
|
369
|
+
private _processUserContent;
|
|
346
370
|
/**
|
|
347
371
|
* Extract text content from tool_result content field
|
|
348
372
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-watcher.d.ts","sourceRoot":"","sources":["../src/subagent-watcher.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"subagent-watcher.d.ts","sourceRoot":"","sources":["../src/subagent-watcher.ts"],"names":[],"mappings":"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"}
|
package/dist/subagent-watcher.js
CHANGED
|
@@ -106,6 +106,72 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
106
106
|
return true;
|
|
107
107
|
return INTERNAL_AGENT_PATTERNS.some((pattern) => pattern.test(description));
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Mark a subagent as completed: clear PID, set status, clean up pending tool calls, emit event.
|
|
111
|
+
*/
|
|
112
|
+
markSubagentAsCompleted(info) {
|
|
113
|
+
info.pid = undefined;
|
|
114
|
+
info.status = 'completed';
|
|
115
|
+
this.pendingToolCalls.delete(info.agentId);
|
|
116
|
+
this.emit('subagent:completed', info);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Extract text from message content, handling both string and array formats.
|
|
120
|
+
* For array content, returns the text from the first 'text' block.
|
|
121
|
+
*/
|
|
122
|
+
extractFirstTextContent(content) {
|
|
123
|
+
if (!content)
|
|
124
|
+
return undefined;
|
|
125
|
+
if (typeof content === 'string') {
|
|
126
|
+
const trimmed = content.trim();
|
|
127
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
128
|
+
}
|
|
129
|
+
if (Array.isArray(content)) {
|
|
130
|
+
const firstContent = content[0];
|
|
131
|
+
if (firstContent?.type === 'text' && firstContent.text) {
|
|
132
|
+
const trimmed = firstContent.text.trim();
|
|
133
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Process a tool_result content block: look up pending tool call, emit tool_result event.
|
|
140
|
+
*/
|
|
141
|
+
emitToolResult(content, agentId, sessionId, timestamp) {
|
|
142
|
+
const resultContent = this.extractToolResultContent(content.content);
|
|
143
|
+
const agentPendingCalls = this.pendingToolCalls.get(agentId);
|
|
144
|
+
const pendingCall = agentPendingCalls?.get(content.tool_use_id);
|
|
145
|
+
const toolName = pendingCall?.toolName;
|
|
146
|
+
// Delete after lookup to prevent memory leak
|
|
147
|
+
agentPendingCalls?.delete(content.tool_use_id);
|
|
148
|
+
const toolResult = {
|
|
149
|
+
agentId,
|
|
150
|
+
sessionId,
|
|
151
|
+
timestamp,
|
|
152
|
+
toolUseId: content.tool_use_id,
|
|
153
|
+
tool: toolName,
|
|
154
|
+
preview: resultContent.substring(0, MESSAGE_TEXT_LIMIT),
|
|
155
|
+
contentLength: resultContent.length,
|
|
156
|
+
isError: content.is_error || false,
|
|
157
|
+
};
|
|
158
|
+
this.emit('subagent:tool_result', toolResult);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Find the oldest inactive (non-active) agent for LRU eviction.
|
|
162
|
+
* Returns the agent ID of the oldest inactive agent, or null if all are active.
|
|
163
|
+
*/
|
|
164
|
+
findOldestInactiveAgent() {
|
|
165
|
+
let oldestId = null;
|
|
166
|
+
let oldestTime = Infinity;
|
|
167
|
+
for (const [id, existing] of this.agentInfo) {
|
|
168
|
+
if (existing.status !== 'active' && existing.lastActivityAt < oldestTime) {
|
|
169
|
+
oldestTime = existing.lastActivityAt;
|
|
170
|
+
oldestId = id;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return oldestId;
|
|
174
|
+
}
|
|
109
175
|
/**
|
|
110
176
|
* Extract short model identifier from full model name
|
|
111
177
|
*/
|
|
@@ -181,10 +247,7 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
181
247
|
continue;
|
|
182
248
|
const alive = this.checkSubagentAliveFromPidMap(info, pidMap);
|
|
183
249
|
if (!alive) {
|
|
184
|
-
info
|
|
185
|
-
info.status = 'completed';
|
|
186
|
-
this.pendingToolCalls.delete(info.agentId);
|
|
187
|
-
this.emit('subagent:completed', info);
|
|
250
|
+
this.markSubagentAsCompleted(info);
|
|
188
251
|
}
|
|
189
252
|
}
|
|
190
253
|
}
|
|
@@ -512,10 +575,7 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
512
575
|
const pid = await this.findSubagentProcess(info.sessionId);
|
|
513
576
|
if (pid) {
|
|
514
577
|
process.kill(pid, 'SIGTERM');
|
|
515
|
-
info
|
|
516
|
-
info.status = 'completed';
|
|
517
|
-
this.pendingToolCalls.delete(info.agentId);
|
|
518
|
-
this.emit('subagent:completed', info);
|
|
578
|
+
this.markSubagentAsCompleted(info);
|
|
519
579
|
return true;
|
|
520
580
|
}
|
|
521
581
|
}
|
|
@@ -523,10 +583,7 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
523
583
|
// Process may have already exited
|
|
524
584
|
}
|
|
525
585
|
// Mark as completed even if we couldn't find the process
|
|
526
|
-
info
|
|
527
|
-
info.status = 'completed';
|
|
528
|
-
this.pendingToolCalls.delete(info.agentId);
|
|
529
|
-
this.emit('subagent:completed', info);
|
|
586
|
+
this.markSubagentAsCompleted(info);
|
|
530
587
|
return true;
|
|
531
588
|
}
|
|
532
589
|
/**
|
|
@@ -675,20 +732,9 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
675
732
|
}
|
|
676
733
|
else if (entry.type === 'user' && entry.message?.content) {
|
|
677
734
|
// Handle both string and array content formats
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
lines.push(`${this.formatTime(entry.timestamp)} 📥 User: ${text.substring(0, USER_TEXT_PREVIEW_LENGTH)}`);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
685
|
-
const firstContent = entry.message.content[0];
|
|
686
|
-
if (firstContent?.type === 'text' && firstContent.text) {
|
|
687
|
-
const text = firstContent.text.trim();
|
|
688
|
-
if (text.length < 100 && !text.includes('{')) {
|
|
689
|
-
lines.push(`${this.formatTime(entry.timestamp)} 📥 User: ${text.substring(0, USER_TEXT_PREVIEW_LENGTH)}`);
|
|
690
|
-
}
|
|
691
|
-
}
|
|
735
|
+
const text = this.extractFirstTextContent(entry.message.content);
|
|
736
|
+
if (text && text.length < 100 && !text.includes('{')) {
|
|
737
|
+
lines.push(`${this.formatTime(entry.timestamp)} 📥 User: ${text.substring(0, USER_TEXT_PREVIEW_LENGTH)}`);
|
|
692
738
|
}
|
|
693
739
|
}
|
|
694
740
|
}
|
|
@@ -753,6 +799,17 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
753
799
|
}
|
|
754
800
|
return truncated.replace(/[.!?,:\s]+$/, '');
|
|
755
801
|
}
|
|
802
|
+
async _resolveDescription(projectHash, sessionId, agentId, filePath, fallbackText) {
|
|
803
|
+
// First try parent transcript (most reliable)
|
|
804
|
+
const fromParent = await this.extractDescriptionFromParentTranscript(projectHash, sessionId, agentId);
|
|
805
|
+
if (fromParent)
|
|
806
|
+
return fromParent;
|
|
807
|
+
// Fallback: inline text (from processEntry) or file extraction
|
|
808
|
+
if (fallbackText) {
|
|
809
|
+
return this.extractSmartTitle(fallbackText);
|
|
810
|
+
}
|
|
811
|
+
return this.extractDescriptionFromFile(filePath);
|
|
812
|
+
}
|
|
756
813
|
/**
|
|
757
814
|
* Extract the short description from the parent session's transcript.
|
|
758
815
|
* This is the most reliable method because it reads the actual Task tool result
|
|
@@ -843,16 +900,7 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
843
900
|
try {
|
|
844
901
|
const entry = JSON.parse(line);
|
|
845
902
|
if (entry.type === 'user' && entry.message?.content) {
|
|
846
|
-
|
|
847
|
-
if (typeof entry.message.content === 'string') {
|
|
848
|
-
text = entry.message.content.trim();
|
|
849
|
-
}
|
|
850
|
-
else if (Array.isArray(entry.message.content)) {
|
|
851
|
-
const firstContent = entry.message.content[0];
|
|
852
|
-
if (firstContent?.type === 'text' && firstContent.text) {
|
|
853
|
-
text = firstContent.text.trim();
|
|
854
|
-
}
|
|
855
|
-
}
|
|
903
|
+
const text = this.extractFirstTextContent(entry.message.content);
|
|
856
904
|
if (text) {
|
|
857
905
|
resolved = true;
|
|
858
906
|
rl.close();
|
|
@@ -1012,14 +1060,8 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
1012
1060
|
}
|
|
1013
1061
|
// Retry description extraction if missing (race condition fix)
|
|
1014
1062
|
if (!existingInfo.description) {
|
|
1015
|
-
|
|
1016
|
-
let extractedDescription = await this.extractDescriptionFromParentTranscript(existingInfo.projectHash, existingInfo.sessionId, agentId);
|
|
1017
|
-
// Fallback to subagent file
|
|
1018
|
-
if (!extractedDescription) {
|
|
1019
|
-
extractedDescription = await this.extractDescriptionFromFile(filePath);
|
|
1020
|
-
}
|
|
1063
|
+
const extractedDescription = await this._resolveDescription(existingInfo.projectHash, existingInfo.sessionId, agentId, filePath);
|
|
1021
1064
|
if (extractedDescription) {
|
|
1022
|
-
// Check if this is an internal agent - if so, remove it
|
|
1023
1065
|
if (this.isInternalAgent(extractedDescription)) {
|
|
1024
1066
|
this.removeAgent(agentId);
|
|
1025
1067
|
return;
|
|
@@ -1061,12 +1103,7 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
1061
1103
|
}
|
|
1062
1104
|
}
|
|
1063
1105
|
// Extract description - prefer reading from parent transcript (most reliable)
|
|
1064
|
-
|
|
1065
|
-
let description = await this.extractDescriptionFromParentTranscript(projectHash, sessionId, agentId);
|
|
1066
|
-
// Fallback: extract a smart title from the subagent's prompt if parent lookup failed
|
|
1067
|
-
if (!description) {
|
|
1068
|
-
description = await this.extractDescriptionFromFile(filePath);
|
|
1069
|
-
}
|
|
1106
|
+
const description = await this._resolveDescription(projectHash, sessionId, agentId, filePath);
|
|
1070
1107
|
// Skip internal Claude Code agents (e.g., suggestion mode) - not real subagents
|
|
1071
1108
|
if (this.isInternalAgent(description)) {
|
|
1072
1109
|
return;
|
|
@@ -1086,14 +1123,7 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
1086
1123
|
};
|
|
1087
1124
|
// Enforce MAX_TRACKED_AGENTS during insertion — evict oldest inactive agent
|
|
1088
1125
|
if (this.agentInfo.size >= MAX_TRACKED_AGENTS) {
|
|
1089
|
-
|
|
1090
|
-
let oldestTime = Infinity;
|
|
1091
|
-
for (const [id, existing] of this.agentInfo) {
|
|
1092
|
-
if (existing.status !== 'active' && existing.lastActivityAt < oldestTime) {
|
|
1093
|
-
oldestTime = existing.lastActivityAt;
|
|
1094
|
-
oldestId = id;
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1126
|
+
const oldestId = this.findOldestInactiveAgent();
|
|
1097
1127
|
if (oldestId) {
|
|
1098
1128
|
this.removeAgent(oldestId);
|
|
1099
1129
|
}
|
|
@@ -1152,50 +1182,11 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
1152
1182
|
*/
|
|
1153
1183
|
async processEntry(entry, agentId, sessionId) {
|
|
1154
1184
|
const info = this.agentInfo.get(agentId);
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
}
|
|
1161
|
-
// Aggregate token usage from messages
|
|
1162
|
-
if (info && entry.message?.usage) {
|
|
1163
|
-
if (entry.message.usage.input_tokens) {
|
|
1164
|
-
info.totalInputTokens = (info.totalInputTokens || 0) + entry.message.usage.input_tokens;
|
|
1165
|
-
}
|
|
1166
|
-
if (entry.message.usage.output_tokens) {
|
|
1167
|
-
info.totalOutputTokens = (info.totalOutputTokens || 0) + entry.message.usage.output_tokens;
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
// Check if this is first user message and description is missing
|
|
1171
|
-
if (info && !info.description && entry.type === 'user' && entry.message?.content) {
|
|
1172
|
-
// First try parent transcript (most reliable)
|
|
1173
|
-
let description = await this.extractDescriptionFromParentTranscript(info.projectHash, info.sessionId, agentId);
|
|
1174
|
-
// Fallback: extract smart title from the prompt content
|
|
1175
|
-
if (!description) {
|
|
1176
|
-
let text;
|
|
1177
|
-
if (typeof entry.message.content === 'string') {
|
|
1178
|
-
text = entry.message.content.trim();
|
|
1179
|
-
}
|
|
1180
|
-
else if (Array.isArray(entry.message.content)) {
|
|
1181
|
-
const firstContent = entry.message.content[0];
|
|
1182
|
-
if (firstContent?.type === 'text' && firstContent.text) {
|
|
1183
|
-
text = firstContent.text.trim();
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
if (text) {
|
|
1187
|
-
description = this.extractSmartTitle(text);
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
if (description) {
|
|
1191
|
-
// Check if this is an internal agent - if so, remove it
|
|
1192
|
-
if (this.isInternalAgent(description)) {
|
|
1193
|
-
this.removeAgent(agentId);
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
info.description = description;
|
|
1197
|
-
this.emit('subagent:updated', info);
|
|
1198
|
-
}
|
|
1185
|
+
if (info) {
|
|
1186
|
+
this._processModelInfo(entry, info);
|
|
1187
|
+
this._processTokenInfo(entry, info);
|
|
1188
|
+
if (await this._processDescription(entry, agentId, info))
|
|
1189
|
+
return;
|
|
1199
1190
|
}
|
|
1200
1191
|
if (entry.type === 'progress' && entry.data) {
|
|
1201
1192
|
const progress = {
|
|
@@ -1205,7 +1196,6 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
1205
1196
|
progressType: entry.data.type,
|
|
1206
1197
|
query: entry.data.query,
|
|
1207
1198
|
resultCount: entry.data.resultCount,
|
|
1208
|
-
// Extract hook event info if present
|
|
1209
1199
|
hookEvent: entry.data.hookEvent,
|
|
1210
1200
|
hookName: entry.data.hookName ||
|
|
1211
1201
|
(entry.data.hookEvent && entry.data.tool_name
|
|
@@ -1215,142 +1205,147 @@ export class SubagentWatcher extends EventEmitter {
|
|
|
1215
1205
|
this.emit('subagent:progress', progress);
|
|
1216
1206
|
}
|
|
1217
1207
|
else if (entry.type === 'assistant' && entry.message?.content) {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1208
|
+
this._processAssistantContent(entry, agentId, sessionId);
|
|
1209
|
+
}
|
|
1210
|
+
else if (entry.type === 'user' && entry.message?.content) {
|
|
1211
|
+
this._processUserContent(entry, agentId, sessionId);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
_processModelInfo(entry, agent) {
|
|
1215
|
+
if (entry.type === 'assistant' && entry.message?.model && !agent.model) {
|
|
1216
|
+
agent.model = entry.message.model;
|
|
1217
|
+
agent.modelShort = this.extractModelShort(entry.message.model);
|
|
1218
|
+
this.emit('subagent:updated', agent);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
_processTokenInfo(entry, agent) {
|
|
1222
|
+
if (!entry.message?.usage)
|
|
1223
|
+
return;
|
|
1224
|
+
if (entry.message.usage.input_tokens) {
|
|
1225
|
+
agent.totalInputTokens = (agent.totalInputTokens || 0) + entry.message.usage.input_tokens;
|
|
1226
|
+
}
|
|
1227
|
+
if (entry.message.usage.output_tokens) {
|
|
1228
|
+
agent.totalOutputTokens = (agent.totalOutputTokens || 0) + entry.message.usage.output_tokens;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
async _processDescription(entry, agentId, agent) {
|
|
1232
|
+
if (agent.description || entry.type !== 'user' || !entry.message?.content)
|
|
1233
|
+
return false;
|
|
1234
|
+
const fallbackText = this.extractFirstTextContent(entry.message.content);
|
|
1235
|
+
const description = await this._resolveDescription(agent.projectHash, agent.sessionId, agentId, agent.filePath, fallbackText);
|
|
1236
|
+
if (description) {
|
|
1237
|
+
if (this.isInternalAgent(description)) {
|
|
1238
|
+
this.removeAgent(agentId);
|
|
1239
|
+
return true;
|
|
1240
|
+
}
|
|
1241
|
+
agent.description = description;
|
|
1242
|
+
this.emit('subagent:updated', agent);
|
|
1243
|
+
}
|
|
1244
|
+
return false;
|
|
1245
|
+
}
|
|
1246
|
+
_processAssistantContent(entry, agentId, sessionId) {
|
|
1247
|
+
const messageContent = entry.message.content;
|
|
1248
|
+
if (typeof messageContent === 'string') {
|
|
1249
|
+
const text = messageContent.trim();
|
|
1250
|
+
if (text.length > 0) {
|
|
1251
|
+
const message = {
|
|
1252
|
+
agentId,
|
|
1253
|
+
sessionId,
|
|
1254
|
+
timestamp: entry.timestamp,
|
|
1255
|
+
role: 'assistant',
|
|
1256
|
+
text: text.substring(0, MESSAGE_TEXT_LIMIT),
|
|
1257
|
+
};
|
|
1258
|
+
this.emit('subagent:message', message);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
else {
|
|
1262
|
+
for (const content of messageContent) {
|
|
1263
|
+
if (content.type === 'tool_use' && content.name) {
|
|
1264
|
+
// Store toolUseId for linking to results, with timestamp for TTL cleanup
|
|
1265
|
+
if (content.id) {
|
|
1266
|
+
if (!this.pendingToolCalls.has(agentId)) {
|
|
1267
|
+
this.pendingToolCalls.set(agentId, new Map());
|
|
1268
|
+
}
|
|
1269
|
+
const agentCalls = this.pendingToolCalls.get(agentId);
|
|
1270
|
+
// Enforce size limit to prevent memory leak from rapid tool calls
|
|
1271
|
+
if (agentCalls.size >= MAX_PENDING_TOOL_CALLS) {
|
|
1272
|
+
// FIFO eviction: delete first (oldest) entry using Map insertion order
|
|
1273
|
+
const firstKey = agentCalls.keys().next().value;
|
|
1274
|
+
if (firstKey !== undefined)
|
|
1275
|
+
agentCalls.delete(firstKey);
|
|
1276
|
+
}
|
|
1277
|
+
agentCalls.set(content.id, {
|
|
1278
|
+
toolName: content.name,
|
|
1279
|
+
timestamp: Date.now(),
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
const toolCall = {
|
|
1223
1283
|
agentId,
|
|
1224
1284
|
sessionId,
|
|
1225
1285
|
timestamp: entry.timestamp,
|
|
1226
|
-
|
|
1227
|
-
|
|
1286
|
+
tool: content.name,
|
|
1287
|
+
input: this.getTruncatedInput(content.name, content.input || {}),
|
|
1288
|
+
toolUseId: content.id,
|
|
1289
|
+
fullInput: content.input || {},
|
|
1228
1290
|
};
|
|
1229
|
-
this.emit('subagent:
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
if (content.type === 'tool_use' && content.name) {
|
|
1235
|
-
// Store toolUseId for linking to results, with timestamp for TTL cleanup
|
|
1236
|
-
if (content.id) {
|
|
1237
|
-
if (!this.pendingToolCalls.has(agentId)) {
|
|
1238
|
-
this.pendingToolCalls.set(agentId, new Map());
|
|
1239
|
-
}
|
|
1240
|
-
const agentCalls = this.pendingToolCalls.get(agentId);
|
|
1241
|
-
// Enforce size limit to prevent memory leak from rapid tool calls
|
|
1242
|
-
if (agentCalls.size >= MAX_PENDING_TOOL_CALLS) {
|
|
1243
|
-
// FIFO eviction: delete first (oldest) entry using Map insertion order
|
|
1244
|
-
const firstKey = agentCalls.keys().next().value;
|
|
1245
|
-
if (firstKey !== undefined)
|
|
1246
|
-
agentCalls.delete(firstKey);
|
|
1247
|
-
}
|
|
1248
|
-
agentCalls.set(content.id, {
|
|
1249
|
-
toolName: content.name,
|
|
1250
|
-
timestamp: Date.now(),
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
const toolCall = {
|
|
1254
|
-
agentId,
|
|
1255
|
-
sessionId,
|
|
1256
|
-
timestamp: entry.timestamp,
|
|
1257
|
-
tool: content.name,
|
|
1258
|
-
input: this.getTruncatedInput(content.name, content.input || {}),
|
|
1259
|
-
toolUseId: content.id,
|
|
1260
|
-
fullInput: content.input || {},
|
|
1261
|
-
};
|
|
1262
|
-
this.emit('subagent:tool_call', toolCall);
|
|
1263
|
-
// Update tool call count
|
|
1264
|
-
const agentInfo = this.agentInfo.get(agentId);
|
|
1265
|
-
if (agentInfo) {
|
|
1266
|
-
agentInfo.toolCallCount++;
|
|
1267
|
-
}
|
|
1291
|
+
this.emit('subagent:tool_call', toolCall);
|
|
1292
|
+
// Update tool call count
|
|
1293
|
+
const agentInfo = this.agentInfo.get(agentId);
|
|
1294
|
+
if (agentInfo) {
|
|
1295
|
+
agentInfo.toolCallCount++;
|
|
1268
1296
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
const toolResult = {
|
|
1297
|
+
}
|
|
1298
|
+
else if (content.type === 'tool_result' && content.tool_use_id) {
|
|
1299
|
+
this.emitToolResult({ tool_use_id: content.tool_use_id, content: content.content, is_error: content.is_error }, agentId, sessionId, entry.timestamp);
|
|
1300
|
+
}
|
|
1301
|
+
else if (content.type === 'text' && content.text) {
|
|
1302
|
+
const text = content.text.trim();
|
|
1303
|
+
if (text.length > 0) {
|
|
1304
|
+
const message = {
|
|
1278
1305
|
agentId,
|
|
1279
1306
|
sessionId,
|
|
1280
1307
|
timestamp: entry.timestamp,
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
preview: resultContent.substring(0, MESSAGE_TEXT_LIMIT),
|
|
1284
|
-
contentLength: resultContent.length,
|
|
1285
|
-
isError: content.is_error || false,
|
|
1308
|
+
role: 'assistant',
|
|
1309
|
+
text: text.substring(0, MESSAGE_TEXT_LIMIT),
|
|
1286
1310
|
};
|
|
1287
|
-
this.emit('subagent:
|
|
1288
|
-
}
|
|
1289
|
-
else if (content.type === 'text' && content.text) {
|
|
1290
|
-
const text = content.text.trim();
|
|
1291
|
-
if (text.length > 0) {
|
|
1292
|
-
const message = {
|
|
1293
|
-
agentId,
|
|
1294
|
-
sessionId,
|
|
1295
|
-
timestamp: entry.timestamp,
|
|
1296
|
-
role: 'assistant',
|
|
1297
|
-
text: text.substring(0, MESSAGE_TEXT_LIMIT), // Limit text length
|
|
1298
|
-
};
|
|
1299
|
-
this.emit('subagent:message', message);
|
|
1300
|
-
}
|
|
1311
|
+
this.emit('subagent:message', message);
|
|
1301
1312
|
}
|
|
1302
1313
|
}
|
|
1303
1314
|
}
|
|
1304
1315
|
}
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1316
|
+
}
|
|
1317
|
+
_processUserContent(entry, agentId, sessionId) {
|
|
1318
|
+
const messageContent = entry.message.content;
|
|
1319
|
+
if (typeof messageContent === 'string') {
|
|
1320
|
+
const userText = messageContent.trim();
|
|
1321
|
+
if (userText.length > 0 && userText.length < 500) {
|
|
1322
|
+
const message = {
|
|
1323
|
+
agentId,
|
|
1324
|
+
sessionId,
|
|
1325
|
+
timestamp: entry.timestamp,
|
|
1326
|
+
role: 'user',
|
|
1327
|
+
text: userText,
|
|
1328
|
+
};
|
|
1329
|
+
this.emit('subagent:message', message);
|
|
1319
1330
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
const
|
|
1331
|
+
}
|
|
1332
|
+
else {
|
|
1333
|
+
// Check for tool_result blocks in user messages (common pattern)
|
|
1334
|
+
for (const content of messageContent) {
|
|
1335
|
+
if (content.type === 'tool_result' && content.tool_use_id) {
|
|
1336
|
+
this.emitToolResult({ tool_use_id: content.tool_use_id, content: content.content, is_error: content.is_error }, agentId, sessionId, entry.timestamp);
|
|
1337
|
+
}
|
|
1338
|
+
else if (content.type === 'text' && content.text) {
|
|
1339
|
+
const userText = content.text.trim();
|
|
1340
|
+
if (userText.length > 0 && userText.length < 500) {
|
|
1341
|
+
const message = {
|
|
1331
1342
|
agentId,
|
|
1332
1343
|
sessionId,
|
|
1333
1344
|
timestamp: entry.timestamp,
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
preview: resultContent.substring(0, MESSAGE_TEXT_LIMIT),
|
|
1337
|
-
contentLength: resultContent.length,
|
|
1338
|
-
isError: content.is_error || false,
|
|
1345
|
+
role: 'user',
|
|
1346
|
+
text: userText,
|
|
1339
1347
|
};
|
|
1340
|
-
this.emit('subagent:
|
|
1341
|
-
}
|
|
1342
|
-
else if (content.type === 'text' && content.text) {
|
|
1343
|
-
const userText = content.text.trim();
|
|
1344
|
-
if (userText.length > 0 && userText.length < 500) {
|
|
1345
|
-
const message = {
|
|
1346
|
-
agentId,
|
|
1347
|
-
sessionId,
|
|
1348
|
-
timestamp: entry.timestamp,
|
|
1349
|
-
role: 'user',
|
|
1350
|
-
text: userText,
|
|
1351
|
-
};
|
|
1352
|
-
this.emit('subagent:message', message);
|
|
1353
|
-
}
|
|
1348
|
+
this.emit('subagent:message', message);
|
|
1354
1349
|
}
|
|
1355
1350
|
}
|
|
1356
1351
|
}
|