@jeffreycao/copilot-api 1.11.1 → 1.11.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/main.js +1 -1
- package/dist/{server-BxCf-DN5.js → server--yUElsYz.js} +176 -10
- package/dist/{server-BxCf-DN5.js.map → server--yUElsYz.js.map} +1 -1
- package/dist/{start-CFeefs3X.js → start-CUCHCtOg.js} +2 -2
- package/dist/{start-CFeefs3X.js.map → start-CUCHCtOg.js.map} +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -43,7 +43,7 @@ const { auth } = await import("./auth-D3ta3JW0.js");
|
|
|
43
43
|
const { checkUsage } = await import("./check-usage-Dh0WqiLC.js");
|
|
44
44
|
const { debug } = await import("./debug-BiX0ewij.js");
|
|
45
45
|
const { mcp } = await import("./mcp-DZgcvqQY.js");
|
|
46
|
-
const { start } = await import("./start-
|
|
46
|
+
const { start } = await import("./start-CUCHCtOg.js");
|
|
47
47
|
await runMain(defineCommand({
|
|
48
48
|
meta: {
|
|
49
49
|
name: "copilot-api",
|
|
@@ -4351,7 +4351,7 @@ const prepareWebSearchResponsesPayload = (payload, options = {}) => {
|
|
|
4351
4351
|
...payload,
|
|
4352
4352
|
model: options.model ?? payload.model,
|
|
4353
4353
|
tools: [],
|
|
4354
|
-
stream:
|
|
4354
|
+
stream: true
|
|
4355
4355
|
}, options.subagentAgentId);
|
|
4356
4356
|
responsesPayload.tools = [buildResponsesWebSearchTool(config)];
|
|
4357
4357
|
responsesPayload.tool_choice = void 0;
|
|
@@ -4377,6 +4377,143 @@ const reconstructWebSearchResponse = (payload, result, options) => {
|
|
|
4377
4377
|
}
|
|
4378
4378
|
};
|
|
4379
4379
|
};
|
|
4380
|
+
const collectWebSearchResponsesStreamResult = async ({ errorMessagePrefix = "Web search responses stream", parseEvent = parseWebSearchResponsesStreamEvent, upstreamResponse, logger }) => {
|
|
4381
|
+
const state = createWebSearchResponsesStreamCollection();
|
|
4382
|
+
for await (const chunk of upstreamResponse) {
|
|
4383
|
+
debugJson(logger, "Received web search responses stream chunk:", chunk.data);
|
|
4384
|
+
if (chunk.event === "ping") continue;
|
|
4385
|
+
if (!chunk.data || chunk.data === "[DONE]") continue;
|
|
4386
|
+
const parsed = parseEvent(chunk.data);
|
|
4387
|
+
if (!parsed) continue;
|
|
4388
|
+
collectWebSearchResponsesStreamEvent(parsed, state);
|
|
4389
|
+
if (parsed.type === "error") throw new Error(getStreamErrorMessage(parsed) ?? `${errorMessagePrefix} failed`);
|
|
4390
|
+
if (isResponsesTerminalEvent(parsed)) return buildWebSearchResponsesStreamResult(state);
|
|
4391
|
+
}
|
|
4392
|
+
throw new Error(`${errorMessagePrefix} ended without a terminal event`);
|
|
4393
|
+
};
|
|
4394
|
+
const parseWebSearchResponsesStreamEvent = (data) => {
|
|
4395
|
+
try {
|
|
4396
|
+
return JSON.parse(data);
|
|
4397
|
+
} catch {
|
|
4398
|
+
return null;
|
|
4399
|
+
}
|
|
4400
|
+
};
|
|
4401
|
+
const isWebSearchResponsesStream = (value) => {
|
|
4402
|
+
return Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
|
|
4403
|
+
};
|
|
4404
|
+
const isResponsesTerminalEvent = (event) => (event.type === "response.completed" || event.type === "response.failed" || event.type === "response.incomplete") && getResponsesResult(event.response) !== void 0;
|
|
4405
|
+
const createWebSearchResponsesStreamCollection = () => ({
|
|
4406
|
+
outputItemsByIndex: /* @__PURE__ */ new Map(),
|
|
4407
|
+
textPartsByKey: /* @__PURE__ */ new Map()
|
|
4408
|
+
});
|
|
4409
|
+
const collectWebSearchResponsesStreamEvent = (event, state) => {
|
|
4410
|
+
if (event.type === "response.created") {
|
|
4411
|
+
state.createdResponse = getResponsesResult(event.response);
|
|
4412
|
+
return;
|
|
4413
|
+
}
|
|
4414
|
+
if (isResponsesTerminalEvent(event)) {
|
|
4415
|
+
state.terminalResponse = event.response;
|
|
4416
|
+
return;
|
|
4417
|
+
}
|
|
4418
|
+
if (event.type === "response.output_item.added" || event.type === "response.output_item.done") {
|
|
4419
|
+
const outputIndex = getNumber(event.output_index);
|
|
4420
|
+
const item = getRecord(event.item);
|
|
4421
|
+
if (outputIndex !== void 0 && item) state.outputItemsByIndex.set(outputIndex, item);
|
|
4422
|
+
return;
|
|
4423
|
+
}
|
|
4424
|
+
if (event.type === "response.output_text.delta") {
|
|
4425
|
+
const part = getOrCreateOutputTextPart(event, state);
|
|
4426
|
+
const delta = getString(event.delta);
|
|
4427
|
+
if (part && delta) part.text += delta;
|
|
4428
|
+
return;
|
|
4429
|
+
}
|
|
4430
|
+
if (event.type === "response.output_text.done") {
|
|
4431
|
+
const part = getOrCreateOutputTextPart(event, state);
|
|
4432
|
+
const text = getString(event.text);
|
|
4433
|
+
if (part && text !== void 0) part.text = text;
|
|
4434
|
+
return;
|
|
4435
|
+
}
|
|
4436
|
+
if (event.type === "response.output_text.annotation.added") {
|
|
4437
|
+
const part = getOrCreateOutputTextPart(event, state);
|
|
4438
|
+
const annotation = event.annotation;
|
|
4439
|
+
if (part && annotation !== void 0) part.annotations.push(annotation);
|
|
4440
|
+
return;
|
|
4441
|
+
}
|
|
4442
|
+
if (event.type === "response.content_part.done") collectDoneContentPart(event, state);
|
|
4443
|
+
};
|
|
4444
|
+
const buildWebSearchResponsesStreamResult = (state) => {
|
|
4445
|
+
const response = state.terminalResponse ?? state.createdResponse;
|
|
4446
|
+
if (!response) throw new Error("Web search responses stream ended without a response");
|
|
4447
|
+
const output = buildCollectedWebSearchOutput(state);
|
|
4448
|
+
return {
|
|
4449
|
+
...response,
|
|
4450
|
+
output: output.length > 0 ? output : response.output
|
|
4451
|
+
};
|
|
4452
|
+
};
|
|
4453
|
+
const buildCollectedWebSearchOutput = (state) => [...state.outputItemsByIndex.entries()].sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex).map(([outputIndex, item]) => mergeOutputItemWithCollectedText(outputIndex, item, state));
|
|
4454
|
+
const mergeOutputItemWithCollectedText = (outputIndex, item, state) => {
|
|
4455
|
+
if (item.type !== "message") return item;
|
|
4456
|
+
const collectedParts = getCollectedTextParts(outputIndex, state);
|
|
4457
|
+
if (collectedParts.length === 0) return item;
|
|
4458
|
+
const content = getArray(item.content);
|
|
4459
|
+
for (const part of collectedParts) {
|
|
4460
|
+
const existingPart = getRecord(content[part.contentIndex]);
|
|
4461
|
+
content[part.contentIndex] = {
|
|
4462
|
+
...existingPart,
|
|
4463
|
+
type: "output_text",
|
|
4464
|
+
text: part.text,
|
|
4465
|
+
annotations: mergeAnnotations(existingPart?.annotations, part.annotations)
|
|
4466
|
+
};
|
|
4467
|
+
}
|
|
4468
|
+
return {
|
|
4469
|
+
...item,
|
|
4470
|
+
content
|
|
4471
|
+
};
|
|
4472
|
+
};
|
|
4473
|
+
const collectDoneContentPart = (event, state) => {
|
|
4474
|
+
const partRecord = getRecord(getRecord(event)?.part);
|
|
4475
|
+
if (partRecord?.type !== "output_text") return;
|
|
4476
|
+
const part = getOrCreateOutputTextPart(event, state);
|
|
4477
|
+
if (!part) return;
|
|
4478
|
+
const text = getString(partRecord.text);
|
|
4479
|
+
if (text !== void 0) part.text = text;
|
|
4480
|
+
const annotations = getArray(partRecord.annotations);
|
|
4481
|
+
if (annotations.length > 0) part.annotations.push(...annotations);
|
|
4482
|
+
};
|
|
4483
|
+
const getOrCreateOutputTextPart = (event, state) => {
|
|
4484
|
+
const eventRecord = getRecord(event);
|
|
4485
|
+
const outputIndex = getNumber(eventRecord?.output_index);
|
|
4486
|
+
const contentIndex = getNumber(eventRecord?.content_index);
|
|
4487
|
+
if (outputIndex === void 0 || contentIndex === void 0) return;
|
|
4488
|
+
const key = `${outputIndex}:${contentIndex}`;
|
|
4489
|
+
let part = state.textPartsByKey.get(key);
|
|
4490
|
+
if (!part) {
|
|
4491
|
+
part = {
|
|
4492
|
+
annotations: [],
|
|
4493
|
+
contentIndex,
|
|
4494
|
+
itemId: getString(eventRecord?.item_id),
|
|
4495
|
+
outputIndex,
|
|
4496
|
+
text: ""
|
|
4497
|
+
};
|
|
4498
|
+
state.textPartsByKey.set(key, part);
|
|
4499
|
+
}
|
|
4500
|
+
return part;
|
|
4501
|
+
};
|
|
4502
|
+
const getCollectedTextParts = (outputIndex, state) => [...state.textPartsByKey.values()].filter((part) => part.outputIndex === outputIndex).sort((left, right) => left.contentIndex - right.contentIndex || (left.itemId ?? "").localeCompare(right.itemId ?? ""));
|
|
4503
|
+
const mergeAnnotations = (existingAnnotations, collectedAnnotations) => {
|
|
4504
|
+
const annotations = getArray(existingAnnotations);
|
|
4505
|
+
annotations.push(...collectedAnnotations);
|
|
4506
|
+
return annotations;
|
|
4507
|
+
};
|
|
4508
|
+
const getResponsesResult = (value) => getRecord(value);
|
|
4509
|
+
const getRecord = (value) => value && typeof value === "object" ? value : void 0;
|
|
4510
|
+
const getArray = (value) => Array.isArray(value) ? Array.from(value) : [];
|
|
4511
|
+
const getStreamErrorMessage = (event) => {
|
|
4512
|
+
const eventRecord = getRecord(event);
|
|
4513
|
+
return getString(getRecord(eventRecord?.error)?.message) ?? getString(eventRecord?.message);
|
|
4514
|
+
};
|
|
4515
|
+
const getNumber = (value) => typeof value === "number" ? value : void 0;
|
|
4516
|
+
const getString = (value) => typeof value === "string" ? value : void 0;
|
|
4380
4517
|
const createUsageRecorder = (payload, sessionId, webSearchModel) => webSearchFlowDependencies.createUsageRecorder(payload, sessionId, webSearchModel);
|
|
4381
4518
|
/**
|
|
4382
4519
|
* Entry point for web-search detection and routing on /v1/messages.
|
|
@@ -4432,8 +4569,8 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
|
|
|
4432
4569
|
const selectedModel = findEndpointModel(webSearchModel);
|
|
4433
4570
|
const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
|
|
4434
4571
|
const transport = getResponsesTransportForModel(selectedModel, { compactType: options.compactType }) ?? "http";
|
|
4435
|
-
logger
|
|
4436
|
-
const
|
|
4572
|
+
debugJson(logger, `Switching web search request to model: ${webSearchModel}`, responsesPayload);
|
|
4573
|
+
const upstreamResult = await webSearchFlowDependencies.createResponses(responsesPayload, {
|
|
4437
4574
|
vision,
|
|
4438
4575
|
initiator,
|
|
4439
4576
|
transport,
|
|
@@ -4442,8 +4579,13 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
|
|
|
4442
4579
|
sessionId: options.sessionId,
|
|
4443
4580
|
compactType: options.compactType
|
|
4444
4581
|
});
|
|
4582
|
+
const result = isWebSearchResponsesStream(upstreamResult) ? await collectWebSearchResponsesStreamResult({
|
|
4583
|
+
errorMessagePrefix: "Web search responses stream",
|
|
4584
|
+
upstreamResponse: upstreamResult,
|
|
4585
|
+
logger
|
|
4586
|
+
}) : upstreamResult;
|
|
4445
4587
|
const { extract, response } = reconstructWebSearchResponse(payload, result, { requestId: options.requestId });
|
|
4446
|
-
logger
|
|
4588
|
+
debugJson(logger, `Web search via responses: ${extract.queries.length} quer(y/ies), ${extract.sources.length} source(s)`, result);
|
|
4447
4589
|
createUsageRecorder(payload, options.sessionId, webSearchModel)(normalizeResponsesUsage(result.usage));
|
|
4448
4590
|
if (!wantsStream) return c.json(response);
|
|
4449
4591
|
return streamSSE(c, async (stream) => {
|
|
@@ -4701,17 +4843,31 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
4701
4843
|
const { payload, provider, providerConfig } = options;
|
|
4702
4844
|
const selectedModel = providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0;
|
|
4703
4845
|
const responsesPayload = prepareWebSearchResponsesPayload(payload);
|
|
4846
|
+
responsesPayload.stream = true;
|
|
4704
4847
|
applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens);
|
|
4705
4848
|
compactInputByLatestCompaction(responsesPayload);
|
|
4706
4849
|
debugJson(logger$5, "provider.messages.responses.web_search.request", {
|
|
4707
4850
|
payload: responsesPayload,
|
|
4708
4851
|
provider
|
|
4709
4852
|
});
|
|
4710
|
-
if (providerConfig.name === "codex")
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4853
|
+
if (providerConfig.name === "codex") {
|
|
4854
|
+
const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl);
|
|
4855
|
+
if (isResponsesStream$1(upstreamResponse)) return respondWebSearchProviderMessagesJson(c, {
|
|
4856
|
+
body: await collectWebSearchResponsesStreamResult({
|
|
4857
|
+
errorMessagePrefix: `${provider} web search responses stream`,
|
|
4858
|
+
parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
|
|
4859
|
+
upstreamResponse,
|
|
4860
|
+
logger: logger$5
|
|
4861
|
+
}),
|
|
4862
|
+
payload,
|
|
4863
|
+
provider
|
|
4864
|
+
});
|
|
4865
|
+
return respondWebSearchProviderMessagesJson(c, {
|
|
4866
|
+
body: upstreamResponse,
|
|
4867
|
+
payload,
|
|
4868
|
+
provider
|
|
4869
|
+
});
|
|
4870
|
+
}
|
|
4715
4871
|
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers);
|
|
4716
4872
|
if (!upstreamResponse.ok) {
|
|
4717
4873
|
logger$5.error("Failed to create provider web search responses", {
|
|
@@ -4720,6 +4876,16 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
4720
4876
|
});
|
|
4721
4877
|
throw new HTTPError("Failed to create provider web search responses", upstreamResponse);
|
|
4722
4878
|
}
|
|
4879
|
+
if ((upstreamResponse.headers.get("content-type") ?? "").includes("text/event-stream")) return respondWebSearchProviderMessagesJson(c, {
|
|
4880
|
+
body: await collectWebSearchResponsesStreamResult({
|
|
4881
|
+
errorMessagePrefix: `${provider} web search responses stream`,
|
|
4882
|
+
parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
|
|
4883
|
+
upstreamResponse: events(upstreamResponse),
|
|
4884
|
+
logger: logger$5
|
|
4885
|
+
}),
|
|
4886
|
+
payload,
|
|
4887
|
+
provider
|
|
4888
|
+
});
|
|
4723
4889
|
return respondWebSearchProviderMessagesJson(c, {
|
|
4724
4890
|
body: await upstreamResponse.json(),
|
|
4725
4891
|
payload,
|
|
@@ -5970,4 +6136,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
|
|
|
5970
6136
|
//#endregion
|
|
5971
6137
|
export { server };
|
|
5972
6138
|
|
|
5973
|
-
//# sourceMappingURL=server
|
|
6139
|
+
//# sourceMappingURL=server--yUElsYz.js.map
|