agentgui 1.0.939 → 1.0.941
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/AGENTS.md +12 -7
- package/lib/claude-runner-agents.js +25 -0
- package/lib/ws-handlers-util.js +27 -1
- package/package.json +1 -1
- package/server.js +10 -1
- package/site/app/index.html +14 -37
- package/site/app/js/app.js +506 -104
- package/site/app/js/backend.js +44 -32
- package/site/app/vendor/anentrypoint-design/247420.css +274 -86
- package/site/app/vendor/anentrypoint-design/247420.js +12 -12
- package/site/app/vendor/cdn/dompurify.js +9 -0
- package/site/app/vendor/cdn/fonts/1291de6d401a.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/1ba89a87e0b8.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/3644d51c507b.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/4b91d2650dc2.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/530d036ba64a.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/570a2bdd8f8b.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/5dd6d880fee9.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/62de9143afe3.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/64884efa2f11.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/68cd7063be2e.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/6c252abcf99b.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/71e69e06516a.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/9ea68c62083f.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/c010f9b7d6b2.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/d69723fc74be.woff2 +0 -0
- package/site/app/vendor/cdn/fonts/fonts.css +459 -0
- package/site/app/vendor/cdn/marked.js +8 -0
- package/site/app/vendor/cdn/prismjs/components/prism-bash.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-clike.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-core.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-css.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-diff.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-go.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-javascript.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-json.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-jsx.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-markdown.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-markup.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-python.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-rust.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-sql.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-toml.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-tsx.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-typescript.min.js +1 -0
- package/site/app/vendor/cdn/prismjs/components/prism-yaml.min.js +1 -0
package/site/app/js/backend.js
CHANGED
|
@@ -27,14 +27,17 @@ function withToken(url) {
|
|
|
27
27
|
return url + (url.includes('?') ? '&' : '?') + 'token=' + encodeURIComponent(tok);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function lsGet(k) { try { return localStorage.getItem(k); } catch { return null; } }
|
|
31
|
+
function lsSet(k, v) { try { localStorage.setItem(k, v); } catch {} }
|
|
32
|
+
|
|
30
33
|
export function getBackend() {
|
|
31
34
|
const u = new URL(location.href);
|
|
32
35
|
const fromQs = u.searchParams.get('backend');
|
|
33
|
-
if (fromQs) {
|
|
34
|
-
return
|
|
36
|
+
if (fromQs) { lsSet(KEY, fromQs); return fromQs; }
|
|
37
|
+
return lsGet(KEY) || DEFAULT_BACKEND;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
export function setBackend(url) {
|
|
40
|
+
export function setBackend(url) { lsSet(KEY, url); }
|
|
38
41
|
|
|
39
42
|
export async function probeBackend(base) {
|
|
40
43
|
try {
|
|
@@ -203,12 +206,28 @@ function addSessionListener(sessionId, fn) {
|
|
|
203
206
|
|
|
204
207
|
// ---------- Agents / models (WS) ----------
|
|
205
208
|
|
|
206
|
-
export async function
|
|
209
|
+
export async function listAgents(base) {
|
|
207
210
|
const { agents } = await wsCall(base, 'agents.list', {});
|
|
208
|
-
// Compatibility shape: app.js expects an array of {id, name?, ...}
|
|
209
211
|
return agents || [];
|
|
210
212
|
}
|
|
211
213
|
|
|
214
|
+
export async function listActiveChats(base) {
|
|
215
|
+
try { const { sessions } = await wsCall(base, 'chat.active', {}); return sessions || []; }
|
|
216
|
+
catch { return []; }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export async function cancelChat(base, sessionId) {
|
|
220
|
+
return wsCall(base, 'chat.cancel', { sessionId });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export async function listAgentModels(base, agentId) {
|
|
224
|
+
if (!agentId) return [];
|
|
225
|
+
try {
|
|
226
|
+
const { models } = await wsCall(base, 'agents.models', { id: agentId });
|
|
227
|
+
return models || [];
|
|
228
|
+
} catch { return []; }
|
|
229
|
+
}
|
|
230
|
+
|
|
212
231
|
// ---------- Streaming chat (WS) ----------
|
|
213
232
|
//
|
|
214
233
|
// Yields events of shape:
|
|
@@ -218,29 +237,15 @@ export async function listModels(base) {
|
|
|
218
237
|
// { type: 'error', error: '...' }
|
|
219
238
|
//
|
|
220
239
|
// Caller signature kept compatible with the previous HTTP/SSE impl.
|
|
221
|
-
export async function* streamChat(base, { model, messages, signal, agentId, resumeSid }) {
|
|
222
|
-
// The last user message is the prompt; agentgui's claude-runner
|
|
223
|
-
//
|
|
224
|
-
// For multi-turn, the agent's own session/resume handles continuity.
|
|
240
|
+
export async function* streamChat(base, { model, messages, signal, agentId, resumeSid, cwd }) {
|
|
241
|
+
// The last user message is the prompt; agentgui's claude-runner spawns the
|
|
242
|
+
// agent for a single prompt. Multi-turn continuity is the agent's own resume.
|
|
225
243
|
const last = messages[messages.length - 1];
|
|
226
244
|
const content = last?.content || '';
|
|
227
245
|
if (!content) return;
|
|
228
246
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
// If `model` looks like a real model id (has a slash), keep it as model
|
|
232
|
-
// and default agent to claude-code.
|
|
233
|
-
let resolvedAgentId = agentId;
|
|
234
|
-
let resolvedModel = model;
|
|
235
|
-
if (!resolvedAgentId) {
|
|
236
|
-
if (!model || /^[a-z][a-z0-9-]*$/.test(model)) {
|
|
237
|
-
// Bare slug — treat as agentId.
|
|
238
|
-
resolvedAgentId = model || 'claude-code';
|
|
239
|
-
resolvedModel = undefined;
|
|
240
|
-
} else {
|
|
241
|
-
resolvedAgentId = 'claude-code';
|
|
242
|
-
}
|
|
243
|
-
}
|
|
247
|
+
const resolvedAgentId = agentId || 'claude-code';
|
|
248
|
+
const resolvedModel = model || undefined;
|
|
244
249
|
|
|
245
250
|
// Queue events here; the async iterator pulls from it.
|
|
246
251
|
const queue = [];
|
|
@@ -252,7 +257,7 @@ export async function* streamChat(base, { model, messages, signal, agentId, resu
|
|
|
252
257
|
// Kick off the chat on the server.
|
|
253
258
|
let started;
|
|
254
259
|
try {
|
|
255
|
-
started = await wsCall(base, 'chat.sendMessage', { content, agentId: resolvedAgentId, model: resolvedModel, resumeSid });
|
|
260
|
+
started = await wsCall(base, 'chat.sendMessage', { content, agentId: resolvedAgentId, model: resolvedModel, resumeSid, cwd });
|
|
256
261
|
} catch (e) {
|
|
257
262
|
yield { type: 'error', error: e.message };
|
|
258
263
|
return;
|
|
@@ -260,25 +265,31 @@ export async function* streamChat(base, { model, messages, signal, agentId, resu
|
|
|
260
265
|
const sessionId = started?.sessionId;
|
|
261
266
|
if (!sessionId) { yield { type: 'error', error: 'no sessionId from server' }; return; }
|
|
262
267
|
|
|
268
|
+
const finish = () => { done = true; if (resolveWait) { resolveWait(); resolveWait = null; } };
|
|
269
|
+
|
|
263
270
|
const unsub = addSessionListener(sessionId, (ev) => {
|
|
264
271
|
if (ev.type === 'streaming_progress') {
|
|
265
272
|
const block = ev.block;
|
|
266
273
|
if (block?.type === 'text' && block.text) push({ type: 'text', text: block.text });
|
|
267
274
|
else if (block?.type === 'tool_use') push({ type: 'tool', block });
|
|
268
|
-
else if (block?.type === 'tool_result') push({ type: '
|
|
275
|
+
else if (block?.type === 'tool_result') push({ type: 'tool_result', block });
|
|
269
276
|
else if (block?.type === 'result') push({ type: 'result', block });
|
|
270
277
|
} else if (ev.type === 'streaming_complete') {
|
|
271
|
-
|
|
272
|
-
if (resolveWait) { resolveWait(); resolveWait = null; }
|
|
278
|
+
finish();
|
|
273
279
|
} else if (ev.type === 'streaming_error') {
|
|
274
280
|
errored = ev.error || 'streaming error';
|
|
275
|
-
|
|
276
|
-
if (resolveWait) { resolveWait(); resolveWait = null; }
|
|
281
|
+
finish();
|
|
277
282
|
}
|
|
278
283
|
});
|
|
279
284
|
|
|
280
|
-
//
|
|
281
|
-
|
|
285
|
+
// If the websocket drops mid-stream, streaming_complete will never arrive —
|
|
286
|
+
// surface an error and end the iterator instead of hanging forever.
|
|
287
|
+
const onWs = (s) => { if ((s === 'closed' || s === 'error') && !done) { errored = errored || 'connection lost during stream'; finish(); } };
|
|
288
|
+
const unsubWs = onWsStatus ? onWsStatus(onWs) : null;
|
|
289
|
+
|
|
290
|
+
// Wire AbortSignal to chat.cancel — and end the iterator immediately so the
|
|
291
|
+
// caller's busy state clears even if the server never emits a final event.
|
|
292
|
+
const onAbort = () => { wsCall(base, 'chat.cancel', { sessionId }).catch(() => {}); finish(); };
|
|
282
293
|
if (signal) {
|
|
283
294
|
if (signal.aborted) onAbort();
|
|
284
295
|
else signal.addEventListener('abort', onAbort, { once: true });
|
|
@@ -295,6 +306,7 @@ export async function* streamChat(base, { model, messages, signal, agentId, resu
|
|
|
295
306
|
if (errored) yield { type: 'error', error: errored };
|
|
296
307
|
} finally {
|
|
297
308
|
unsub();
|
|
309
|
+
if (typeof unsubWs === 'function') unsubWs();
|
|
298
310
|
if (signal) signal.removeEventListener?.('abort', onAbort);
|
|
299
311
|
}
|
|
300
312
|
}
|