44 lines
2.4 KiB
TypeScript
44 lines
2.4 KiB
TypeScript
import type { Router } from "express";
|
|
import { z } from "zod";
|
|
import { getLocalAgentContext } from "../context/localContext.js";
|
|
import type { OpencodeRuntimeAdapter } from "../runtime/opencode.js";
|
|
import { readPurpose, type SessionMetadataStore } from "../sessions/metadataStore.js";
|
|
import type { ChatRunState } from "./chatRunState.js";
|
|
|
|
const id = z.string().regex(/^msg_[a-f0-9]{32}$/);
|
|
const update = z.object({ delivery: z.enum(["steer", "queue"]) }).strict();
|
|
|
|
export function registerResponseInputRoutes(router: Router, options: {
|
|
runtime: OpencodeRuntimeAdapter; sessionMetadataStore: SessionMetadataStore; runState: ChatRunState;
|
|
}) {
|
|
for (const method of ["get", "patch", "delete"] as const) {
|
|
router[method](method === "get" ? "/session/:session_id/inputs" : "/session/:session_id/inputs/:input_id", async (req, res) => {
|
|
const sessionId = String(req.params.session_id);
|
|
try {
|
|
const record = await options.sessionMetadataStore.get(getLocalAgentContext(req), sessionId);
|
|
if (!record || readPurpose(record) === "task_execution") { res.status(404).json({ message: "session not found" }); return; }
|
|
if (method === "get") {
|
|
res.json({ items: await options.runtime.listPendingUserInputs(sessionId) });
|
|
return;
|
|
}
|
|
const inputId = id.parse((req.params as Record<string, string>).input_id);
|
|
if (method === "delete") {
|
|
const input = await options.runtime.cancelPendingUserInput(sessionId, inputId);
|
|
options.runState.activeRuns.get(sessionId)?.inputs?.observe("session.inbox.cancelled", { inboxID: inputId });
|
|
res.json(input);
|
|
return;
|
|
}
|
|
const { delivery } = update.parse(req.body);
|
|
const input = await options.runtime.updatePendingUserInput(sessionId, inputId, delivery);
|
|
options.runState.activeRuns.get(sessionId)?.inputs?.observe("session.inbox.delivery.changed", { inboxID: inputId, delivery });
|
|
res.json(input);
|
|
} catch (error) {
|
|
if (error instanceof z.ZodError) { res.status(400).json({ message: "invalid input delivery" }); return; }
|
|
const status = error && typeof error === "object" && "status" in error ? error.status : undefined;
|
|
res.status(status === 404 || status === 409 ? 409 : 503).json({ message: status === 404 || status === 409
|
|
? "Message has already been consumed or is unavailable" : "Input inbox is unavailable" });
|
|
}
|
|
});
|
|
}
|
|
}
|