@openhoo/hoopilot 0.9.0 → 0.9.2

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/index.cjs CHANGED
@@ -64,6 +64,7 @@ __export(index_exports, {
64
64
  parseLogFormat: () => parseLogFormat,
65
65
  parseLogLevel: () => parseLogLevel,
66
66
  readStoredCopilotAuth: () => readStoredCopilotAuth,
67
+ responsesCompactionResult: () => responsesCompactionResult,
67
68
  responsesRequestToChatCompletion: () => responsesRequestToChatCompletion,
68
69
  responsesResponseToAnthropicMessage: () => responsesResponseToAnthropicMessage,
69
70
  responsesStreamFromChatStream: () => responsesStreamFromChatStream,
@@ -212,6 +213,48 @@ function chatCompletionToResponse(completion, responseId) {
212
213
  usage
213
214
  });
214
215
  }
216
+ function responsesCompactionResult(upstreamText, isSse) {
217
+ const output = isSse ? compactionOutputFromResponsesSse(upstreamText) : compactionOutputFromResponse(asRecord(safeJsonParse(upstreamText)));
218
+ return { output };
219
+ }
220
+ function compactionOutputFromResponse(response) {
221
+ if (Array.isArray(response.output) && response.output.length > 0) {
222
+ return response.output;
223
+ }
224
+ const text = contentToText(response.output_text);
225
+ return text ? [messageOutputItem(text)] : [];
226
+ }
227
+ function compactionOutputFromResponsesSse(text) {
228
+ let deltas = "";
229
+ let completedOutput;
230
+ for (const block of text.split(/\r?\n\r?\n/)) {
231
+ const data = block.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).join("");
232
+ if (!data || data === "[DONE]") {
233
+ continue;
234
+ }
235
+ const record = asRecord(safeJsonParse(data));
236
+ const type = contentToText(record.type);
237
+ if (type === "response.output_text.delta") {
238
+ deltas += contentToText(record.delta);
239
+ } else if (type === "response.completed" || type === "response.incomplete") {
240
+ const response = asRecord(record.response);
241
+ if (Array.isArray(response.output)) {
242
+ completedOutput = response.output;
243
+ }
244
+ }
245
+ }
246
+ if (completedOutput && completedOutput.length > 0) {
247
+ return completedOutput;
248
+ }
249
+ return deltas ? [messageOutputItem(deltas)] : [];
250
+ }
251
+ function safeJsonParse(text) {
252
+ try {
253
+ return JSON.parse(text);
254
+ } catch {
255
+ return void 0;
256
+ }
257
+ }
215
258
  function chatCompletionToCompletion(completion) {
216
259
  return removeUndefined({
217
260
  choices: completionChoices(completion).map((choice, index) => {
@@ -2766,6 +2809,11 @@ function createHoopilotHandler(options = {}) {
2766
2809
  )
2767
2810
  );
2768
2811
  }
2812
+ if (request.method === "POST" && apiPath === "/v1/responses/compact") {
2813
+ return finish(
2814
+ await handleResponsesCompact(client, metrics, recordTokens, request, requestLogger)
2815
+ );
2816
+ }
2769
2817
  if (request.method === "POST" && apiPath === "/v1/responses") {
2770
2818
  return finish(
2771
2819
  await handleResponses(
@@ -2980,6 +3028,22 @@ async function handleResponses(client, metrics, recordTokens, request, logger, b
2980
3028
  )
2981
3029
  );
2982
3030
  }
3031
+ async function handleResponsesCompact(client, metrics, recordTokens, request, logger) {
3032
+ const body = await readJson(request);
3033
+ const upstream = await client.responses(
3034
+ JSON.stringify({ ...body, stream: false }),
3035
+ request.signal
3036
+ );
3037
+ metrics.recordUpstream("/responses", upstream.ok);
3038
+ if (!upstream.ok) {
3039
+ return proxyError(upstream, logger);
3040
+ }
3041
+ logUpstreamSuccess(logger, "/responses", upstream.status);
3042
+ const isSse = isStreamingResponse(upstream);
3043
+ const text = await upstream.text();
3044
+ recordResponseTextUsage(text, isSse, normalizeRequestedModel(body.model), recordTokens);
3045
+ return jsonResponse(responsesCompactionResult(text, isSse));
3046
+ }
2983
3047
  async function responseWithObservedUsage(response, fallbackModel, recordTokens, signal, bufferBody) {
2984
3048
  const isSse = isStreamingResponse(response);
2985
3049
  if (bufferBody && response.body) {
@@ -3299,6 +3363,8 @@ function canonicalApiPath(path) {
3299
3363
  return "/v1/messages/count_tokens";
3300
3364
  case "/responses":
3301
3365
  return "/v1/responses";
3366
+ case "/responses/compact":
3367
+ return "/v1/responses/compact";
3302
3368
  case "/usage":
3303
3369
  return "/v1/usage";
3304
3370
  default:
@@ -3333,6 +3399,9 @@ function routeFor(method, path) {
3333
3399
  if (method === "POST" && path === "/v1/completions") {
3334
3400
  return "completions";
3335
3401
  }
3402
+ if (method === "POST" && path === "/v1/responses/compact") {
3403
+ return "responses_compact";
3404
+ }
3336
3405
  if (method === "POST" && path === "/v1/responses") {
3337
3406
  return "responses";
3338
3407
  }
@@ -3441,6 +3510,7 @@ function safeParseJson(text) {
3441
3510
  parseLogFormat,
3442
3511
  parseLogLevel,
3443
3512
  readStoredCopilotAuth,
3513
+ responsesCompactionResult,
3444
3514
  responsesRequestToChatCompletion,
3445
3515
  responsesResponseToAnthropicMessage,
3446
3516
  responsesStreamFromChatStream,