copilot-api-plus 1.2.46 → 1.2.48
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.en.md +1 -0
- package/README.md +1 -0
- package/dist/main.js +80 -2
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -51,6 +51,7 @@ English | [简体中文](README.md)
|
|
|
51
51
|
| ✂️ **Context Passthrough** | Full context passthrough to upstream API; clients (e.g. Claude Code) manage compression |
|
|
52
52
|
| 🔍 **Smart Model Matching** | Handles model name format differences (date suffixes, dash/dot versions, etc.) |
|
|
53
53
|
| 🧠 **Thinking Chain** | Automatically enables deep thinking for supported models, improving code quality |
|
|
54
|
+
| 🧹 **Reminder Stripping** | Strips client-injected reminder blocks before forwarding, avoiding upstream false-positive rejections |
|
|
54
55
|
|
|
55
56
|
---
|
|
56
57
|
|
package/README.md
CHANGED
package/dist/main.js
CHANGED
|
@@ -2760,6 +2760,84 @@ function getAnthropicToolUseBlocks(toolCalls) {
|
|
|
2760
2760
|
}));
|
|
2761
2761
|
}
|
|
2762
2762
|
//#endregion
|
|
2763
|
+
//#region src/routes/messages/strip-reminders.ts
|
|
2764
|
+
/** Matches `<system-reminder>…</system-reminder>` non-greedy, across lines. */
|
|
2765
|
+
const REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
|
|
2766
|
+
/** Cheap sentinel that lets callers skip the regex scan. */
|
|
2767
|
+
const REMINDER_OPEN_TAG = "<system-reminder>";
|
|
2768
|
+
/**
|
|
2769
|
+
* Strip every `<system-reminder>` block from a plain string.
|
|
2770
|
+
*
|
|
2771
|
+
* Collapses runs of 3+ newlines left behind by the removal into a
|
|
2772
|
+
* single blank line, then trims leading/trailing whitespace. Returns
|
|
2773
|
+
* the same reference if no reminder was present (zero allocation).
|
|
2774
|
+
*/
|
|
2775
|
+
function stripText(s) {
|
|
2776
|
+
if (!s.includes(REMINDER_OPEN_TAG)) return s;
|
|
2777
|
+
return s.replaceAll(REMINDER_RE, "").replaceAll(/\n{3,}/g, "\n\n").trim();
|
|
2778
|
+
}
|
|
2779
|
+
/**
|
|
2780
|
+
* Strip reminders from a block array. Non-text blocks pass through.
|
|
2781
|
+
* Text blocks that become empty after stripping are filtered out.
|
|
2782
|
+
* Returns the same reference if nothing changed.
|
|
2783
|
+
*/
|
|
2784
|
+
function stripBlocks(content) {
|
|
2785
|
+
if (!content.some((b) => b.type === "text" && b.text.includes(REMINDER_OPEN_TAG))) return content;
|
|
2786
|
+
const out = [];
|
|
2787
|
+
for (const b of content) {
|
|
2788
|
+
if (b.type !== "text") {
|
|
2789
|
+
out.push(b);
|
|
2790
|
+
continue;
|
|
2791
|
+
}
|
|
2792
|
+
const t = stripText(b.text);
|
|
2793
|
+
if (t.length === 0) continue;
|
|
2794
|
+
out.push(t === b.text ? b : {
|
|
2795
|
+
...b,
|
|
2796
|
+
text: t
|
|
2797
|
+
});
|
|
2798
|
+
}
|
|
2799
|
+
return out;
|
|
2800
|
+
}
|
|
2801
|
+
/**
|
|
2802
|
+
* Strip reminders from a single message. Returns the same reference
|
|
2803
|
+
* if nothing changed.
|
|
2804
|
+
*/
|
|
2805
|
+
function stripMessage(message) {
|
|
2806
|
+
if (typeof message.content === "string") {
|
|
2807
|
+
const next = stripText(message.content);
|
|
2808
|
+
if (next === message.content) return message;
|
|
2809
|
+
return {
|
|
2810
|
+
...message,
|
|
2811
|
+
content: next
|
|
2812
|
+
};
|
|
2813
|
+
}
|
|
2814
|
+
const next = stripBlocks(message.content);
|
|
2815
|
+
if (next === message.content) return message;
|
|
2816
|
+
return {
|
|
2817
|
+
...message,
|
|
2818
|
+
content: next
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
/**
|
|
2822
|
+
* Return a shallow-cloned payload with `<system-reminder>` blocks
|
|
2823
|
+
* removed from every message's text content. The input payload is
|
|
2824
|
+
* NOT mutated; if no reminders are present anywhere, the original
|
|
2825
|
+
* payload reference is returned unchanged (no allocation).
|
|
2826
|
+
*/
|
|
2827
|
+
function stripSystemReminders(payload) {
|
|
2828
|
+
let changed = false;
|
|
2829
|
+
const newMessages = payload.messages.map((m) => {
|
|
2830
|
+
const next = stripMessage(m);
|
|
2831
|
+
if (next !== m) changed = true;
|
|
2832
|
+
return next;
|
|
2833
|
+
});
|
|
2834
|
+
if (!changed) return payload;
|
|
2835
|
+
return {
|
|
2836
|
+
...payload,
|
|
2837
|
+
messages: newMessages
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
//#endregion
|
|
2763
2841
|
//#region src/routes/messages/count-tokens-handler.ts
|
|
2764
2842
|
/**
|
|
2765
2843
|
* Handles token counting for Anthropic messages.
|
|
@@ -2772,7 +2850,7 @@ async function handleCountTokens(c) {
|
|
|
2772
2850
|
try {
|
|
2773
2851
|
const anthropicBeta = c.req.header("anthropic-beta");
|
|
2774
2852
|
const anthropicPayload = await c.req.json();
|
|
2775
|
-
const openAIPayload = translateToOpenAI(anthropicPayload);
|
|
2853
|
+
const openAIPayload = translateToOpenAI(stripSystemReminders(anthropicPayload));
|
|
2776
2854
|
const translatedModelName = translateModelName(anthropicPayload.model);
|
|
2777
2855
|
const selectedModel = findModel(translatedModelName) ?? findModel(anthropicPayload.model);
|
|
2778
2856
|
if (!selectedModel) {
|
|
@@ -3086,7 +3164,7 @@ async function handleCompletion(c) {
|
|
|
3086
3164
|
messages_count: anthropicPayload.messages.length,
|
|
3087
3165
|
max_tokens: anthropicPayload.max_tokens
|
|
3088
3166
|
});
|
|
3089
|
-
const openAIPayload = translateToOpenAI(anthropicPayload);
|
|
3167
|
+
const openAIPayload = translateToOpenAI(stripSystemReminders(anthropicPayload));
|
|
3090
3168
|
if (state.manualApprove) await awaitApproval();
|
|
3091
3169
|
const response = await createChatCompletions(openAIPayload);
|
|
3092
3170
|
if (isNonStreaming(response)) return c.json(translateToAnthropic(response));
|