Add /answer endpoint for rich prompt responses
Adds new POST /api/prompts/:id/answer endpoint that handles AnswerResponse types: - option: sends value + newline to PTY - text: sends user input + newline to PTY - tab_instructions: placeholder implementation sends selected_option (TODO: needs key sequences) Updated /approve and /reject endpoints to use "1\n" and "3\n" instead of "y\n" and "n\n" for consistency with option-based responses. Marked as legacy endpoints for backward compatibility.
This commit is contained in:
parent
cd7d1c0ea8
commit
5404598a5e
1 changed files with 72 additions and 5 deletions
|
|
@ -14,7 +14,12 @@ import {
|
|||
respondToPrompt,
|
||||
updateLastSeen,
|
||||
} from "./db";
|
||||
import type { ClientMessage, ServerMessage, SSEEvent } from "./types";
|
||||
import type {
|
||||
AnswerResponse,
|
||||
ClientMessage,
|
||||
ServerMessage,
|
||||
SSEEvent,
|
||||
} from "./types";
|
||||
|
||||
// Server state
|
||||
const sseClients = new Set<ReadableStreamDefaultController<string>>();
|
||||
|
|
@ -133,6 +138,67 @@ const server = Bun.serve<SessionData>({
|
|||
return new Response("Invalid prompt ID", { status: 400 });
|
||||
}
|
||||
|
||||
// New unified answer endpoint
|
||||
if (url.pathname.endsWith("/answer") && req.method === "POST") {
|
||||
const prompt = getPrompt(promptId);
|
||||
if (!prompt) {
|
||||
return new Response("Prompt not found", { status: 404 });
|
||||
}
|
||||
if (prompt.response !== null) {
|
||||
return new Response("Prompt already responded", { status: 400 });
|
||||
}
|
||||
|
||||
const body = (await req.json()) as { response?: unknown };
|
||||
if (!body.response || typeof body.response !== "object") {
|
||||
return new Response("Missing or invalid response", { status: 400 });
|
||||
}
|
||||
|
||||
const answer = body.response as AnswerResponse;
|
||||
let inputData: string;
|
||||
|
||||
// Handle each response type
|
||||
if (answer.type === "option") {
|
||||
inputData = `${answer.value}\n`;
|
||||
} else if (answer.type === "text") {
|
||||
inputData = `${answer.value}\n`;
|
||||
} else if (answer.type === "tab_instructions") {
|
||||
// TODO: Implement proper key sequence handling for tab instructions
|
||||
// For now, just send the selected option number
|
||||
inputData = `${answer.selected_option}\n`;
|
||||
console.debug(
|
||||
`TODO: tab_instructions needs key sequence implementation - instruction: "${answer.instruction}"`,
|
||||
);
|
||||
} else {
|
||||
return new Response("Invalid response type", { status: 400 });
|
||||
}
|
||||
|
||||
// Mark as responded in DB
|
||||
respondToPrompt(
|
||||
promptId,
|
||||
answer.type === "option" ? answer.value : "custom",
|
||||
);
|
||||
|
||||
// Notify CLI via WebSocket
|
||||
const ws = sessionWebSockets.get(prompt.session_id);
|
||||
if (ws) {
|
||||
const message: ServerMessage = { type: "input", data: inputData };
|
||||
ws.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
// Broadcast to dashboards
|
||||
broadcastSSE({
|
||||
type: "prompt_response",
|
||||
prompt_id: promptId,
|
||||
response:
|
||||
answer.type === "option" && answer.value === "1"
|
||||
? "approve"
|
||||
: "reject",
|
||||
});
|
||||
|
||||
return Response.json({ success: true });
|
||||
}
|
||||
|
||||
// Legacy approve endpoint (backward compatibility)
|
||||
if (url.pathname.endsWith("/approve") && req.method === "POST") {
|
||||
const prompt = getPrompt(promptId);
|
||||
if (!prompt) {
|
||||
|
|
@ -144,10 +210,10 @@ const server = Bun.serve<SessionData>({
|
|||
|
||||
respondToPrompt(promptId, "approve");
|
||||
|
||||
// Notify CLI via WebSocket
|
||||
// Notify CLI via WebSocket (using "1\n" for option 1)
|
||||
const ws = sessionWebSockets.get(prompt.session_id);
|
||||
if (ws) {
|
||||
const message: ServerMessage = { type: "input", data: "y\n" };
|
||||
const message: ServerMessage = { type: "input", data: "1\n" };
|
||||
ws.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
|
|
@ -161,6 +227,7 @@ const server = Bun.serve<SessionData>({
|
|||
return Response.json({ success: true });
|
||||
}
|
||||
|
||||
// Legacy reject endpoint (backward compatibility)
|
||||
if (url.pathname.endsWith("/reject") && req.method === "POST") {
|
||||
const prompt = getPrompt(promptId);
|
||||
if (!prompt) {
|
||||
|
|
@ -172,10 +239,10 @@ const server = Bun.serve<SessionData>({
|
|||
|
||||
respondToPrompt(promptId, "reject");
|
||||
|
||||
// Notify CLI via WebSocket
|
||||
// Notify CLI via WebSocket (using "3\n" for option 3)
|
||||
const ws = sessionWebSockets.get(prompt.session_id);
|
||||
if (ws) {
|
||||
const message: ServerMessage = { type: "input", data: "n\n" };
|
||||
const message: ServerMessage = { type: "input", data: "3\n" };
|
||||
ws.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue