browserclaw-agent 0.1.0 → 0.1.1
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/agent-loop.d.ts +23 -15
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +55 -32
- package/dist/agent-loop.js.map +1 -1
- package/dist/config.d.ts +10 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +29 -16
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +7 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -12
- package/dist/index.js.map +1 -1
- package/dist/lesson-store.d.ts +11 -0
- package/dist/lesson-store.d.ts.map +1 -0
- package/dist/lesson-store.js +323 -0
- package/dist/lesson-store.js.map +1 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +37 -24
- package/dist/llm.js.map +1 -1
- package/dist/port-probe.d.ts +8 -0
- package/dist/port-probe.d.ts.map +1 -0
- package/dist/port-probe.js +22 -0
- package/dist/port-probe.js.map +1 -0
- package/dist/prompt-log.d.ts +17 -0
- package/dist/prompt-log.d.ts.map +1 -0
- package/dist/prompt-log.js +28 -0
- package/dist/prompt-log.js.map +1 -0
- package/dist/routes.d.ts +3 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +227 -0
- package/dist/routes.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +121 -0
- package/dist/server.js.map +1 -0
- package/dist/session-manager.d.ts +40 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +635 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/skill-generator.d.ts +5 -0
- package/dist/skill-generator.d.ts.map +1 -0
- package/dist/skill-generator.js +173 -0
- package/dist/skill-generator.js.map +1 -0
- package/dist/skill-store.d.ts +7 -0
- package/dist/skill-store.d.ts.map +1 -0
- package/dist/skill-store.js +85 -0
- package/dist/skill-store.js.map +1 -0
- package/dist/trajectory-store.d.ts +20 -0
- package/dist/trajectory-store.d.ts.map +1 -0
- package/dist/trajectory-store.js +61 -0
- package/dist/trajectory-store.js.map +1 -0
- package/package.json +6 -14
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { appendFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { logger } from './logger.js';
|
|
4
|
+
import { requireEnv } from './config.js';
|
|
5
|
+
const LOG_DIR = requireEnv('PROMPT_LOG_DIR');
|
|
6
|
+
let ensureDirPromise = null;
|
|
7
|
+
function ensureDir() {
|
|
8
|
+
ensureDirPromise ??= mkdir(LOG_DIR, { recursive: true }).then(() => {
|
|
9
|
+
/* dir created */
|
|
10
|
+
}, (err) => {
|
|
11
|
+
ensureDirPromise = null;
|
|
12
|
+
throw err;
|
|
13
|
+
});
|
|
14
|
+
return ensureDirPromise;
|
|
15
|
+
}
|
|
16
|
+
export async function logPrompt(entry) {
|
|
17
|
+
logger.info({ type: 'prompt_log', ...entry }, 'Prompt log');
|
|
18
|
+
try {
|
|
19
|
+
await ensureDir();
|
|
20
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
21
|
+
const file = join(LOG_DIR, `prompts-${date}.jsonl`);
|
|
22
|
+
await appendFile(file, JSON.stringify(entry) + '\n');
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
logger.error({ err }, 'Failed to write prompt log');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=prompt-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-log.js","sourceRoot":"","sources":["../src/prompt-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAiB7C,IAAI,gBAAgB,GAAyB,IAAI,CAAC;AAElD,SAAS,SAAS;IAChB,gBAAgB,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC3D,GAAG,EAAE;QACH,iBAAiB;IACnB,CAAC,EACD,CAAC,GAAY,EAAE,EAAE;QACf,gBAAgB,GAAG,IAAI,CAAC;QACxB,MAAM,GAAG,CAAC;IACZ,CAAC,CACF,CAAC;IACF,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAqB;IACnD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,IAAI,QAAQ,CAAC,CAAC;QACpD,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
|
package/dist/routes.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAkQjE,wBAAsB,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,SAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BpH"}
|
package/dist/routes.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { logger } from './logger.js';
|
|
2
|
+
import { createSession, getSession, getSessionResult, closeSession, addSSEClient, sessionCount, enqueueUserMessage, } from './session-manager.js';
|
|
3
|
+
import { loadTrajectory } from './trajectory-store.js';
|
|
4
|
+
import { INTERJECTION_MAX_CHARS } from './config.js';
|
|
5
|
+
import { BYOK_PROVIDERS } from './llm.js';
|
|
6
|
+
import { HttpError } from './types.js';
|
|
7
|
+
const MAX_BODY_BYTES = 100 * 1024; // 100KB
|
|
8
|
+
async function parseBody(req) {
|
|
9
|
+
const chunks = [];
|
|
10
|
+
let totalSize = 0;
|
|
11
|
+
for await (const chunk of req) {
|
|
12
|
+
totalSize += chunk.length;
|
|
13
|
+
if (totalSize > MAX_BODY_BYTES) {
|
|
14
|
+
throw new HttpError(413, 'Request body too large');
|
|
15
|
+
}
|
|
16
|
+
chunks.push(chunk);
|
|
17
|
+
}
|
|
18
|
+
const raw = Buffer.concat(chunks).toString('utf-8');
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new HttpError(400, 'Invalid JSON in request body');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const ALLOWED_URL_SCHEMES = ['http:', 'https:'];
|
|
27
|
+
function validateUrl(url) {
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = new URL(url);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new HttpError(400, 'Invalid URL');
|
|
34
|
+
}
|
|
35
|
+
if (!ALLOWED_URL_SCHEMES.includes(parsed.protocol)) {
|
|
36
|
+
throw new HttpError(400, 'URL must use http or https');
|
|
37
|
+
}
|
|
38
|
+
return parsed.href;
|
|
39
|
+
}
|
|
40
|
+
function json(res, status, data) {
|
|
41
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
42
|
+
res.end(JSON.stringify(data));
|
|
43
|
+
}
|
|
44
|
+
function sendError(res, status, message) {
|
|
45
|
+
json(res, status, { error_code: 'BROWSER_ERROR', message });
|
|
46
|
+
}
|
|
47
|
+
const routes = [
|
|
48
|
+
{
|
|
49
|
+
method: 'GET',
|
|
50
|
+
pattern: /^\/health$/,
|
|
51
|
+
paramNames: [],
|
|
52
|
+
handler: ({ res }) => {
|
|
53
|
+
json(res, 200, {
|
|
54
|
+
status: 'healthy',
|
|
55
|
+
service: 'browserclaw-browser',
|
|
56
|
+
sessions: sessionCount(),
|
|
57
|
+
});
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
method: 'POST',
|
|
63
|
+
pattern: /^\/api\/v1\/sessions$/,
|
|
64
|
+
paramNames: [],
|
|
65
|
+
handler: async ({ req, res, clientIp }) => {
|
|
66
|
+
const body = await parseBody(req);
|
|
67
|
+
if (typeof body.prompt !== 'string' || body.prompt.trim().length === 0) {
|
|
68
|
+
sendError(res, 400, 'prompt is required and must be a non-empty string');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (body.headless !== undefined && typeof body.headless !== 'boolean') {
|
|
72
|
+
sendError(res, 400, 'headless must be a boolean');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const url = body.url !== undefined && body.url !== '' ? validateUrl(body.url) : undefined;
|
|
76
|
+
const envForcesVisible = process.env.BROWSER_HEADLESS === 'false';
|
|
77
|
+
const headless = envForcesVisible ? false : body.headless;
|
|
78
|
+
const hasValidToken = req.headers.authorization !== undefined;
|
|
79
|
+
const skipModeration = hasValidToken && body.skip_moderation === true;
|
|
80
|
+
const skipPostprocessing = hasValidToken && body.skip_postprocessing === true;
|
|
81
|
+
// Validate BYOK LLM config if provided
|
|
82
|
+
let llmConfig;
|
|
83
|
+
if (body.llm_config !== undefined) {
|
|
84
|
+
const { provider, model, api_key } = body.llm_config;
|
|
85
|
+
if (!(provider in BYOK_PROVIDERS)) {
|
|
86
|
+
sendError(res, 400, `Invalid provider. Must be one of: ${Object.keys(BYOK_PROVIDERS).join(', ')}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (typeof model !== 'string' || model.trim() === '') {
|
|
90
|
+
sendError(res, 400, 'model is required');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (typeof api_key !== 'string' || api_key.trim() === '') {
|
|
94
|
+
sendError(res, 400, 'api_key is required');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
llmConfig = { provider, model: model.trim(), api_key: api_key.trim() };
|
|
98
|
+
}
|
|
99
|
+
const { session } = await createSession(body.prompt, url, headless, clientIp, skipModeration, llmConfig, skipPostprocessing);
|
|
100
|
+
json(res, 201, {
|
|
101
|
+
session_id: session.id,
|
|
102
|
+
status: session.status,
|
|
103
|
+
created_at: session.created_at,
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
method: 'GET',
|
|
109
|
+
pattern: /^\/api\/v1\/sessions\/([^/]+)\/stream$/,
|
|
110
|
+
paramNames: ['id'],
|
|
111
|
+
handler: ({ res, params }) => {
|
|
112
|
+
const sessionId = params.id;
|
|
113
|
+
getSession(sessionId); // throws 404 if session doesn't exist
|
|
114
|
+
res.writeHead(200, {
|
|
115
|
+
'Content-Type': 'text/event-stream',
|
|
116
|
+
'Cache-Control': 'no-cache',
|
|
117
|
+
Connection: 'keep-alive',
|
|
118
|
+
'X-Accel-Buffering': 'no',
|
|
119
|
+
});
|
|
120
|
+
res.write(`event: connected\ndata: ${JSON.stringify({ session_id: sessionId })}\n\n`);
|
|
121
|
+
addSSEClient(sessionId, res);
|
|
122
|
+
const heartbeat = setInterval(() => {
|
|
123
|
+
res.write(': heartbeat\n\n');
|
|
124
|
+
}, 15_000);
|
|
125
|
+
res.on('close', () => {
|
|
126
|
+
clearInterval(heartbeat);
|
|
127
|
+
});
|
|
128
|
+
return Promise.resolve();
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
method: 'GET',
|
|
133
|
+
pattern: /^\/api\/v1\/sessions\/([^/]+)$/,
|
|
134
|
+
paramNames: ['id'],
|
|
135
|
+
handler: ({ res, params }) => {
|
|
136
|
+
const sessionId = params.id;
|
|
137
|
+
const session = getSession(sessionId);
|
|
138
|
+
const { result, skill, domain_skills } = getSessionResult(sessionId);
|
|
139
|
+
json(res, 200, {
|
|
140
|
+
...session,
|
|
141
|
+
result: result !== null
|
|
142
|
+
? {
|
|
143
|
+
success: result.success,
|
|
144
|
+
steps_completed: result.steps.length,
|
|
145
|
+
duration_ms: result.duration_ms,
|
|
146
|
+
error: result.error,
|
|
147
|
+
final_url: result.final_url,
|
|
148
|
+
}
|
|
149
|
+
: null,
|
|
150
|
+
skill,
|
|
151
|
+
domain_skills,
|
|
152
|
+
});
|
|
153
|
+
return Promise.resolve();
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
method: 'GET',
|
|
158
|
+
pattern: /^\/api\/v1\/sessions\/([^/]+)\/trajectory$/,
|
|
159
|
+
paramNames: ['id'],
|
|
160
|
+
handler: async ({ res, params }) => {
|
|
161
|
+
const sessionId = params.id;
|
|
162
|
+
const record = await loadTrajectory(sessionId);
|
|
163
|
+
if (record === null) {
|
|
164
|
+
sendError(res, 404, 'Trajectory not found');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
json(res, 200, record);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
method: 'POST',
|
|
172
|
+
pattern: /^\/api\/v1\/sessions\/([^/]+)\/respond$/,
|
|
173
|
+
paramNames: ['id'],
|
|
174
|
+
handler: async ({ req, res, params }) => {
|
|
175
|
+
const body = await parseBody(req);
|
|
176
|
+
if (typeof body.text !== 'string' || body.text.trim().length === 0) {
|
|
177
|
+
sendError(res, 400, 'text is required and must be a non-empty string');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const text = body.text.trim();
|
|
181
|
+
if (text.length > INTERJECTION_MAX_CHARS) {
|
|
182
|
+
sendError(res, 400, `text must be under ${String(INTERJECTION_MAX_CHARS)} characters`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
enqueueUserMessage(params.id, text);
|
|
186
|
+
json(res, 200, { success: true });
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
method: 'DELETE',
|
|
191
|
+
pattern: /^\/api\/v1\/sessions\/([^/]+)$/,
|
|
192
|
+
paramNames: ['id'],
|
|
193
|
+
handler: async ({ res, params }) => {
|
|
194
|
+
const sessionId = params.id;
|
|
195
|
+
await closeSession(sessionId);
|
|
196
|
+
json(res, 200, { success: true });
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
export async function handleRequest(req, res, clientIp = '127.0.0.1') {
|
|
201
|
+
const method = req.method ?? 'GET';
|
|
202
|
+
const path = req.url?.split('?')[0] ?? '/';
|
|
203
|
+
for (const route of routes) {
|
|
204
|
+
if (route.method !== method)
|
|
205
|
+
continue;
|
|
206
|
+
const match = path.match(route.pattern);
|
|
207
|
+
if (!match)
|
|
208
|
+
continue;
|
|
209
|
+
const params = {};
|
|
210
|
+
for (let i = 0; i < route.paramNames.length; i++) {
|
|
211
|
+
params[route.paramNames[i]] = match[i + 1];
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
await route.handler({ req, res, params, clientIp });
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
const isHttpError = err instanceof HttpError;
|
|
218
|
+
const status = isHttpError ? err.statusCode : 500;
|
|
219
|
+
const internal = err instanceof Error ? err.message : 'Internal server error';
|
|
220
|
+
logger.error({ method, path, error: internal }, 'Request handler error');
|
|
221
|
+
sendError(res, status, isHttpError ? internal : 'Internal server error');
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
sendError(res, 404, 'Not found');
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
3
|
+
import { handleRequest } from './routes.js';
|
|
4
|
+
import { startCleanupLoop, closeAllSessions, stopCleanupLoop } from './session-manager.js';
|
|
5
|
+
import { validateConfig } from './config.js';
|
|
6
|
+
import { initSkillStore } from './skill-store.js';
|
|
7
|
+
import { initLessonStore } from './lesson-store.js';
|
|
8
|
+
import { initTrajectoryStore } from './trajectory-store.js';
|
|
9
|
+
import { logger } from './logger.js';
|
|
10
|
+
const { port, rateLimitMax, rateLimitWindowMs, internalToken } = validateConfig();
|
|
11
|
+
const BEARER_PREFIX = 'Bearer ';
|
|
12
|
+
const ipHits = new Map();
|
|
13
|
+
function getClientIP(req) {
|
|
14
|
+
// Last XFF entry only — leading entries are client-supplied and spoofable.
|
|
15
|
+
const forwarded = req.headers['x-forwarded-for'];
|
|
16
|
+
if (forwarded !== undefined) {
|
|
17
|
+
const raw = Array.isArray(forwarded) ? forwarded[forwarded.length - 1] : forwarded;
|
|
18
|
+
const entries = raw.split(',');
|
|
19
|
+
const last = entries[entries.length - 1].trim();
|
|
20
|
+
if (last !== '')
|
|
21
|
+
return last;
|
|
22
|
+
}
|
|
23
|
+
return req.socket.remoteAddress ?? '127.0.0.1';
|
|
24
|
+
}
|
|
25
|
+
function checkAndRecordHit(ip) {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const hits = (ipHits.get(ip) ?? []).filter((t) => now - t < rateLimitWindowMs);
|
|
28
|
+
if (hits.length >= rateLimitMax) {
|
|
29
|
+
ipHits.set(ip, hits);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
hits.push(now);
|
|
33
|
+
ipHits.set(ip, hits);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
const IP_HITS_MAX_ENTRIES = 10_000;
|
|
37
|
+
const ipCleanupInterval = setInterval(() => {
|
|
38
|
+
if (ipHits.size > IP_HITS_MAX_ENTRIES) {
|
|
39
|
+
ipHits.clear();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
for (const [ip, hits] of ipHits) {
|
|
44
|
+
const active = hits.filter((t) => now - t < rateLimitWindowMs);
|
|
45
|
+
if (active.length === 0)
|
|
46
|
+
ipHits.delete(ip);
|
|
47
|
+
else
|
|
48
|
+
ipHits.set(ip, active);
|
|
49
|
+
}
|
|
50
|
+
}, 3600_000);
|
|
51
|
+
function tokensMatch(provided, expected) {
|
|
52
|
+
const providedBuf = Buffer.from(provided);
|
|
53
|
+
const expectedBuf = Buffer.from(expected);
|
|
54
|
+
if (providedBuf.length !== expectedBuf.length)
|
|
55
|
+
return false;
|
|
56
|
+
return timingSafeEqual(providedBuf, expectedBuf);
|
|
57
|
+
}
|
|
58
|
+
const server = createServer((req, res) => {
|
|
59
|
+
void (async () => {
|
|
60
|
+
const headerValue = req.headers['x-correlation-id'];
|
|
61
|
+
const raw = Array.isArray(headerValue) ? headerValue[0] : headerValue;
|
|
62
|
+
const correlationId = raw ?? crypto.randomUUID();
|
|
63
|
+
res.setHeader('X-Correlation-Id', correlationId);
|
|
64
|
+
if (req.url !== '/health') {
|
|
65
|
+
const auth = req.headers.authorization ?? '';
|
|
66
|
+
const token = auth.startsWith(BEARER_PREFIX) ? auth.slice(BEARER_PREFIX.length) : '';
|
|
67
|
+
if (!tokensMatch(token, internalToken)) {
|
|
68
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
69
|
+
res.end(JSON.stringify({ error_code: 'UNAUTHORIZED', message: 'Invalid or missing internal token' }));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const ip = getClientIP(req);
|
|
74
|
+
if (req.method === 'POST' && req.url?.startsWith('/api/v1/sessions') === true) {
|
|
75
|
+
if (!checkAndRecordHit(ip)) {
|
|
76
|
+
res.writeHead(429, { 'Content-Type': 'application/json' });
|
|
77
|
+
res.end(JSON.stringify({
|
|
78
|
+
error_code: 'RATE_LIMITED',
|
|
79
|
+
message: `Maximum ${String(rateLimitMax)} runs per 24 hours. Try again later.`,
|
|
80
|
+
}));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
await handleRequest(req, res, ip);
|
|
85
|
+
})();
|
|
86
|
+
});
|
|
87
|
+
startCleanupLoop();
|
|
88
|
+
initLessonStore();
|
|
89
|
+
initTrajectoryStore();
|
|
90
|
+
initSkillStore()
|
|
91
|
+
.then(() => {
|
|
92
|
+
server.listen(port, () => {
|
|
93
|
+
logger.info({ port }, 'browserclaw-browser listening');
|
|
94
|
+
});
|
|
95
|
+
})
|
|
96
|
+
.catch((err) => {
|
|
97
|
+
logger.warn({ err }, 'Skill store unavailable — running without skill catalog');
|
|
98
|
+
server.listen(port, () => {
|
|
99
|
+
logger.info({ port }, 'browserclaw-browser listening');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
async function shutdown() {
|
|
103
|
+
logger.info('Shutting down...');
|
|
104
|
+
const forceExit = setTimeout(() => {
|
|
105
|
+
logger.error('Graceful shutdown timed out, forcing exit');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}, 10_000);
|
|
108
|
+
forceExit.unref();
|
|
109
|
+
clearInterval(ipCleanupInterval);
|
|
110
|
+
stopCleanupLoop();
|
|
111
|
+
await closeAllSessions();
|
|
112
|
+
server.close();
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
process.on('SIGTERM', () => {
|
|
116
|
+
void shutdown();
|
|
117
|
+
});
|
|
118
|
+
process.on('SIGINT', () => {
|
|
119
|
+
void shutdown();
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ServerResponse } from 'node:http';
|
|
2
|
+
import type { Session, AgentLoopResult, SkillOutput, DomainSkillEntry, LlmConfig, UserMessage } from './types.js';
|
|
3
|
+
export declare function emitSSE(sessionId: string, event: string, data: unknown): void;
|
|
4
|
+
export declare function addSSEClient(sessionId: string, res: ServerResponse): void;
|
|
5
|
+
export declare function startCleanupLoop(): void;
|
|
6
|
+
export declare function stopCleanupLoop(): void;
|
|
7
|
+
export declare function createSession(prompt: string, url: string | undefined, headless: boolean | undefined, ip: string, skipModeration?: boolean, llmConfig?: LlmConfig, skipPostprocessing?: boolean): Promise<{
|
|
8
|
+
session: Session;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function getSession(sessionId: string): Session;
|
|
11
|
+
export declare function getSessionResult(sessionId: string): {
|
|
12
|
+
result: AgentLoopResult | null;
|
|
13
|
+
skill: SkillOutput | null;
|
|
14
|
+
domain_skills: DomainSkillEntry[];
|
|
15
|
+
};
|
|
16
|
+
export declare function waitForUserResponse(sessionId: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Accept a user message. When the flag is off, preserves the legacy behavior —
|
|
19
|
+
* only accepts replies while the agent is blocked on ask_user. When on, always
|
|
20
|
+
* enqueues (subject to rate limit + hard cap); if the agent is blocked on
|
|
21
|
+
* ask_user, additionally resolves the waiting promise so existing callers keep
|
|
22
|
+
* working unchanged.
|
|
23
|
+
*/
|
|
24
|
+
export declare function enqueueUserMessage(sessionId: string, text: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Drain and return all pending user messages. Called by the agent loop at the
|
|
27
|
+
* top of each step.
|
|
28
|
+
*/
|
|
29
|
+
export declare function drainUserMessages(sessionId: string): UserMessage[];
|
|
30
|
+
export declare function getInterjectionNonce(sessionId: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Legacy export — preserved so existing route handlers that imported it keep
|
|
33
|
+
* compiling while we migrate them. Prefer `enqueueUserMessage`.
|
|
34
|
+
* @deprecated use enqueueUserMessage
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveUserResponse(sessionId: string, text: string): void;
|
|
37
|
+
export declare function closeSession(sessionId: string): Promise<void>;
|
|
38
|
+
export declare function closeAllSessions(): Promise<void>;
|
|
39
|
+
export declare function sessionCount(): number;
|
|
40
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,KAAK,EACV,OAAO,EAEP,eAAe,EACf,WAAW,EAEX,gBAAgB,EAChB,SAAS,EACT,WAAW,EACZ,MAAM,YAAY,CAAC;AAuFpB,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAO7E;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAezE;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAiBvC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,OAAO,GAAG,SAAS,EAC7B,EAAE,EAAE,MAAM,EACV,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,SAAS,EACrB,kBAAkB,CAAC,EAAE,OAAO,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA2G/B;AAmWD,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CASrD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG;IACnD,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,gBAAgB,EAAE,CAAC;CACnC,CAGA;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BtE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAuCxE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAKlE;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnE;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|