agentgui 1.0.268 → 1.0.270
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/claude-runner.js +3 -187
- package/package.json +1 -1
- package/server.js +84 -6
package/lib/claude-runner.js
CHANGED
|
@@ -626,6 +626,7 @@ registry.register({
|
|
|
626
626
|
type: 'tool_use',
|
|
627
627
|
id: update.toolCallId,
|
|
628
628
|
name: update.title || update.kind || 'tool',
|
|
629
|
+
kind: update.kind || 'other',
|
|
629
630
|
input: update.rawInput || update.input || {}
|
|
630
631
|
}]
|
|
631
632
|
},
|
|
@@ -644,6 +645,8 @@ registry.register({
|
|
|
644
645
|
type: 'tool_status',
|
|
645
646
|
tool_use_id: update.toolCallId,
|
|
646
647
|
status: status,
|
|
648
|
+
kind: update.kind || 'other',
|
|
649
|
+
locations: update.locations || [],
|
|
647
650
|
session_id: params.sessionId
|
|
648
651
|
};
|
|
649
652
|
}
|
|
@@ -904,193 +907,6 @@ function createACPProtocolHandler() {
|
|
|
904
907
|
};
|
|
905
908
|
}
|
|
906
909
|
|
|
907
|
-
// Handle prompt response (end of turn)
|
|
908
|
-
if (message.id && message.result && message.result.stopReason) {
|
|
909
|
-
return {
|
|
910
|
-
type: 'result',
|
|
911
|
-
result: '',
|
|
912
|
-
stopReason: message.result.stopReason,
|
|
913
|
-
usage: message.result.usage,
|
|
914
|
-
session_id: context.sessionId
|
|
915
|
-
};
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
if (message.method === 'error' || message.error) {
|
|
919
|
-
return {
|
|
920
|
-
type: 'error',
|
|
921
|
-
error: message.error || message.params || { message: 'Unknown error' }
|
|
922
|
-
};
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
return null;
|
|
926
|
-
}
|
|
927
|
-
});
|
|
928
|
-
|
|
929
|
-
/**
|
|
930
|
-
* Common ACP protocol handler for all ACP agents
|
|
931
|
-
*/
|
|
932
|
-
function createACPProtocolHandler() {
|
|
933
|
-
return function(message, context) {
|
|
934
|
-
if (!message || typeof message !== 'object') return null;
|
|
935
|
-
|
|
936
|
-
// Handle ACP session/update notifications
|
|
937
|
-
if (message.method === 'session/update') {
|
|
938
|
-
const params = message.params || {};
|
|
939
|
-
const update = params.update || {};
|
|
940
|
-
|
|
941
|
-
// Agent message chunk (text response)
|
|
942
|
-
if (update.sessionUpdate === 'agent_message_chunk' && update.content) {
|
|
943
|
-
let contentBlock;
|
|
944
|
-
|
|
945
|
-
// Handle different content formats
|
|
946
|
-
if (typeof update.content === 'string') {
|
|
947
|
-
contentBlock = { type: 'text', text: update.content };
|
|
948
|
-
} else if (update.content.type === 'text' && update.content.text) {
|
|
949
|
-
contentBlock = update.content;
|
|
950
|
-
} else if (update.content.text) {
|
|
951
|
-
contentBlock = { type: 'text', text: update.content.text };
|
|
952
|
-
} else if (update.content.content) {
|
|
953
|
-
const inner = update.content.content;
|
|
954
|
-
if (typeof inner === 'string') {
|
|
955
|
-
contentBlock = { type: 'text', text: inner };
|
|
956
|
-
} else if (inner.type === 'text' && inner.text) {
|
|
957
|
-
contentBlock = inner;
|
|
958
|
-
} else {
|
|
959
|
-
contentBlock = { type: 'text', text: JSON.stringify(inner) };
|
|
960
|
-
}
|
|
961
|
-
} else {
|
|
962
|
-
contentBlock = { type: 'text', text: JSON.stringify(update.content) };
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
return {
|
|
966
|
-
type: 'assistant',
|
|
967
|
-
message: {
|
|
968
|
-
role: 'assistant',
|
|
969
|
-
content: [contentBlock]
|
|
970
|
-
},
|
|
971
|
-
session_id: params.sessionId
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
// Tool call
|
|
976
|
-
if (update.sessionUpdate === 'tool_call') {
|
|
977
|
-
return {
|
|
978
|
-
type: 'assistant',
|
|
979
|
-
message: {
|
|
980
|
-
role: 'assistant',
|
|
981
|
-
content: [{
|
|
982
|
-
type: 'tool_use',
|
|
983
|
-
id: update.toolCallId,
|
|
984
|
-
name: update.title || update.kind || 'tool',
|
|
985
|
-
input: update.rawInput || update.input || {}
|
|
986
|
-
}]
|
|
987
|
-
},
|
|
988
|
-
session_id: params.sessionId
|
|
989
|
-
};
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
// Tool call update (result) - handle all statuses
|
|
993
|
-
if (update.sessionUpdate === 'tool_call_update') {
|
|
994
|
-
const status = update.status;
|
|
995
|
-
const isError = status === 'failed';
|
|
996
|
-
const isCompleted = status === 'completed';
|
|
997
|
-
|
|
998
|
-
if (!isCompleted && !isError) {
|
|
999
|
-
return {
|
|
1000
|
-
type: 'tool_status',
|
|
1001
|
-
tool_use_id: update.toolCallId,
|
|
1002
|
-
status: status,
|
|
1003
|
-
session_id: params.sessionId
|
|
1004
|
-
};
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
const contentParts = [];
|
|
1008
|
-
if (update.content && Array.isArray(update.content)) {
|
|
1009
|
-
for (const item of update.content) {
|
|
1010
|
-
if (item.type === 'content' && item.content) {
|
|
1011
|
-
const innerContent = item.content;
|
|
1012
|
-
if (innerContent.type === 'text' && innerContent.text) {
|
|
1013
|
-
contentParts.push(innerContent.text);
|
|
1014
|
-
} else if (innerContent.type === 'resource' && innerContent.resource) {
|
|
1015
|
-
contentParts.push(innerContent.resource.text || JSON.stringify(innerContent.resource));
|
|
1016
|
-
} else {
|
|
1017
|
-
contentParts.push(JSON.stringify(innerContent));
|
|
1018
|
-
}
|
|
1019
|
-
} else if (item.type === 'diff') {
|
|
1020
|
-
const diffText = item.oldText
|
|
1021
|
-
? `--- ${item.path}\n+++ ${item.path}\n${item.oldText}\n---\n${item.newText}`
|
|
1022
|
-
: `+++ ${item.path}\n${item.newText}`;
|
|
1023
|
-
contentParts.push(diffText);
|
|
1024
|
-
} else if (item.type === 'terminal') {
|
|
1025
|
-
contentParts.push(`[Terminal: ${item.terminalId}]`);
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
const combinedContent = contentParts.join('\n') || (update.rawOutput ? JSON.stringify(update.rawOutput) : '');
|
|
1031
|
-
|
|
1032
|
-
return {
|
|
1033
|
-
type: 'user',
|
|
1034
|
-
message: {
|
|
1035
|
-
role: 'user',
|
|
1036
|
-
content: [{
|
|
1037
|
-
type: 'tool_result',
|
|
1038
|
-
tool_use_id: update.toolCallId,
|
|
1039
|
-
content: combinedContent,
|
|
1040
|
-
is_error: isError
|
|
1041
|
-
}]
|
|
1042
|
-
},
|
|
1043
|
-
session_id: params.sessionId
|
|
1044
|
-
};
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
// Usage update
|
|
1048
|
-
if (update.sessionUpdate === 'usage_update') {
|
|
1049
|
-
return {
|
|
1050
|
-
type: 'usage',
|
|
1051
|
-
usage: {
|
|
1052
|
-
used: update.used,
|
|
1053
|
-
size: update.size,
|
|
1054
|
-
cost: update.cost
|
|
1055
|
-
},
|
|
1056
|
-
session_id: params.sessionId
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
// Plan update
|
|
1061
|
-
if (update.sessionUpdate === 'plan') {
|
|
1062
|
-
return {
|
|
1063
|
-
type: 'plan',
|
|
1064
|
-
entries: update.entries || [],
|
|
1065
|
-
session_id: params.sessionId
|
|
1066
|
-
};
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
return null;
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
// Handle prompt response (end of turn)
|
|
1073
|
-
if (message.id && message.result && message.result.stopReason) {
|
|
1074
|
-
return {
|
|
1075
|
-
type: 'result',
|
|
1076
|
-
result: '',
|
|
1077
|
-
stopReason: message.result.stopReason,
|
|
1078
|
-
usage: message.result.usage,
|
|
1079
|
-
session_id: context.sessionId
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
if (message.method === 'error' || message.error) {
|
|
1084
|
-
return {
|
|
1085
|
-
type: 'error',
|
|
1086
|
-
error: message.error || message.params || { message: 'Unknown error' }
|
|
1087
|
-
};
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
return null;
|
|
1091
|
-
};
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
910
|
// Shared ACP handler
|
|
1095
911
|
const acpProtocolHandler = createACPProtocolHandler();
|
|
1096
912
|
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -104,22 +104,100 @@ async function ensureModelsDownloaded() {
|
|
|
104
104
|
|
|
105
105
|
if (!sttOk) {
|
|
106
106
|
console.log('[MODELS] Downloading STT model...');
|
|
107
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', completedFiles, totalFiles });
|
|
107
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'ipfs-fallback', completedFiles, totalFiles });
|
|
108
|
+
|
|
109
|
+
let sttDownloaded = false;
|
|
110
|
+
|
|
111
|
+
// Try IPFS first with fallback to HuggingFace
|
|
108
112
|
try {
|
|
109
|
-
|
|
113
|
+
const ipfsCid = queries.getIpfsCidByModel('whisper-base', 'stt');
|
|
114
|
+
if (ipfsCid) {
|
|
115
|
+
console.log('[MODELS] Attempting IPFS download for STT model:', ipfsCid.cid);
|
|
116
|
+
const sttFile = path.join(sttDir, 'model.onnx');
|
|
117
|
+
fs.mkdirSync(sttDir, { recursive: true });
|
|
118
|
+
await IPFSDownloader.downloadWithProgress(
|
|
119
|
+
`https://ipfs.io/ipfs/${ipfsCid.cid}`,
|
|
120
|
+
sttFile,
|
|
121
|
+
(progress) => {
|
|
122
|
+
broadcastModelProgress({
|
|
123
|
+
started: true,
|
|
124
|
+
done: false,
|
|
125
|
+
downloading: true,
|
|
126
|
+
type: 'stt',
|
|
127
|
+
source: 'ipfs',
|
|
128
|
+
...progress,
|
|
129
|
+
completedFiles,
|
|
130
|
+
totalFiles
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
sttDownloaded = true;
|
|
135
|
+
console.log('[MODELS] STT model downloaded via IPFS');
|
|
136
|
+
}
|
|
110
137
|
} catch (err) {
|
|
111
|
-
console.warn('[MODELS] STT download failed
|
|
138
|
+
console.warn('[MODELS] IPFS STT download failed:', err.message);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Fall back to webtalk/HuggingFace if IPFS didn't work
|
|
142
|
+
if (!sttDownloaded) {
|
|
143
|
+
try {
|
|
144
|
+
console.log('[MODELS] Falling back to HuggingFace for STT model');
|
|
145
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'huggingface', completedFiles, totalFiles });
|
|
146
|
+
await webtalkWhisper.ensureModel('onnx-community/whisper-base', config);
|
|
147
|
+
console.log('[MODELS] STT model downloaded via HuggingFace');
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.warn('[MODELS] HuggingFace STT download also failed:', err.message);
|
|
150
|
+
}
|
|
112
151
|
}
|
|
113
152
|
completedFiles += 10;
|
|
114
153
|
}
|
|
115
154
|
|
|
116
155
|
if (!ttsOk) {
|
|
117
156
|
console.log('[MODELS] Downloading TTS models...');
|
|
118
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', completedFiles, totalFiles });
|
|
157
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: 'ipfs-fallback', completedFiles, totalFiles });
|
|
158
|
+
|
|
159
|
+
let ttsDownloaded = false;
|
|
160
|
+
|
|
161
|
+
// Try IPFS first with fallback to HuggingFace
|
|
119
162
|
try {
|
|
120
|
-
|
|
163
|
+
const ipfsCid = queries.getIpfsCidByModel('tts', 'voice');
|
|
164
|
+
if (ipfsCid) {
|
|
165
|
+
console.log('[MODELS] Attempting IPFS download for TTS models:', ipfsCid.cid);
|
|
166
|
+
const ttsFile = path.join(ttsDir, 'models.tar.gz');
|
|
167
|
+
fs.mkdirSync(ttsDir, { recursive: true });
|
|
168
|
+
await IPFSDownloader.downloadWithProgress(
|
|
169
|
+
`https://ipfs.io/ipfs/${ipfsCid.cid}`,
|
|
170
|
+
ttsFile,
|
|
171
|
+
(progress) => {
|
|
172
|
+
broadcastModelProgress({
|
|
173
|
+
started: true,
|
|
174
|
+
done: false,
|
|
175
|
+
downloading: true,
|
|
176
|
+
type: 'tts',
|
|
177
|
+
source: 'ipfs',
|
|
178
|
+
...progress,
|
|
179
|
+
completedFiles,
|
|
180
|
+
totalFiles
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
ttsDownloaded = true;
|
|
185
|
+
console.log('[MODELS] TTS models downloaded via IPFS');
|
|
186
|
+
}
|
|
121
187
|
} catch (err) {
|
|
122
|
-
console.warn('[MODELS] TTS download failed
|
|
188
|
+
console.warn('[MODELS] IPFS TTS download failed:', err.message);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Fall back to webtalk/HuggingFace if IPFS didn't work
|
|
192
|
+
if (!ttsDownloaded) {
|
|
193
|
+
try {
|
|
194
|
+
console.log('[MODELS] Falling back to HuggingFace for TTS models');
|
|
195
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: 'huggingface', completedFiles, totalFiles });
|
|
196
|
+
await webtalkTTS.ensureTTSModels(config);
|
|
197
|
+
console.log('[MODELS] TTS models downloaded via HuggingFace');
|
|
198
|
+
} catch (err) {
|
|
199
|
+
console.warn('[MODELS] HuggingFace TTS download also failed:', err.message);
|
|
200
|
+
}
|
|
123
201
|
}
|
|
124
202
|
completedFiles += 6;
|
|
125
203
|
}
|