@openhoo/hoopilot 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -909,12 +909,13 @@ function createHoopilotHandler(options = {}) {
909
909
  return async (request) => {
910
910
  const startedAt = performance.now();
911
911
  const url = new URL(request.url);
912
+ const apiPath = canonicalApiPath(url.pathname);
912
913
  const requestId = requestIdFor(request);
913
914
  const requestLogger = logger.child({
914
915
  method: request.method,
915
916
  path: url.pathname,
916
917
  requestId,
917
- route: routeFor(request.method, url.pathname)
918
+ route: routeFor(request.method, apiPath)
918
919
  });
919
920
  if (request.method === "OPTIONS") {
920
921
  return finishResponse(new Response(null, { headers: corsHeaders() }), {
@@ -935,7 +936,7 @@ function createHoopilotHandler(options = {}) {
935
936
  );
936
937
  }
937
938
  try {
938
- if (request.method === "GET" && (url.pathname === "/" || url.pathname === "/healthz")) {
939
+ if (request.method === "GET" && (apiPath === "/" || apiPath === "/healthz")) {
939
940
  return finishResponse(
940
941
  jsonResponse({
941
942
  name: "hoopilot",
@@ -945,28 +946,28 @@ function createHoopilotHandler(options = {}) {
945
946
  { logger: requestLogger, requestId, startedAt }
946
947
  );
947
948
  }
948
- if (request.method === "GET" && url.pathname === "/v1/models") {
949
+ if (request.method === "GET" && apiPath === "/v1/models") {
949
950
  return finishResponse(await handleModels(client, request.signal, requestLogger), {
950
951
  logger: requestLogger,
951
952
  requestId,
952
953
  startedAt
953
954
  });
954
955
  }
955
- if (request.method === "POST" && url.pathname === "/v1/chat/completions") {
956
+ if (request.method === "POST" && apiPath === "/v1/chat/completions") {
956
957
  return finishResponse(await handleChatCompletions(client, request, requestLogger), {
957
958
  logger: requestLogger,
958
959
  requestId,
959
960
  startedAt
960
961
  });
961
962
  }
962
- if (request.method === "POST" && url.pathname === "/v1/completions") {
963
+ if (request.method === "POST" && apiPath === "/v1/completions") {
963
964
  return finishResponse(await handleCompletions(client, request, requestLogger), {
964
965
  logger: requestLogger,
965
966
  requestId,
966
967
  startedAt
967
968
  });
968
969
  }
969
- if (request.method === "POST" && url.pathname === "/v1/responses") {
970
+ if (request.method === "POST" && apiPath === "/v1/responses") {
970
971
  return finishResponse(await handleResponses(client, request, requestLogger), {
971
972
  logger: requestLogger,
972
973
  requestId,
@@ -1231,6 +1232,21 @@ function requestIdFor(request) {
1231
1232
  const existing = request.headers.get("x-request-id")?.trim();
1232
1233
  return existing || crypto.randomUUID();
1233
1234
  }
1235
+ function canonicalApiPath(path) {
1236
+ const withoutTrailingSlash = path.length > 1 ? path.replace(/\/+$/, "") : path;
1237
+ switch (withoutTrailingSlash) {
1238
+ case "/models":
1239
+ return "/v1/models";
1240
+ case "/chat/completions":
1241
+ return "/v1/chat/completions";
1242
+ case "/completions":
1243
+ return "/v1/completions";
1244
+ case "/responses":
1245
+ return "/v1/responses";
1246
+ default:
1247
+ return withoutTrailingSlash;
1248
+ }
1249
+ }
1234
1250
  function routeFor(method, path) {
1235
1251
  if (method === "OPTIONS") {
1236
1252
  return "cors.preflight";