Add features & update project
This commit is contained in:
@@ -1,12 +1,19 @@
|
||||
import { createServer } from 'node:http';
|
||||
import type { IncomingMessage, ServerResponse } from 'node:http';
|
||||
|
||||
import type { Id } from '@spoon/backend/convex/_generated/dataModel.js';
|
||||
|
||||
import { env } from './env';
|
||||
import {
|
||||
abortWorkspaceAgent,
|
||||
cleanupOrphanedWorkspaces,
|
||||
getWorkerHealth,
|
||||
getWorkspaceAgentStatus,
|
||||
getWorkspaceDiff,
|
||||
listWorkspaceTree,
|
||||
openWorkspacePullRequest,
|
||||
readWorkspaceFile,
|
||||
replyToInteraction,
|
||||
runWorkspaceCommand,
|
||||
sendWorkspaceMessage,
|
||||
stopWorkspace,
|
||||
@@ -43,7 +50,7 @@ const requireAuth = (request: IncomingMessage) => {
|
||||
};
|
||||
|
||||
const jobRoute = (pathname: string) => {
|
||||
const match = /^\/jobs\/([^/]+)\/([^/]+)$/.exec(pathname);
|
||||
const match = /^\/jobs\/([^/]+)\/(.+)$/.exec(pathname);
|
||||
if (!match?.[1] || !match[2]) return null;
|
||||
return { jobId: decodeURIComponent(match[1]), action: match[2] };
|
||||
};
|
||||
@@ -57,8 +64,12 @@ export const startWorkerServer = () => {
|
||||
request.url ?? '/',
|
||||
`http://localhost:${env.httpPort}`,
|
||||
);
|
||||
if (url.pathname === '/health') {
|
||||
sendJson(response, 200, { ok: true, workerId: env.workerId });
|
||||
if (url.pathname === '/health' && request.method === 'GET') {
|
||||
sendJson(response, 200, await getWorkerHealth());
|
||||
return;
|
||||
}
|
||||
if (url.pathname === '/cleanup' && request.method === 'POST') {
|
||||
sendJson(response, 200, await cleanupOrphanedWorkspaces());
|
||||
return;
|
||||
}
|
||||
const route = jobRoute(url.pathname);
|
||||
@@ -108,6 +119,34 @@ export const startWorkerServer = () => {
|
||||
sendJson(response, 200, { success: true });
|
||||
return;
|
||||
}
|
||||
if (request.method === 'GET' && route.action === 'agent/status') {
|
||||
sendJson(response, 200, getWorkspaceAgentStatus(route.jobId));
|
||||
return;
|
||||
}
|
||||
if (request.method === 'POST' && route.action === 'agent/abort') {
|
||||
sendJson(response, 200, await abortWorkspaceAgent(route.jobId));
|
||||
return;
|
||||
}
|
||||
const interactionMatch =
|
||||
/^interactions\/([^/]+)\/reply$/.exec(route.action);
|
||||
if (request.method === 'POST' && interactionMatch?.[1]) {
|
||||
const body = await parseJson<{
|
||||
externalRequestId?: string;
|
||||
response?: string;
|
||||
}>(request);
|
||||
sendJson(
|
||||
response,
|
||||
200,
|
||||
await replyToInteraction(route.jobId, {
|
||||
interactionId: decodeURIComponent(
|
||||
interactionMatch[1],
|
||||
) as Id<'agentInteractionRequests'>,
|
||||
externalRequestId: body.externalRequestId ?? '',
|
||||
response: body.response ?? 'once',
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (request.method === 'POST' && route.action === 'run-command') {
|
||||
const body = await parseJson<{ command?: string }>(request);
|
||||
sendJson(
|
||||
@@ -126,12 +165,18 @@ export const startWorkerServer = () => {
|
||||
return;
|
||||
}
|
||||
sendJson(response, 404, { error: 'Not found' });
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
sendJson(response, message === 'Unauthorized' ? 401 : 500, {
|
||||
error: message,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
const status =
|
||||
message === 'Unauthorized'
|
||||
? 401
|
||||
: message.includes('not supported')
|
||||
? 409
|
||||
: 500;
|
||||
sendJson(response, status, {
|
||||
error: message,
|
||||
});
|
||||
}
|
||||
})();
|
||||
});
|
||||
server.listen(env.httpPort, () => {
|
||||
|
||||
Reference in New Issue
Block a user