agentgui 1.0.842 → 1.0.843
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/CHANGELOG.md +1 -0
- package/lib/routes-upload.js +79 -0
- package/package.json +1 -1
- package/server.js +2 -82
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
3
|
### Refactor
|
|
4
|
+
- Extract express upload + fsbrowse setup from server.js to lib/routes-upload.js (79L) exporting createExpressApp; server.js imports createExpressApp and no longer contains Busboy/fsbrowse/express inline code
|
|
4
5
|
- Extract maskKey, getProviderConfigs, saveProviderConfig, buildSystemPrompt, PROVIDER_CONFIGS from server.js to lib/provider-config.js (151L); extract logError, makeCleanupExecution, makeGetModelsForAgent, errLogPath from server.js to lib/server-utils.js (61L); server.js imports all via named imports; cleanupExecution wired after broadcastSync; _debugRoutes receives errLogPath
|
|
5
6
|
- Extract parseBody, acceptsEncoding, compressAndSend, sendJSON from server.js to lib/http-utils.js (43L); server.js imports from new module; zlib import removed from server.js
|
|
6
7
|
- Extract message/stream/queue routes (messagesMatch, streamMatch, queueMatch handlers) to lib/routes-messages.js (140L) and session/chunk/full/execution routes to lib/routes-sessions.js (145L); server.js reduced from 2406L to 2127L; both files ≤200L; wired via _messagesRoutes._match and _sessionsRoutes._match in request handler
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import Busboy from 'busboy';
|
|
3
|
+
import fsbrowse from 'fsbrowse';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
export function createExpressApp({ queries, BASE_URL }) {
|
|
8
|
+
const app = express();
|
|
9
|
+
const fsbrowseRouters = new Map();
|
|
10
|
+
|
|
11
|
+
app.post(BASE_URL + '/api/upload/:conversationId', (req, res) => {
|
|
12
|
+
try {
|
|
13
|
+
const conv = queries.getConversation(req.params.conversationId);
|
|
14
|
+
if (!conv) return res.status(404).json({ error: 'Conversation not found' });
|
|
15
|
+
if (!conv.workingDirectory) return res.status(400).json({ error: 'No working directory set for this conversation' });
|
|
16
|
+
|
|
17
|
+
const uploadDir = conv.workingDirectory;
|
|
18
|
+
if (!fs.existsSync(uploadDir)) {
|
|
19
|
+
fs.mkdirSync(uploadDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const bb = Busboy({ headers: req.headers });
|
|
23
|
+
const fileNames = [];
|
|
24
|
+
const writePromises = [];
|
|
25
|
+
|
|
26
|
+
bb.on('file', (fieldname, file, info) => {
|
|
27
|
+
const safeName = path.basename(info.filename);
|
|
28
|
+
const filePath = path.join(uploadDir, safeName);
|
|
29
|
+
fileNames.push(safeName);
|
|
30
|
+
const p = new Promise((resolve) => {
|
|
31
|
+
const writeStream = fs.createWriteStream(filePath);
|
|
32
|
+
file.pipe(writeStream);
|
|
33
|
+
writeStream.on('finish', resolve);
|
|
34
|
+
writeStream.on('error', () => { file.resume(); resolve(); });
|
|
35
|
+
});
|
|
36
|
+
writePromises.push(p);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
bb.on('finish', () => {
|
|
40
|
+
Promise.all(writePromises).then(() => {
|
|
41
|
+
res.json({ ok: true, files: fileNames, count: fileNames.length });
|
|
42
|
+
}).catch(() => {
|
|
43
|
+
res.json({ ok: true, files: fileNames, count: fileNames.length });
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
bb.on('error', (err) => {
|
|
48
|
+
res.status(500).json({ error: 'Upload failed: ' + err.message });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
req.pipe(bb);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
res.status(500).json({ error: err.message });
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
app.use(BASE_URL + '/files/:conversationId', (req, res, next) => {
|
|
58
|
+
const convId = req.params.conversationId;
|
|
59
|
+
const conv = queries.getConversation(convId);
|
|
60
|
+
if (!conv || !conv.workingDirectory) {
|
|
61
|
+
return res.status(404).json({ error: 'Conversation not found or no working directory' });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const normalizedWorkingDir = path.resolve(conv.workingDirectory);
|
|
65
|
+
|
|
66
|
+
let router = fsbrowseRouters.get(convId);
|
|
67
|
+
if (!router) {
|
|
68
|
+
router = fsbrowse({ baseDir: normalizedWorkingDir, name: 'Files' });
|
|
69
|
+
fsbrowseRouters.set(convId, router);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
req.baseUrl = BASE_URL + '/files/' + convId;
|
|
73
|
+
req.url = req.url.replace(new RegExp(`^${BASE_URL}/files/${convId}`), '');
|
|
74
|
+
|
|
75
|
+
router(req, res, next);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return app;
|
|
79
|
+
}
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -9,9 +9,7 @@ import { LRUCache } from 'lru-cache';
|
|
|
9
9
|
import { createRequire } from 'module';
|
|
10
10
|
import crypto from 'crypto';
|
|
11
11
|
const PKG_VERSION = JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url), 'utf8')).version;
|
|
12
|
-
import
|
|
13
|
-
import Busboy from 'busboy';
|
|
14
|
-
import fsbrowse from 'fsbrowse';
|
|
12
|
+
import { createExpressApp } from './lib/routes-upload.js';
|
|
15
13
|
import { queries } from './database.js';
|
|
16
14
|
import { runClaudeWithStreaming } from './lib/claude-runner-run.js';
|
|
17
15
|
import { initializeDescriptors, getAgentDescriptor } from './lib/agent-descriptors.js';
|
|
@@ -111,85 +109,7 @@ const STARTUP_CWD = (() => {
|
|
|
111
109
|
const staticDir = path.join(rootDir, 'static');
|
|
112
110
|
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
|
|
113
111
|
|
|
114
|
-
|
|
115
|
-
const expressApp = express();
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// File upload endpoint - copies dropped files to conversation workingDirectory
|
|
119
|
-
expressApp.post(BASE_URL + '/api/upload/:conversationId', (req, res) => {
|
|
120
|
-
try {
|
|
121
|
-
const conv = queries.getConversation(req.params.conversationId);
|
|
122
|
-
if (!conv) return res.status(404).json({ error: 'Conversation not found' });
|
|
123
|
-
if (!conv.workingDirectory) return res.status(400).json({ error: 'No working directory set for this conversation' });
|
|
124
|
-
|
|
125
|
-
const uploadDir = conv.workingDirectory;
|
|
126
|
-
if (!fs.existsSync(uploadDir)) {
|
|
127
|
-
fs.mkdirSync(uploadDir, { recursive: true });
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const bb = Busboy({ headers: req.headers });
|
|
131
|
-
const fileNames = [];
|
|
132
|
-
const writePromises = [];
|
|
133
|
-
|
|
134
|
-
bb.on('file', (fieldname, file, info) => {
|
|
135
|
-
const safeName = path.basename(info.filename);
|
|
136
|
-
const filePath = path.join(uploadDir, safeName);
|
|
137
|
-
fileNames.push(safeName);
|
|
138
|
-
const p = new Promise((resolve) => {
|
|
139
|
-
const writeStream = fs.createWriteStream(filePath);
|
|
140
|
-
file.pipe(writeStream);
|
|
141
|
-
writeStream.on('finish', resolve);
|
|
142
|
-
writeStream.on('error', () => { file.resume(); resolve(); });
|
|
143
|
-
});
|
|
144
|
-
writePromises.push(p);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
bb.on('finish', () => {
|
|
148
|
-
Promise.all(writePromises).then(() => {
|
|
149
|
-
res.json({ ok: true, files: fileNames, count: fileNames.length });
|
|
150
|
-
}).catch(() => {
|
|
151
|
-
res.json({ ok: true, files: fileNames, count: fileNames.length });
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
bb.on('error', (err) => {
|
|
156
|
-
res.status(500).json({ error: 'Upload failed: ' + err.message });
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
req.pipe(bb);
|
|
160
|
-
} catch (err) {
|
|
161
|
-
res.status(500).json({ error: err.message });
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// Cache fsbrowse routers per conversation to ensure API calls work
|
|
166
|
-
const fsbrowseRouters = new Map();
|
|
167
|
-
|
|
168
|
-
// fsbrowse file browser - mounted per conversation workingDirectory
|
|
169
|
-
// Route: /gm/files/:conversationId/*
|
|
170
|
-
expressApp.use(BASE_URL + '/files/:conversationId', (req, res, next) => {
|
|
171
|
-
const convId = req.params.conversationId;
|
|
172
|
-
const conv = queries.getConversation(convId);
|
|
173
|
-
if (!conv || !conv.workingDirectory) {
|
|
174
|
-
return res.status(404).json({ error: 'Conversation not found or no working directory' });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Normalize the working directory path to avoid Windows path duplication issues
|
|
178
|
-
const normalizedWorkingDir = path.resolve(conv.workingDirectory);
|
|
179
|
-
|
|
180
|
-
// Get or create cached fsbrowse router for this conversation
|
|
181
|
-
let router = fsbrowseRouters.get(convId);
|
|
182
|
-
if (!router) {
|
|
183
|
-
router = fsbrowse({ baseDir: normalizedWorkingDir, name: 'Files' });
|
|
184
|
-
fsbrowseRouters.set(convId, router);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Set baseUrl before calling the router
|
|
188
|
-
req.baseUrl = BASE_URL + '/files/' + convId;
|
|
189
|
-
req.url = req.url.replace(new RegExp(`^${BASE_URL}/files/${convId}`), '');
|
|
190
|
-
|
|
191
|
-
router(req, res, next);
|
|
192
|
-
});
|
|
112
|
+
const expressApp = createExpressApp({ queries, BASE_URL });
|
|
193
113
|
|
|
194
114
|
let discoveredAgents = [];
|
|
195
115
|
initializeDescriptors(discoveredAgents);
|