34 lines
1.8 KiB
TypeScript
34 lines
1.8 KiB
TypeScript
import type { Express } from "express";
|
|
import { z } from "zod";
|
|
import { interactionQuestionsSchema } from "../chat/interaction-request-contract.js";
|
|
import { isTrustedInternalBridgeRequest } from "../product/internal-bridge-auth.js";
|
|
import { operationalTaskClient, type OperationalTaskClient } from "../product/operational-task-client.js";
|
|
import { getRuntimeSessionContext } from "../runtime/sessionContext.js";
|
|
|
|
const inputSchema = z.object({ session_id: z.string().min(1).max(128),
|
|
request_id: z.string().uuid(), questions: interactionQuestionsSchema }).strict();
|
|
|
|
export function registerTaskQuestionBridge(app: Express, options: {
|
|
internalToken: string; client?: Pick<OperationalTaskClient, "askTaskUser">;
|
|
}) {
|
|
app.post("/internal/operational-task/questions", async (req, res) => {
|
|
if (!isTrustedInternalBridgeRequest(req, options.internalToken)) {
|
|
res.status(403).json({ message: "forbidden" }); return;
|
|
}
|
|
const parsed = inputSchema.safeParse(req.body);
|
|
if (!parsed.success) { res.status(400).json({ message: "invalid task questions" }); return; }
|
|
const { session_id, ...input } = parsed.data;
|
|
const context = getRuntimeSessionContext(session_id);
|
|
if (context?.purpose !== "task_execution" || !context.taskId) {
|
|
res.status(403).json({ message: "active investigation coordinator required" }); return;
|
|
}
|
|
try {
|
|
res.json(await (options.client ?? operationalTaskClient).askTaskUser(session_id, context.taskId,
|
|
{ ...input, sourceSessionId: context.clientSessionId }));
|
|
} catch (error) {
|
|
const status = error && typeof error === "object" && "status" in error && typeof error.status === "number" ? error.status : 502;
|
|
res.status(status).json({ message: error instanceof Error ? error.message : "task question failed" });
|
|
}
|
|
});
|
|
}
|