@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/README.md +8 -0
- package/dist/cli.js +83 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +70 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -282,6 +282,16 @@ declare function normalizeChatCompletionRequest(request: JsonObject): JsonObject
|
|
|
282
282
|
declare function completionsRequestToChatCompletion(request: JsonObject): JsonObject;
|
|
283
283
|
declare function normalizeRequestedModel(model: unknown): string;
|
|
284
284
|
declare function chatCompletionToResponse(completion: JsonObject, responseId?: string): JsonObject;
|
|
285
|
+
/**
|
|
286
|
+
* Reduce a Copilot `/responses` result into the `{ output }` document Codex's
|
|
287
|
+
* remote-compaction client (`POST /responses/compact`) deserializes. Codex keeps
|
|
288
|
+
* only assistant/user message items from `output` and discards everything else,
|
|
289
|
+
* so a Responses `output` array passes through verbatim; when the upstream only
|
|
290
|
+
* exposes `output_text` (or, for a stream it did not honor `stream: false` on,
|
|
291
|
+
* `output_text` deltas) a single assistant message is synthesized instead. The
|
|
292
|
+
* input may be a unary JSON body or an SSE stream, so both framings are handled.
|
|
293
|
+
*/
|
|
294
|
+
declare function responsesCompactionResult(upstreamText: string, isSse: boolean): JsonObject;
|
|
285
295
|
declare function chatCompletionToCompletion(completion: JsonObject): JsonObject;
|
|
286
296
|
declare function completionStreamFromChatStream(chatStream: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;
|
|
287
297
|
declare function normalizeModelsResponse(upstream: unknown): JsonObject;
|
|
@@ -299,4 +309,4 @@ declare function extractTokenUsage(usage: unknown): TokenUsage | undefined;
|
|
|
299
309
|
declare function createHoopilotHandler(options?: HoopilotServerOptions): (request: Request) => Promise<Response>;
|
|
300
310
|
declare function startHoopilotServer(options?: HoopilotServerOptions): StartedHoopilotServer;
|
|
301
311
|
|
|
302
|
-
export { AnthropicCompatibilityError, COPILOT_USAGE_API_VERSION, type CopilotAccess, CopilotAuth, CopilotAuthError, type CopilotAuthOptions, CopilotClient, type CopilotQuota, type CopilotUsage, DEFAULT_GITHUB_API_BASE_URL, DEFAULT_LOG_FORMAT, DEFAULT_LOG_LEVEL, DEFAULT_MODEL, type FetchLike, type HoopilotLogger, type HoopilotLoggerOptions, type HoopilotServerOptions, type JsonObject, type LogFields, type LogFormat, type LogLevel, type LogMethod, type Logger, MetricsRegistry, type MetricsSnapshot, type ModelTokenTotals, PROMETHEUS_CONTENT_TYPE, type RequestObservation, type StartedHoopilotServer, type TokenUsage, anthropicMessagesToResponsesRequest, applyCopilotHeaders, applyGithubApiHeaders, authStorePath, chatCompletionToCompletion, chatCompletionToResponse, completionStreamFromChatStream, completionsRequestToChatCompletion, createHoopilotHandler, createHoopilotLogger, estimateAnthropicMessageTokens, extractTokenUsage, fallbackModels, githubCopilotDeviceLogin, noopLogger, normalizeChatCompletionRequest, normalizeCopilotUsage, normalizeModelsResponse, normalizeRequestedModel, observeResponseUsage, parseLogFormat, parseLogLevel, readStoredCopilotAuth, responsesRequestToChatCompletion, responsesResponseToAnthropicMessage, responsesStreamFromChatStream, responsesStreamToAnthropicStream, startHoopilotServer, writeStoredCopilotAuth };
|
|
312
|
+
export { AnthropicCompatibilityError, COPILOT_USAGE_API_VERSION, type CopilotAccess, CopilotAuth, CopilotAuthError, type CopilotAuthOptions, CopilotClient, type CopilotQuota, type CopilotUsage, DEFAULT_GITHUB_API_BASE_URL, DEFAULT_LOG_FORMAT, DEFAULT_LOG_LEVEL, DEFAULT_MODEL, type FetchLike, type HoopilotLogger, type HoopilotLoggerOptions, type HoopilotServerOptions, type JsonObject, type LogFields, type LogFormat, type LogLevel, type LogMethod, type Logger, MetricsRegistry, type MetricsSnapshot, type ModelTokenTotals, PROMETHEUS_CONTENT_TYPE, type RequestObservation, type StartedHoopilotServer, type TokenUsage, anthropicMessagesToResponsesRequest, applyCopilotHeaders, applyGithubApiHeaders, authStorePath, chatCompletionToCompletion, chatCompletionToResponse, completionStreamFromChatStream, completionsRequestToChatCompletion, createHoopilotHandler, createHoopilotLogger, estimateAnthropicMessageTokens, extractTokenUsage, fallbackModels, githubCopilotDeviceLogin, noopLogger, normalizeChatCompletionRequest, normalizeCopilotUsage, normalizeModelsResponse, normalizeRequestedModel, observeResponseUsage, parseLogFormat, parseLogLevel, readStoredCopilotAuth, responsesCompactionResult, responsesRequestToChatCompletion, responsesResponseToAnthropicMessage, responsesStreamFromChatStream, responsesStreamToAnthropicStream, startHoopilotServer, writeStoredCopilotAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -282,6 +282,16 @@ declare function normalizeChatCompletionRequest(request: JsonObject): JsonObject
|
|
|
282
282
|
declare function completionsRequestToChatCompletion(request: JsonObject): JsonObject;
|
|
283
283
|
declare function normalizeRequestedModel(model: unknown): string;
|
|
284
284
|
declare function chatCompletionToResponse(completion: JsonObject, responseId?: string): JsonObject;
|
|
285
|
+
/**
|
|
286
|
+
* Reduce a Copilot `/responses` result into the `{ output }` document Codex's
|
|
287
|
+
* remote-compaction client (`POST /responses/compact`) deserializes. Codex keeps
|
|
288
|
+
* only assistant/user message items from `output` and discards everything else,
|
|
289
|
+
* so a Responses `output` array passes through verbatim; when the upstream only
|
|
290
|
+
* exposes `output_text` (or, for a stream it did not honor `stream: false` on,
|
|
291
|
+
* `output_text` deltas) a single assistant message is synthesized instead. The
|
|
292
|
+
* input may be a unary JSON body or an SSE stream, so both framings are handled.
|
|
293
|
+
*/
|
|
294
|
+
declare function responsesCompactionResult(upstreamText: string, isSse: boolean): JsonObject;
|
|
285
295
|
declare function chatCompletionToCompletion(completion: JsonObject): JsonObject;
|
|
286
296
|
declare function completionStreamFromChatStream(chatStream: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;
|
|
287
297
|
declare function normalizeModelsResponse(upstream: unknown): JsonObject;
|
|
@@ -299,4 +309,4 @@ declare function extractTokenUsage(usage: unknown): TokenUsage | undefined;
|
|
|
299
309
|
declare function createHoopilotHandler(options?: HoopilotServerOptions): (request: Request) => Promise<Response>;
|
|
300
310
|
declare function startHoopilotServer(options?: HoopilotServerOptions): StartedHoopilotServer;
|
|
301
311
|
|
|
302
|
-
export { AnthropicCompatibilityError, COPILOT_USAGE_API_VERSION, type CopilotAccess, CopilotAuth, CopilotAuthError, type CopilotAuthOptions, CopilotClient, type CopilotQuota, type CopilotUsage, DEFAULT_GITHUB_API_BASE_URL, DEFAULT_LOG_FORMAT, DEFAULT_LOG_LEVEL, DEFAULT_MODEL, type FetchLike, type HoopilotLogger, type HoopilotLoggerOptions, type HoopilotServerOptions, type JsonObject, type LogFields, type LogFormat, type LogLevel, type LogMethod, type Logger, MetricsRegistry, type MetricsSnapshot, type ModelTokenTotals, PROMETHEUS_CONTENT_TYPE, type RequestObservation, type StartedHoopilotServer, type TokenUsage, anthropicMessagesToResponsesRequest, applyCopilotHeaders, applyGithubApiHeaders, authStorePath, chatCompletionToCompletion, chatCompletionToResponse, completionStreamFromChatStream, completionsRequestToChatCompletion, createHoopilotHandler, createHoopilotLogger, estimateAnthropicMessageTokens, extractTokenUsage, fallbackModels, githubCopilotDeviceLogin, noopLogger, normalizeChatCompletionRequest, normalizeCopilotUsage, normalizeModelsResponse, normalizeRequestedModel, observeResponseUsage, parseLogFormat, parseLogLevel, readStoredCopilotAuth, responsesRequestToChatCompletion, responsesResponseToAnthropicMessage, responsesStreamFromChatStream, responsesStreamToAnthropicStream, startHoopilotServer, writeStoredCopilotAuth };
|
|
312
|
+
export { AnthropicCompatibilityError, COPILOT_USAGE_API_VERSION, type CopilotAccess, CopilotAuth, CopilotAuthError, type CopilotAuthOptions, CopilotClient, type CopilotQuota, type CopilotUsage, DEFAULT_GITHUB_API_BASE_URL, DEFAULT_LOG_FORMAT, DEFAULT_LOG_LEVEL, DEFAULT_MODEL, type FetchLike, type HoopilotLogger, type HoopilotLoggerOptions, type HoopilotServerOptions, type JsonObject, type LogFields, type LogFormat, type LogLevel, type LogMethod, type Logger, MetricsRegistry, type MetricsSnapshot, type ModelTokenTotals, PROMETHEUS_CONTENT_TYPE, type RequestObservation, type StartedHoopilotServer, type TokenUsage, anthropicMessagesToResponsesRequest, applyCopilotHeaders, applyGithubApiHeaders, authStorePath, chatCompletionToCompletion, chatCompletionToResponse, completionStreamFromChatStream, completionsRequestToChatCompletion, createHoopilotHandler, createHoopilotLogger, estimateAnthropicMessageTokens, extractTokenUsage, fallbackModels, githubCopilotDeviceLogin, noopLogger, normalizeChatCompletionRequest, normalizeCopilotUsage, normalizeModelsResponse, normalizeRequestedModel, observeResponseUsage, parseLogFormat, parseLogLevel, readStoredCopilotAuth, responsesCompactionResult, responsesRequestToChatCompletion, responsesResponseToAnthropicMessage, responsesStreamFromChatStream, responsesStreamToAnthropicStream, startHoopilotServer, writeStoredCopilotAuth };
|
package/dist/index.js
CHANGED
|
@@ -137,6 +137,48 @@ function chatCompletionToResponse(completion, responseId) {
|
|
|
137
137
|
usage
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
|
+
function responsesCompactionResult(upstreamText, isSse) {
|
|
141
|
+
const output = isSse ? compactionOutputFromResponsesSse(upstreamText) : compactionOutputFromResponse(asRecord(safeJsonParse(upstreamText)));
|
|
142
|
+
return { output };
|
|
143
|
+
}
|
|
144
|
+
function compactionOutputFromResponse(response) {
|
|
145
|
+
if (Array.isArray(response.output) && response.output.length > 0) {
|
|
146
|
+
return response.output;
|
|
147
|
+
}
|
|
148
|
+
const text = contentToText(response.output_text);
|
|
149
|
+
return text ? [messageOutputItem(text)] : [];
|
|
150
|
+
}
|
|
151
|
+
function compactionOutputFromResponsesSse(text) {
|
|
152
|
+
let deltas = "";
|
|
153
|
+
let completedOutput;
|
|
154
|
+
for (const block of text.split(/\r?\n\r?\n/)) {
|
|
155
|
+
const data = block.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).join("");
|
|
156
|
+
if (!data || data === "[DONE]") {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const record = asRecord(safeJsonParse(data));
|
|
160
|
+
const type = contentToText(record.type);
|
|
161
|
+
if (type === "response.output_text.delta") {
|
|
162
|
+
deltas += contentToText(record.delta);
|
|
163
|
+
} else if (type === "response.completed" || type === "response.incomplete") {
|
|
164
|
+
const response = asRecord(record.response);
|
|
165
|
+
if (Array.isArray(response.output)) {
|
|
166
|
+
completedOutput = response.output;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (completedOutput && completedOutput.length > 0) {
|
|
171
|
+
return completedOutput;
|
|
172
|
+
}
|
|
173
|
+
return deltas ? [messageOutputItem(deltas)] : [];
|
|
174
|
+
}
|
|
175
|
+
function safeJsonParse(text) {
|
|
176
|
+
try {
|
|
177
|
+
return JSON.parse(text);
|
|
178
|
+
} catch {
|
|
179
|
+
return void 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
140
182
|
function chatCompletionToCompletion(completion) {
|
|
141
183
|
return removeUndefined({
|
|
142
184
|
choices: completionChoices(completion).map((choice, index) => {
|
|
@@ -2691,6 +2733,11 @@ function createHoopilotHandler(options = {}) {
|
|
|
2691
2733
|
)
|
|
2692
2734
|
);
|
|
2693
2735
|
}
|
|
2736
|
+
if (request.method === "POST" && apiPath === "/v1/responses/compact") {
|
|
2737
|
+
return finish(
|
|
2738
|
+
await handleResponsesCompact(client, metrics, recordTokens, request, requestLogger)
|
|
2739
|
+
);
|
|
2740
|
+
}
|
|
2694
2741
|
if (request.method === "POST" && apiPath === "/v1/responses") {
|
|
2695
2742
|
return finish(
|
|
2696
2743
|
await handleResponses(
|
|
@@ -2905,6 +2952,22 @@ async function handleResponses(client, metrics, recordTokens, request, logger, b
|
|
|
2905
2952
|
)
|
|
2906
2953
|
);
|
|
2907
2954
|
}
|
|
2955
|
+
async function handleResponsesCompact(client, metrics, recordTokens, request, logger) {
|
|
2956
|
+
const body = await readJson(request);
|
|
2957
|
+
const upstream = await client.responses(
|
|
2958
|
+
JSON.stringify({ ...body, stream: false }),
|
|
2959
|
+
request.signal
|
|
2960
|
+
);
|
|
2961
|
+
metrics.recordUpstream("/responses", upstream.ok);
|
|
2962
|
+
if (!upstream.ok) {
|
|
2963
|
+
return proxyError(upstream, logger);
|
|
2964
|
+
}
|
|
2965
|
+
logUpstreamSuccess(logger, "/responses", upstream.status);
|
|
2966
|
+
const isSse = isStreamingResponse(upstream);
|
|
2967
|
+
const text = await upstream.text();
|
|
2968
|
+
recordResponseTextUsage(text, isSse, normalizeRequestedModel(body.model), recordTokens);
|
|
2969
|
+
return jsonResponse(responsesCompactionResult(text, isSse));
|
|
2970
|
+
}
|
|
2908
2971
|
async function responseWithObservedUsage(response, fallbackModel, recordTokens, signal, bufferBody) {
|
|
2909
2972
|
const isSse = isStreamingResponse(response);
|
|
2910
2973
|
if (bufferBody && response.body) {
|
|
@@ -3224,6 +3287,8 @@ function canonicalApiPath(path) {
|
|
|
3224
3287
|
return "/v1/messages/count_tokens";
|
|
3225
3288
|
case "/responses":
|
|
3226
3289
|
return "/v1/responses";
|
|
3290
|
+
case "/responses/compact":
|
|
3291
|
+
return "/v1/responses/compact";
|
|
3227
3292
|
case "/usage":
|
|
3228
3293
|
return "/v1/usage";
|
|
3229
3294
|
default:
|
|
@@ -3258,6 +3323,9 @@ function routeFor(method, path) {
|
|
|
3258
3323
|
if (method === "POST" && path === "/v1/completions") {
|
|
3259
3324
|
return "completions";
|
|
3260
3325
|
}
|
|
3326
|
+
if (method === "POST" && path === "/v1/responses/compact") {
|
|
3327
|
+
return "responses_compact";
|
|
3328
|
+
}
|
|
3261
3329
|
if (method === "POST" && path === "/v1/responses") {
|
|
3262
3330
|
return "responses";
|
|
3263
3331
|
}
|
|
@@ -3365,6 +3433,7 @@ export {
|
|
|
3365
3433
|
parseLogFormat,
|
|
3366
3434
|
parseLogLevel,
|
|
3367
3435
|
readStoredCopilotAuth,
|
|
3436
|
+
responsesCompactionResult,
|
|
3368
3437
|
responsesRequestToChatCompletion,
|
|
3369
3438
|
responsesResponseToAnthropicMessage,
|
|
3370
3439
|
responsesStreamFromChatStream,
|