@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.
@@ -1,5 +1,5 @@
1
- import { S as PATHS, a as getMessageApiWebSearchModel, b as setModelMappings, c as getProviderConfig, d as getReasoningEffortForModel, f as getSmallModel, g as isResponsesApiWebSocketEnabled, h as isResponsesApiWebSearchEnabled, i as getExtraPromptForModel, l as getProviderMessageApiWebSearchModel, m as isResponsesApiContextManagementEnabled, n as getClaudeTokenMultiplier, o as getModelMappings, p as isMessagesApiEnabled, r as getConfig, s as getModelResponsesApiCompactThreshold$1, t as getAnthropicApiKey, u as getRawProviderConfig, y as resolveMappedModel } from "./config-Cni8ffEV.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-ZyYn_xJt.js";
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: false
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.debug(`Switching web search request to model: ${webSearchModel} ${JSON.stringify(responsesPayload)}`);
4353
- const result = await webSearchFlowDependencies.createResponses(responsesPayload, {
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.debug(`Web search via responses: ${extract.queries.length} quer(y/ies), ${extract.sources.length} source(s), ${JSON.stringify(result)}`);
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") return respondWebSearchProviderMessagesJson(c, {
4651
- body: await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl),
4652
- payload,
4653
- provider
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-xtwGZKXj.js.map
6139
+ //# sourceMappingURL=server--yUElsYz.js.map