@nick3/copilot-api 1.6.3 → 1.6.5

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 CHANGED
@@ -23,7 +23,7 @@ if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRI
23
23
  const { auth } = await import("./auth-Ba8K-1aX.js");
24
24
  const { checkUsage } = await import("./check-usage-ChbkyMqB.js");
25
25
  const { debug } = await import("./debug-BJfZVBB7.js");
26
- const { start } = await import("./start-BI0sDz7p.js");
26
+ const { start } = await import("./start-CXd89Ylu.js");
27
27
  await runMain(defineCommand({
28
28
  meta: {
29
29
  name: "copilot-api",
@@ -641,6 +641,7 @@ const TOOL_REFERENCE_TURN_BOUNDARY = "Tool loaded.";
641
641
  const IDE_EXECUTE_CODE_TOOL = "mcp__ide__executeCode";
642
642
  const IDE_GET_DIAGNOSTICS_TOOL = "mcp__ide__getDiagnostics";
643
643
  const IDE_GET_DIAGNOSTICS_DESCRIPTION = "Get language diagnostics from VS Code. Returns errors, warnings, information, and hints for files in the workspace.";
644
+ const PDF_FILE_READ_PREFIX = "PDF file read:";
644
645
  const getCompactCandidateText = (message) => {
645
646
  if (message.role !== "user") return "";
646
647
  if (typeof message.content === "string") return message.content;
@@ -706,31 +707,107 @@ const mergeContentWithAttachments = (tr, attachments) => {
706
707
  const isAttachmentBlock = (block) => {
707
708
  return block.type === "image" || block.type === "document";
708
709
  };
709
- const mergeAttachmentsIntoLastToolResult = (content) => {
710
- const attachments = content.filter((block) => isAttachmentBlock(block));
711
- if (attachments.length === 0) return content;
712
- const mergeableToolResultIndices = content.flatMap((block, index) => block.type === "tool_result" && !hasToolRef(block) ? [index] : []);
713
- if (mergeableToolResultIndices.length === 0) return content;
714
- const attachmentsByToolResultIndex = /* @__PURE__ */ new Map();
715
- if (mergeableToolResultIndices.length === attachments.length) for (const [index, toolResultIndex] of mergeableToolResultIndices.entries()) attachmentsByToolResultIndex.set(toolResultIndex, [attachments[index]]);
716
- else {
717
- const lastToolResultIndex = mergeableToolResultIndices.at(-1);
718
- if (lastToolResultIndex === void 0) return content;
719
- attachmentsByToolResultIndex.set(lastToolResultIndex, attachments);
720
- }
721
- const mergedContent = [];
722
- for (const [index, block] of content.entries()) {
723
- if (isAttachmentBlock(block)) continue;
724
- if (block.type === "tool_result") {
725
- const matchedAttachments = attachmentsByToolResultIndex.get(index);
726
- if (matchedAttachments) {
727
- mergedContent.push(mergeContentWithAttachments(block, matchedAttachments));
710
+ const getMergeableToolResultIndices = (toolResults) => {
711
+ return toolResults.flatMap((block, index) => block.is_error || hasToolRef(block) ? [] : [index]);
712
+ };
713
+ const mergeAttachmentsIntoToolResults = (toolResults, attachmentsByToolResultIndex) => {
714
+ if (attachmentsByToolResultIndex.size === 0) return toolResults;
715
+ return toolResults.map((block, index) => {
716
+ const matchedAttachments = attachmentsByToolResultIndex.get(index);
717
+ if (!matchedAttachments) return block;
718
+ return mergeContentWithAttachments(block, [...matchedAttachments].sort((left, right) => left.order - right.order).map(({ attachment }) => attachment));
719
+ });
720
+ };
721
+ const assignAttachmentsToToolResults = (target, attachments, options) => {
722
+ const { toolResultIndices } = options;
723
+ const fallbackToolResultIndices = options.fallbackToolResultIndices ?? toolResultIndices;
724
+ if (attachments.length === 0) return;
725
+ if (toolResultIndices.length > 0 && toolResultIndices.length === attachments.length) {
726
+ for (const [index, toolResultIndex] of toolResultIndices.entries()) {
727
+ const currentAttachments$1 = target.get(toolResultIndex);
728
+ if (currentAttachments$1) {
729
+ currentAttachments$1.push(attachments[index]);
728
730
  continue;
729
731
  }
732
+ target.set(toolResultIndex, [attachments[index]]);
730
733
  }
731
- mergedContent.push(block);
734
+ return;
735
+ }
736
+ const lastToolResultIndex = fallbackToolResultIndices.at(-1);
737
+ if (lastToolResultIndex === void 0) return;
738
+ const currentAttachments = target.get(lastToolResultIndex);
739
+ if (currentAttachments) {
740
+ currentAttachments.push(...attachments);
741
+ return;
732
742
  }
733
- return mergedContent;
743
+ target.set(lastToolResultIndex, [...attachments]);
744
+ };
745
+ const startsWithPdfFileRead = (toolResult) => {
746
+ if (typeof toolResult.content === "string") return toolResult.content.startsWith(PDF_FILE_READ_PREFIX);
747
+ if (toolResult.content.some((block) => block.type === "document")) return false;
748
+ if (toolResult.content.length === 0) return false;
749
+ const firstBlock = toolResult.content[0];
750
+ if (firstBlock.type !== "text") return false;
751
+ return firstBlock.text.startsWith(PDF_FILE_READ_PREFIX);
752
+ };
753
+ const collectMergeableUserContent = (content) => {
754
+ const toolResults = [];
755
+ const textBlocks = [];
756
+ const attachments = [];
757
+ for (const [order, block] of content.entries()) {
758
+ if (block.type === "tool_result") {
759
+ toolResults.push(block);
760
+ continue;
761
+ }
762
+ if (block.type === "text") {
763
+ textBlocks.push(block);
764
+ continue;
765
+ }
766
+ if (isAttachmentBlock(block)) {
767
+ attachments.push({
768
+ attachment: block,
769
+ order
770
+ });
771
+ continue;
772
+ }
773
+ return null;
774
+ }
775
+ return {
776
+ toolResults,
777
+ textBlocks,
778
+ attachments
779
+ };
780
+ };
781
+ const mergeAttachmentsForToolResults = (toolResults, attachments) => {
782
+ if (attachments.length === 0) return toolResults;
783
+ const documentBlocks = attachments.filter(({ attachment }) => attachment.type === "document");
784
+ const mergeableToolResultIndices = getMergeableToolResultIndices(toolResults);
785
+ const pdfReadToolResultIndices = mergeableToolResultIndices.filter((index) => startsWithPdfFileRead(toolResults[index]));
786
+ const attachmentsByToolResultIndex = /* @__PURE__ */ new Map();
787
+ let remainingAttachments = attachments;
788
+ let countMatchToolResultIndices = mergeableToolResultIndices;
789
+ if (documentBlocks.length > 0 && pdfReadToolResultIndices.length > 0) {
790
+ const matchedDocumentCount = Math.min(pdfReadToolResultIndices.length, documentBlocks.length);
791
+ const matchedDocuments = documentBlocks.slice(0, matchedDocumentCount);
792
+ const matchedDocumentOrders = new Set(matchedDocuments.map(({ order }) => order));
793
+ const matchedPdfToolResultIndices = pdfReadToolResultIndices.slice(0, matchedDocumentCount);
794
+ const matchedPdfToolResultIndexSet = new Set(matchedPdfToolResultIndices);
795
+ assignAttachmentsToToolResults(attachmentsByToolResultIndex, matchedDocuments, { toolResultIndices: matchedPdfToolResultIndices });
796
+ countMatchToolResultIndices = mergeableToolResultIndices.filter((index) => !matchedPdfToolResultIndexSet.has(index));
797
+ remainingAttachments = attachments.filter(({ attachment, order }) => attachment.type !== "document" || !matchedDocumentOrders.has(order));
798
+ }
799
+ assignAttachmentsToToolResults(attachmentsByToolResultIndex, remainingAttachments, {
800
+ toolResultIndices: countMatchToolResultIndices,
801
+ fallbackToolResultIndices: mergeableToolResultIndices
802
+ });
803
+ return mergeAttachmentsIntoToolResults(toolResults, attachmentsByToolResultIndex);
804
+ };
805
+ const mergeUserMessageContent = (content) => {
806
+ const mergeableContent = collectMergeableUserContent(content);
807
+ if (!mergeableContent) return null;
808
+ const { toolResults, textBlocks, attachments } = mergeableContent;
809
+ if (toolResults.length === 0 || textBlocks.length === 0 && attachments.length === 0) return null;
810
+ return mergeAttachmentsForToolResults(textBlocks.length === 0 ? toolResults : mergeToolResult(toolResults, textBlocks), attachments);
734
811
  };
735
812
  const mergeToolResult = (toolResults, textBlocks) => {
736
813
  if (toolResults.length === textBlocks.length) return toolResults.map((tr, i) => mergeContentWithText(tr, textBlocks[i]));
@@ -749,18 +826,8 @@ const mergeToolResultForClaude = (anthropicPayload, options) => {
749
826
  for (const [index, msg] of anthropicPayload.messages.entries()) {
750
827
  if (options?.skipLastMessage && index === lastMessageIndex) continue;
751
828
  if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
752
- msg.content = mergeAttachmentsIntoLastToolResult(msg.content);
753
- const toolResults = [];
754
- const textBlocks = [];
755
- let valid = true;
756
- for (const block of msg.content) if (block.type === "tool_result") toolResults.push(block);
757
- else if (block.type === "text") textBlocks.push(block);
758
- else {
759
- valid = false;
760
- break;
761
- }
762
- if (!valid || toolResults.length === 0 || textBlocks.length === 0) continue;
763
- msg.content = mergeToolResult(toolResults, textBlocks);
829
+ const mergedContent = mergeUserMessageContent(msg.content);
830
+ if (mergedContent) msg.content = mergedContent;
764
831
  }
765
832
  };
766
833
  const sanitizeIdeTools = (payload) => {
@@ -7403,4 +7470,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
7403
7470
 
7404
7471
  //#endregion
7405
7472
  export { server };
7406
- //# sourceMappingURL=server-Dw9SIlHL.js.map
7473
+ //# sourceMappingURL=server-kG7N_-Aj.js.map