@jeffreycao/copilot-api 1.11.0 → 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/README.md +2 -4
- package/README.zh-CN.md +2 -4
- package/dist/{auth-BjmTG37p.js → auth-D3ta3JW0.js} +3 -3
- package/dist/{auth-BjmTG37p.js.map → auth-D3ta3JW0.js.map} +1 -1
- package/dist/{check-usage-BB_15i5y.js → check-usage-Dh0WqiLC.js} +3 -3
- package/dist/{check-usage-BB_15i5y.js.map → check-usage-Dh0WqiLC.js.map} +1 -1
- package/dist/{config-Cni8ffEV.js → config-DA-Jdm0G.js} +2 -7
- package/dist/config-DA-Jdm0G.js.map +1 -0
- package/dist/{debug-DCP0VOJy.js → debug-BiX0ewij.js} +2 -2
- package/dist/{debug-DCP0VOJy.js.map → debug-BiX0ewij.js.map} +1 -1
- package/dist/main.js +4 -4
- package/dist/{server-xtwGZKXj.js → server--yUElsYz.js} +269 -103
- package/dist/server--yUElsYz.js.map +1 -0
- package/dist/{start-Gi73-qBt.js → start-CUCHCtOg.js} +4 -4
- package/dist/{start-Gi73-qBt.js.map → start-CUCHCtOg.js.map} +1 -1
- package/dist/{token-ZyYn_xJt.js → token-mo4KkQSp.js} +2 -2
- package/dist/{token-ZyYn_xJt.js.map → token-mo4KkQSp.js.map} +1 -1
- package/package.json +1 -1
- package/dist/config-Cni8ffEV.js.map +0 -1
- package/dist/server-xtwGZKXj.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { B as forwardError, C as prepareMessageProxyHeaders, E as compactMessageSections, F as createPooledWebSocketStream, I as createWebSocketUrl, M as generateTraceId, N as requestContext, O as compactSystemPromptStarts, P as resolveTraceId$1, R as state, S as prepareInteractionHeaders, T as compactAutoContinuePromptStarts, _ as getCopilotUsage, b as copilotWebSocketHeaders, d as generateRequestIdFromPayload, f as getRootSessionId, g as sleep, h as parseUserIdMetadata, j as forwardCodexResponses, m as isNullish, p as getUUID, r as setupCodexToken, s as cacheModels, v as copilotBaseUrl, x as prepareForCompact, y as copilotHeaders, z as HTTPError } from "./token-
|
|
1
|
+
import { a as getMessageApiWebSearchModel, c as getProviderConfig, d as getSmallModel, f as isMessagesApiEnabled, h as isResponsesApiWebSocketEnabled, i as getExtraPromptForModel, l as getRawProviderConfig, m as isResponsesApiWebSearchEnabled, n as getClaudeTokenMultiplier, o as getModelMappings, p as isResponsesApiContextManagementEnabled, r as getConfig, s as getModelResponsesApiCompactThreshold$1, t as getAnthropicApiKey, u as getReasoningEffortForModel, v as resolveMappedModel, x as PATHS, y as setModelMappings } from "./config-DA-Jdm0G.js";
|
|
2
|
+
import { B as forwardError, C as prepareMessageProxyHeaders, E as compactMessageSections, F as createPooledWebSocketStream, I as createWebSocketUrl, M as generateTraceId, N as requestContext, O as compactSystemPromptStarts, P as resolveTraceId$1, R as state, S as prepareInteractionHeaders, T as compactAutoContinuePromptStarts, _ as getCopilotUsage, b as copilotWebSocketHeaders, d as generateRequestIdFromPayload, f as getRootSessionId, g as sleep, h as parseUserIdMetadata, j as forwardCodexResponses, m as isNullish, p as getUUID, r as setupCodexToken, s as cacheModels, v as copilotBaseUrl, x as prepareForCompact, y as copilotHeaders, z as HTTPError } from "./token-mo4KkQSp.js";
|
|
3
3
|
import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-wA-fLduL.js";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
@@ -4004,6 +4004,52 @@ const stringifyToolSearchArguments = (argumentsValue) => {
|
|
|
4004
4004
|
return;
|
|
4005
4005
|
}
|
|
4006
4006
|
};
|
|
4007
|
+
//#endregion
|
|
4008
|
+
//#region src/lib/subagent.ts
|
|
4009
|
+
const subagentMarkerPrefix = "__SUBAGENT_MARKER__";
|
|
4010
|
+
//#endregion
|
|
4011
|
+
//#region src/routes/messages/subagent-marker.ts
|
|
4012
|
+
const parseSubagentMarkerFromFirstUser = (payload) => {
|
|
4013
|
+
const firstUserMessage = payload.messages.find((msg) => msg.role === "user" && Array.isArray(msg.content));
|
|
4014
|
+
if (!firstUserMessage || !Array.isArray(firstUserMessage.content)) return null;
|
|
4015
|
+
for (const block of firstUserMessage.content) {
|
|
4016
|
+
if (block.type !== "text") continue;
|
|
4017
|
+
const marker = parseSubagentMarkerFromSystemReminder(block.text);
|
|
4018
|
+
if (marker) return marker;
|
|
4019
|
+
}
|
|
4020
|
+
return null;
|
|
4021
|
+
};
|
|
4022
|
+
const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
4023
|
+
const startTag = "<system-reminder>";
|
|
4024
|
+
const endTag = "</system-reminder>";
|
|
4025
|
+
let searchFrom = 0;
|
|
4026
|
+
while (true) {
|
|
4027
|
+
const reminderStart = text.indexOf(startTag, searchFrom);
|
|
4028
|
+
if (reminderStart === -1) break;
|
|
4029
|
+
const contentStart = reminderStart + 17;
|
|
4030
|
+
const reminderEnd = text.indexOf(endTag, contentStart);
|
|
4031
|
+
if (reminderEnd === -1) break;
|
|
4032
|
+
const reminderContent = text.slice(contentStart, reminderEnd);
|
|
4033
|
+
const markerIndex = reminderContent.indexOf(subagentMarkerPrefix);
|
|
4034
|
+
if (markerIndex === -1) {
|
|
4035
|
+
searchFrom = reminderEnd + 18;
|
|
4036
|
+
continue;
|
|
4037
|
+
}
|
|
4038
|
+
const markerJson = reminderContent.slice(markerIndex + 19).trim();
|
|
4039
|
+
try {
|
|
4040
|
+
const parsed = JSON.parse(markerJson);
|
|
4041
|
+
if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {
|
|
4042
|
+
searchFrom = reminderEnd + 18;
|
|
4043
|
+
continue;
|
|
4044
|
+
}
|
|
4045
|
+
return parsed;
|
|
4046
|
+
} catch {
|
|
4047
|
+
searchFrom = reminderEnd + 18;
|
|
4048
|
+
continue;
|
|
4049
|
+
}
|
|
4050
|
+
}
|
|
4051
|
+
return null;
|
|
4052
|
+
};
|
|
4007
4053
|
const DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO = .9;
|
|
4008
4054
|
const responsesUtilsDependencies = {
|
|
4009
4055
|
getModelResponsesApiCompactThreshold: getModelResponsesApiCompactThreshold$1,
|
|
@@ -4305,7 +4351,7 @@ const prepareWebSearchResponsesPayload = (payload, options = {}) => {
|
|
|
4305
4351
|
...payload,
|
|
4306
4352
|
model: options.model ?? payload.model,
|
|
4307
4353
|
tools: [],
|
|
4308
|
-
stream:
|
|
4354
|
+
stream: true
|
|
4309
4355
|
}, options.subagentAgentId);
|
|
4310
4356
|
responsesPayload.tools = [buildResponsesWebSearchTool(config)];
|
|
4311
4357
|
responsesPayload.tool_choice = void 0;
|
|
@@ -4331,8 +4377,182 @@ const reconstructWebSearchResponse = (payload, result, options) => {
|
|
|
4331
4377
|
}
|
|
4332
4378
|
};
|
|
4333
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;
|
|
4334
4517
|
const createUsageRecorder = (payload, sessionId, webSearchModel) => webSearchFlowDependencies.createUsageRecorder(payload, sessionId, webSearchModel);
|
|
4335
4518
|
/**
|
|
4519
|
+
* Entry point for web-search detection and routing on /v1/messages.
|
|
4520
|
+
* Called after model mapping but before provider alias resolution and
|
|
4521
|
+
* preprocessing. Returns a Response when web search is handled (provider
|
|
4522
|
+
* reroute or responses-native), or `null` when no web_search tool is
|
|
4523
|
+
* present or the tool was stripped (caller continues normal flow).
|
|
4524
|
+
*
|
|
4525
|
+
* Uses a callback for provider forwarding to avoid circular imports.
|
|
4526
|
+
*/
|
|
4527
|
+
const tryHandleWebSearch = async (c, payload, options) => {
|
|
4528
|
+
if (!hasWebSearchServerTool(payload)) return null;
|
|
4529
|
+
const route = resolveWebSearchRoute(payload, {
|
|
4530
|
+
webSearchModel: getMessageApiWebSearchModel(),
|
|
4531
|
+
responsesWebSearchEnabled: isResponsesApiWebSearchEnabled()
|
|
4532
|
+
});
|
|
4533
|
+
if (route.kind === "provider") {
|
|
4534
|
+
payload.model = route.alias.model;
|
|
4535
|
+
return await options.forwardToProvider(c, payload, route.alias.provider);
|
|
4536
|
+
}
|
|
4537
|
+
if (route.kind === "responses") {
|
|
4538
|
+
const subagentMarker = parseSubagentMarkerFromFirstUser(payload);
|
|
4539
|
+
let sessionId = getRootSessionId(payload, c);
|
|
4540
|
+
const requestId = generateRequestIdFromPayload(payload, sessionId);
|
|
4541
|
+
if (!sessionId) sessionId = getUUID(requestId);
|
|
4542
|
+
const compactType = getCompactType(payload);
|
|
4543
|
+
return await handleWebSearchViaResponses(c, payload, {
|
|
4544
|
+
subagentMarker,
|
|
4545
|
+
webSearchModel: route.model,
|
|
4546
|
+
requestId,
|
|
4547
|
+
sessionId,
|
|
4548
|
+
compactType,
|
|
4549
|
+
logger: options.logger
|
|
4550
|
+
});
|
|
4551
|
+
}
|
|
4552
|
+
stripWebSearchServerTool(payload);
|
|
4553
|
+
return null;
|
|
4554
|
+
};
|
|
4555
|
+
/**
|
|
4336
4556
|
* Handles a web-search-only Claude (Messages API) request by switching it to a
|
|
4337
4557
|
* Responses-capable GPT model (`webSearchModel`), running Copilot's native
|
|
4338
4558
|
* /responses web_search in a single call, and reconstructing native Anthropic
|
|
@@ -4349,8 +4569,8 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
|
|
|
4349
4569
|
const selectedModel = findEndpointModel(webSearchModel);
|
|
4350
4570
|
const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
|
|
4351
4571
|
const transport = getResponsesTransportForModel(selectedModel, { compactType: options.compactType }) ?? "http";
|
|
4352
|
-
logger
|
|
4353
|
-
const
|
|
4572
|
+
debugJson(logger, `Switching web search request to model: ${webSearchModel}`, responsesPayload);
|
|
4573
|
+
const upstreamResult = await webSearchFlowDependencies.createResponses(responsesPayload, {
|
|
4354
4574
|
vision,
|
|
4355
4575
|
initiator,
|
|
4356
4576
|
transport,
|
|
@@ -4359,8 +4579,13 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
|
|
|
4359
4579
|
sessionId: options.sessionId,
|
|
4360
4580
|
compactType: options.compactType
|
|
4361
4581
|
});
|
|
4582
|
+
const result = isWebSearchResponsesStream(upstreamResult) ? await collectWebSearchResponsesStreamResult({
|
|
4583
|
+
errorMessagePrefix: "Web search responses stream",
|
|
4584
|
+
upstreamResponse: upstreamResult,
|
|
4585
|
+
logger
|
|
4586
|
+
}) : upstreamResult;
|
|
4362
4587
|
const { extract, response } = reconstructWebSearchResponse(payload, result, { requestId: options.requestId });
|
|
4363
|
-
logger
|
|
4588
|
+
debugJson(logger, `Web search via responses: ${extract.queries.length} quer(y/ies), ${extract.sources.length} source(s)`, result);
|
|
4364
4589
|
createUsageRecorder(payload, options.sessionId, webSearchModel)(normalizeResponsesUsage(result.usage));
|
|
4365
4590
|
if (!wantsStream) return c.json(response);
|
|
4366
4591
|
return streamSSE(c, async (stream) => {
|
|
@@ -4544,7 +4769,6 @@ async function handleProviderMessages(c) {
|
|
|
4544
4769
|
}
|
|
4545
4770
|
async function handleProviderMessagesForProvider(c, options) {
|
|
4546
4771
|
const { payload, provider } = options;
|
|
4547
|
-
const webSearchRerouteDepth = options.webSearchRerouteDepth ?? 0;
|
|
4548
4772
|
const providerConfig = await resolveProviderConfig(provider);
|
|
4549
4773
|
if (!providerConfig) return c.json({ error: {
|
|
4550
4774
|
message: `Provider '${provider}' not found or disabled`,
|
|
@@ -4557,15 +4781,6 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
4557
4781
|
provider
|
|
4558
4782
|
});
|
|
4559
4783
|
normalizeSystemMessages(payload);
|
|
4560
|
-
const providerWebSearchRoute = webSearchRerouteDepth === 0 ? resolveProviderWebSearchRoute(payload, { provider }) : null;
|
|
4561
|
-
if (providerWebSearchRoute) return await handleProviderMessagesForProvider(c, {
|
|
4562
|
-
payload: {
|
|
4563
|
-
...payload,
|
|
4564
|
-
model: providerWebSearchRoute.model
|
|
4565
|
-
},
|
|
4566
|
-
provider: providerWebSearchRoute.provider,
|
|
4567
|
-
webSearchRerouteDepth: webSearchRerouteDepth + 1
|
|
4568
|
-
});
|
|
4569
4784
|
applyModelDefaults(payload, modelConfig);
|
|
4570
4785
|
if (providerConfig.type === "openai-responses") {
|
|
4571
4786
|
if (hasWebSearchServerTool(payload)) {
|
|
@@ -4624,34 +4839,35 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
4624
4839
|
throw error;
|
|
4625
4840
|
}
|
|
4626
4841
|
}
|
|
4627
|
-
const resolveProviderWebSearchRoute = (payload, options) => {
|
|
4628
|
-
if (!hasWebSearchServerTool(payload) || !isWebSearchOnlyRequest(payload)) return null;
|
|
4629
|
-
const configuredModel = getProviderMessageApiWebSearchModel();
|
|
4630
|
-
if (!configuredModel) return null;
|
|
4631
|
-
const alias = parseProviderModelAlias(configuredModel);
|
|
4632
|
-
const provider = alias?.provider ?? options.provider;
|
|
4633
|
-
const model = alias?.model ?? configuredModel;
|
|
4634
|
-
if (provider === options.provider && model === payload.model) return null;
|
|
4635
|
-
return {
|
|
4636
|
-
model,
|
|
4637
|
-
provider
|
|
4638
|
-
};
|
|
4639
|
-
};
|
|
4640
4842
|
const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
4641
4843
|
const { payload, provider, providerConfig } = options;
|
|
4642
4844
|
const selectedModel = providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0;
|
|
4643
4845
|
const responsesPayload = prepareWebSearchResponsesPayload(payload);
|
|
4846
|
+
responsesPayload.stream = true;
|
|
4644
4847
|
applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens);
|
|
4645
4848
|
compactInputByLatestCompaction(responsesPayload);
|
|
4646
4849
|
debugJson(logger$5, "provider.messages.responses.web_search.request", {
|
|
4647
4850
|
payload: responsesPayload,
|
|
4648
4851
|
provider
|
|
4649
4852
|
});
|
|
4650
|
-
if (providerConfig.name === "codex")
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
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
|
+
}
|
|
4655
4871
|
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers);
|
|
4656
4872
|
if (!upstreamResponse.ok) {
|
|
4657
4873
|
logger$5.error("Failed to create provider web search responses", {
|
|
@@ -4660,6 +4876,16 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
4660
4876
|
});
|
|
4661
4877
|
throw new HTTPError("Failed to create provider web search responses", upstreamResponse);
|
|
4662
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
|
+
});
|
|
4663
4889
|
return respondWebSearchProviderMessagesJson(c, {
|
|
4664
4890
|
body: await upstreamResponse.json(),
|
|
4665
4891
|
payload,
|
|
@@ -5329,52 +5555,6 @@ const parseAnthropicStreamEvent = (data) => {
|
|
|
5329
5555
|
}
|
|
5330
5556
|
};
|
|
5331
5557
|
//#endregion
|
|
5332
|
-
//#region src/lib/subagent.ts
|
|
5333
|
-
const subagentMarkerPrefix = "__SUBAGENT_MARKER__";
|
|
5334
|
-
//#endregion
|
|
5335
|
-
//#region src/routes/messages/subagent-marker.ts
|
|
5336
|
-
const parseSubagentMarkerFromFirstUser = (payload) => {
|
|
5337
|
-
const firstUserMessage = payload.messages.find((msg) => msg.role === "user" && Array.isArray(msg.content));
|
|
5338
|
-
if (!firstUserMessage || !Array.isArray(firstUserMessage.content)) return null;
|
|
5339
|
-
for (const block of firstUserMessage.content) {
|
|
5340
|
-
if (block.type !== "text") continue;
|
|
5341
|
-
const marker = parseSubagentMarkerFromSystemReminder(block.text);
|
|
5342
|
-
if (marker) return marker;
|
|
5343
|
-
}
|
|
5344
|
-
return null;
|
|
5345
|
-
};
|
|
5346
|
-
const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
5347
|
-
const startTag = "<system-reminder>";
|
|
5348
|
-
const endTag = "</system-reminder>";
|
|
5349
|
-
let searchFrom = 0;
|
|
5350
|
-
while (true) {
|
|
5351
|
-
const reminderStart = text.indexOf(startTag, searchFrom);
|
|
5352
|
-
if (reminderStart === -1) break;
|
|
5353
|
-
const contentStart = reminderStart + 17;
|
|
5354
|
-
const reminderEnd = text.indexOf(endTag, contentStart);
|
|
5355
|
-
if (reminderEnd === -1) break;
|
|
5356
|
-
const reminderContent = text.slice(contentStart, reminderEnd);
|
|
5357
|
-
const markerIndex = reminderContent.indexOf(subagentMarkerPrefix);
|
|
5358
|
-
if (markerIndex === -1) {
|
|
5359
|
-
searchFrom = reminderEnd + 18;
|
|
5360
|
-
continue;
|
|
5361
|
-
}
|
|
5362
|
-
const markerJson = reminderContent.slice(markerIndex + 19).trim();
|
|
5363
|
-
try {
|
|
5364
|
-
const parsed = JSON.parse(markerJson);
|
|
5365
|
-
if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {
|
|
5366
|
-
searchFrom = reminderEnd + 18;
|
|
5367
|
-
continue;
|
|
5368
|
-
}
|
|
5369
|
-
return parsed;
|
|
5370
|
-
} catch {
|
|
5371
|
-
searchFrom = reminderEnd + 18;
|
|
5372
|
-
continue;
|
|
5373
|
-
}
|
|
5374
|
-
}
|
|
5375
|
-
return null;
|
|
5376
|
-
};
|
|
5377
|
-
//#endregion
|
|
5378
5558
|
//#region src/routes/messages/handler.ts
|
|
5379
5559
|
const logger$4 = createHandlerLogger("messages-handler");
|
|
5380
5560
|
const messagesFlowHandlers = {
|
|
@@ -5387,6 +5567,14 @@ async function handleCompletion(c) {
|
|
|
5387
5567
|
const requestedModel = anthropicPayload.model;
|
|
5388
5568
|
anthropicPayload.model = resolveMappedModel(anthropicPayload.model);
|
|
5389
5569
|
if (anthropicPayload.model !== requestedModel) consola.debug(`Resolved model mapping: ${requestedModel} -> ${anthropicPayload.model}`);
|
|
5570
|
+
const webSearchResult = await tryHandleWebSearch(c, anthropicPayload, {
|
|
5571
|
+
logger: logger$4,
|
|
5572
|
+
forwardToProvider: (ctx, payload, provider) => handleProviderMessagesForProvider(ctx, {
|
|
5573
|
+
payload,
|
|
5574
|
+
provider
|
|
5575
|
+
})
|
|
5576
|
+
});
|
|
5577
|
+
if (webSearchResult) return webSearchResult;
|
|
5390
5578
|
const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
|
|
5391
5579
|
if (providerModelAlias) {
|
|
5392
5580
|
anthropicPayload.model = providerModelAlias.model;
|
|
@@ -5421,28 +5609,6 @@ async function handleCompletion(c) {
|
|
|
5421
5609
|
if (state.manualApprove) await awaitApproval();
|
|
5422
5610
|
const selectedModel = findEndpointModel(anthropicPayload.model);
|
|
5423
5611
|
anthropicPayload.model = selectedModel?.id ?? anthropicPayload.model;
|
|
5424
|
-
if (hasWebSearchServerTool(anthropicPayload)) {
|
|
5425
|
-
const route = resolveWebSearchRoute(anthropicPayload, {
|
|
5426
|
-
webSearchModel: getMessageApiWebSearchModel(),
|
|
5427
|
-
responsesWebSearchEnabled: isResponsesApiWebSearchEnabled()
|
|
5428
|
-
});
|
|
5429
|
-
if (route.kind === "provider") {
|
|
5430
|
-
anthropicPayload.model = route.alias.model;
|
|
5431
|
-
return await handleProviderMessagesForProvider(c, {
|
|
5432
|
-
payload: anthropicPayload,
|
|
5433
|
-
provider: route.alias.provider
|
|
5434
|
-
});
|
|
5435
|
-
}
|
|
5436
|
-
if (route.kind === "responses") return await handleWebSearchViaResponses(c, anthropicPayload, {
|
|
5437
|
-
subagentMarker,
|
|
5438
|
-
webSearchModel: route.model,
|
|
5439
|
-
requestId,
|
|
5440
|
-
sessionId,
|
|
5441
|
-
compactType,
|
|
5442
|
-
logger: logger$4
|
|
5443
|
-
});
|
|
5444
|
-
stripWebSearchServerTool(anthropicPayload);
|
|
5445
|
-
}
|
|
5446
5612
|
if (shouldUseMessagesApi(selectedModel)) return await messagesFlowHandlers.handleWithMessagesApi(c, anthropicPayload, {
|
|
5447
5613
|
anthropicBetaHeader: anthropicBeta,
|
|
5448
5614
|
subagentMarker,
|
|
@@ -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
|