@exreve/exk 1.0.14 → 1.0.15
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/agentSession.js +67 -12
- package/dist/ttc-cli.tar.gz +0 -0
- package/package.json +1 -1
package/dist/agentSession.js
CHANGED
|
@@ -51,6 +51,9 @@ function extractToolName(toolResult) {
|
|
|
51
51
|
if (toolResult.type === 'text' && toolResult.file)
|
|
52
52
|
return 'Read';
|
|
53
53
|
if (toolResult.file_path || toolResult.filePath) {
|
|
54
|
+
// Has old_string/new_string → Edit; has content/create → Write; else Read
|
|
55
|
+
if (toolResult.old_string !== undefined && toolResult.new_string !== undefined)
|
|
56
|
+
return 'Edit';
|
|
54
57
|
return (toolResult.content !== undefined || toolResult.type === 'create') ? 'Write' : 'Read';
|
|
55
58
|
}
|
|
56
59
|
if (toolResult.stdout !== undefined || toolResult.stderr !== undefined)
|
|
@@ -60,6 +63,23 @@ function extractToolName(toolResult) {
|
|
|
60
63
|
return 'Bash';
|
|
61
64
|
return 'unknown';
|
|
62
65
|
}
|
|
66
|
+
// Look up tool name from the most recent assistant message's tool_use blocks by tool_use_id
|
|
67
|
+
function lookupToolNameFromHistory(messages, toolUseId) {
|
|
68
|
+
if (!toolUseId)
|
|
69
|
+
return null;
|
|
70
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
71
|
+
const msg = messages[i];
|
|
72
|
+
if (msg.role !== 'assistant')
|
|
73
|
+
continue;
|
|
74
|
+
const content = typeof msg.content === 'string' ? null : msg.content;
|
|
75
|
+
if (!Array.isArray(content))
|
|
76
|
+
continue;
|
|
77
|
+
const toolUse = content.find((c) => c.type === 'tool_use' && c.id === toolUseId);
|
|
78
|
+
if (toolUse?.name)
|
|
79
|
+
return toolUse.name;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
63
83
|
// AI config - loaded from server after registration, stored in ~/.talk-to-code/ai-config.json
|
|
64
84
|
// (Do not read ANTHROPIC_* / CLAUDE_MODEL from the host environment — only this file + code default model.)
|
|
65
85
|
const AI_CONFIG_PATH = path.join(os.homedir(), '.talk-to-code', 'ai-config.json');
|
|
@@ -254,6 +274,13 @@ export class AgentSessionManager {
|
|
|
254
274
|
if (!session.isProcessingQueue) {
|
|
255
275
|
this.processPromptQueue(sessionId);
|
|
256
276
|
}
|
|
277
|
+
else if (session.isProcessingQueue && !session.activeQueryStream && !this.emergencyStopInProgress.has(sessionId)) {
|
|
278
|
+
// Safety: isProcessingQueue is true but there's no active stream and no emergency stop
|
|
279
|
+
// This means the queue got stuck (e.g. from a previous abort return that bypassed cleanup)
|
|
280
|
+
console.warn(`[agentSession] Queue stuck detected for session ${sessionId}, resetting isProcessingQueue`);
|
|
281
|
+
session.isProcessingQueue = false;
|
|
282
|
+
this.processPromptQueue(sessionId);
|
|
283
|
+
}
|
|
257
284
|
}
|
|
258
285
|
async processPromptQueue(sessionId) {
|
|
259
286
|
const session = this.sessions.get(sessionId);
|
|
@@ -696,12 +723,16 @@ export class AgentSessionManager {
|
|
|
696
723
|
}
|
|
697
724
|
}
|
|
698
725
|
if (toolResult) {
|
|
726
|
+
const detectedName = extractToolName(toolResult);
|
|
727
|
+
const resolvedName = detectedName !== 'unknown'
|
|
728
|
+
? detectedName
|
|
729
|
+
: (lookupToolNameFromHistory(session.messages, toolUseId) || detectedName);
|
|
699
730
|
onOutput({
|
|
700
731
|
type: 'tool_result',
|
|
701
732
|
data: toolResult,
|
|
702
733
|
timestamp: Date.now(),
|
|
703
734
|
metadata: {
|
|
704
|
-
toolName:
|
|
735
|
+
toolName: resolvedName,
|
|
705
736
|
toolResult: toolResult,
|
|
706
737
|
toolUseId: toolUseId || undefined,
|
|
707
738
|
parentToolUseId: msg.parent_tool_use_id,
|
|
@@ -827,7 +858,9 @@ export class AgentSessionManager {
|
|
|
827
858
|
onComplete(null);
|
|
828
859
|
session.activeQueryStream = undefined;
|
|
829
860
|
session.currentPromptId = undefined;
|
|
830
|
-
return
|
|
861
|
+
// Use break instead of return to ensure isProcessingQueue gets reset
|
|
862
|
+
// after the while loop at the end of processPromptQueue
|
|
863
|
+
break;
|
|
831
864
|
}
|
|
832
865
|
// Re-throw non-abort errors
|
|
833
866
|
throw streamError;
|
|
@@ -1014,24 +1047,46 @@ export class AgentSessionManager {
|
|
|
1014
1047
|
if (!session) {
|
|
1015
1048
|
return { success: false, message: 'Session not found' };
|
|
1016
1049
|
}
|
|
1017
|
-
// 1. Abort
|
|
1050
|
+
// 1. Abort session-level controller only (not all sessions' controllers)
|
|
1018
1051
|
session.abortController.abort();
|
|
1019
|
-
|
|
1020
|
-
|
|
1052
|
+
// Abort only controllers belonging to THIS session
|
|
1053
|
+
// Find and abort controllers for prompts in this session's queue and current prompt
|
|
1054
|
+
if (session.currentPromptId) {
|
|
1055
|
+
const ctrl = this.promptAbortControllers.get(session.currentPromptId);
|
|
1056
|
+
if (ctrl)
|
|
1057
|
+
ctrl.abort();
|
|
1058
|
+
}
|
|
1059
|
+
for (const queued of session.promptQueue) {
|
|
1060
|
+
if (queued.abortController)
|
|
1061
|
+
queued.abortController.abort();
|
|
1062
|
+
if (queued.promptId) {
|
|
1063
|
+
const ctrl = this.promptAbortControllers.get(queued.promptId);
|
|
1064
|
+
if (ctrl)
|
|
1065
|
+
ctrl.abort();
|
|
1066
|
+
}
|
|
1021
1067
|
}
|
|
1022
1068
|
// 2. Kill the entire process tree
|
|
1023
1069
|
await this.killProcessTree(sessionId);
|
|
1024
|
-
// 3.
|
|
1070
|
+
// 3. Collect prompt IDs from queue BEFORE clearing it
|
|
1025
1071
|
const queueSize = session.promptQueue.length;
|
|
1072
|
+
const queuedPromptIds = session.promptQueue
|
|
1073
|
+
.map(p => p.promptId)
|
|
1074
|
+
.filter((id) => !!id);
|
|
1075
|
+
const currentPromptId = session.currentPromptId;
|
|
1076
|
+
// 4. Clear the prompt queue
|
|
1026
1077
|
session.promptQueue = [];
|
|
1027
|
-
//
|
|
1078
|
+
// 5. Clear active stream
|
|
1028
1079
|
session.activeQueryStream = undefined;
|
|
1029
|
-
//
|
|
1080
|
+
// 6. Reset processing state
|
|
1030
1081
|
session.isProcessingQueue = false;
|
|
1031
|
-
//
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1082
|
+
// 7. Clean up abort controllers map (only for this session's prompts, not ALL sessions)
|
|
1083
|
+
if (currentPromptId) {
|
|
1084
|
+
this.promptAbortControllers.delete(currentPromptId);
|
|
1085
|
+
}
|
|
1086
|
+
for (const pid of queuedPromptIds) {
|
|
1087
|
+
this.promptAbortControllers.delete(pid);
|
|
1088
|
+
}
|
|
1089
|
+
session.currentPromptId = undefined;
|
|
1035
1090
|
// 8. Remove from emergency stop tracking
|
|
1036
1091
|
this.emergencyStopInProgress.delete(sessionId);
|
|
1037
1092
|
// 9. Resolve any pending choice request with null (cancelled)
|
package/dist/ttc-cli.tar.gz
CHANGED
|
Binary file
|