@copilotkit/runtime
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
102 lines (100 loc) • 3.55 kB
JavaScript
require("reflect-metadata");
//#region src/v2/runtime/endpoints/single-route-helpers.ts
const METHOD_NAMES = [
"agent/run",
"agent/suggest",
"agent/connect",
"agent/stop",
"info",
"inspector/metadata",
"transcribe"
];
/**
* Detect a single-route JSON envelope on a request the multi-route router
* could not match.
*
* A single-endpoint client (`useSingleEndpoint` on the frontend provider)
* POSTs `{ method, params, body }` at the base path. A multi-route runtime
* matches no route for that path and would otherwise answer a bare 404, giving
* the developer nothing to go on. Recognising the envelope here lets the
* handler name the actual cause instead.
*
* Deliberately conservative: it reports a method only for a POST carrying a
* JSON body whose `method` is one the single-route endpoint actually accepts.
* Anything else is a genuine 404 and must stay one.
*
* @returns The envelope's method name, or `null` if this is not an envelope.
*/
async function detectSingleRouteEnvelope(request) {
if (request.method !== "POST") return null;
if (!(request.headers.get("content-type") || "").includes("application/json")) return null;
let envelope;
try {
envelope = await request.clone().json();
} catch {
return null;
}
if (typeof envelope !== "object" || envelope === null) return null;
const method = envelope.method;
if (typeof method !== "string") return null;
if (!METHOD_NAMES.includes(method)) return null;
return method;
}
async function parseMethodCall(request) {
if (!(request.headers.get("content-type") || "").includes("application/json")) throw createResponseError("Single-route endpoint expects JSON payloads", 415);
let jsonEnvelope;
try {
jsonEnvelope = await request.clone().json();
} catch {
throw createResponseError("Invalid JSON payload", 400);
}
return {
method: validateMethod(jsonEnvelope.method),
params: jsonEnvelope.params,
body: jsonEnvelope.body
};
}
function expectString(params, key) {
const value = params?.[key];
if (typeof value === "string" && value.trim().length > 0) return value;
throw createResponseError(`Missing or invalid parameter '${key}'`, 400);
}
function createJsonRequest(base, body) {
if (body === void 0 || body === null) throw createResponseError("Missing request body for JSON handler", 400);
const headers = new Headers(base.headers);
headers.set("content-type", "application/json");
headers.delete("content-length");
const serializedBody = serializeJsonBody(body);
return new Request(base.url, {
method: "POST",
headers,
body: serializedBody,
signal: base.signal
});
}
function createResponseError(message, status) {
return new Response(JSON.stringify({
error: "invalid_request",
message
}), {
status,
headers: { "Content-Type": "application/json" }
});
}
function validateMethod(method) {
if (!method) throw createResponseError("Missing method field", 400);
if (METHOD_NAMES.includes(method)) return method;
throw createResponseError(`Unsupported method '${method}'`, 400);
}
function serializeJsonBody(body) {
if (typeof body === "string") return body;
if (body instanceof Blob || body instanceof ArrayBuffer || body instanceof Uint8Array) return body;
if (body instanceof FormData || body instanceof URLSearchParams) return body;
return JSON.stringify(body);
}
//#endregion
exports.createJsonRequest = createJsonRequest;
exports.detectSingleRouteEnvelope = detectSingleRouteEnvelope;
exports.expectString = expectString;
exports.parseMethodCall = parseMethodCall;
//# sourceMappingURL=single-route-helpers.cjs.map