L16 Lotse-Chat für Monteure: Datenmodell, Provider mit Tool-Schleife, Vorschläge und Bestätigen über bestehende Services
Chatverlauf (LotseConversation/-Message) und Aktionskarten (LotseActionProposal) als Mandantentabellen mit RLS; Schalter lotseChatEnabled. Tool-Use-Schleife mit Runden- und Tokengrenze, Datenminimierung per Platzhalter, Auftragszuordnung im Sichtbarkeits-Scope, Bestätigen/Verwerfen/Alle bestätigen mit Hash, Ablauf und Idempotenz, Transkriptions-API. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { requireApiContext } from "@/server/api/context";
|
||||
import { ApiError, json, readFormData, withApi } from "@/server/api/respond";
|
||||
import { CHAT_AUDIO_MAX_BYTES, transcribeChatAudio } from "@/server/services/lotse/chat/transcribe";
|
||||
|
||||
/**
|
||||
* POST /api/v1/lotse/transcribe — multipart `file` (audio, max. 10 MB) → `{ text }` (lane L16).
|
||||
* Microphone key of the Lotse chat: the transcript is put into the input field and can be edited
|
||||
* before sending. The audio is not stored.
|
||||
*/
|
||||
export const POST = withApi(async (req: Request) => {
|
||||
const ctx = await requireApiContext("lotse", "lotse:use", "field:execute");
|
||||
const declared = Number(req.headers.get("content-length") ?? "0");
|
||||
if (declared > CHAT_AUDIO_MAX_BYTES + 1024 * 1024) throw new ApiError("payload_too_large", "audio too large");
|
||||
const form = await readFormData(req);
|
||||
const file = form.get("file");
|
||||
if (!(file instanceof File)) throw new ApiError("invalid", "file missing");
|
||||
if (file.size > CHAT_AUDIO_MAX_BYTES) throw new ApiError("payload_too_large", "audio too large");
|
||||
const result = await transcribeChatAudio(ctx, Buffer.from(await file.arrayBuffer()));
|
||||
return json(result);
|
||||
});
|
||||
Reference in New Issue
Block a user