oira666_pi-limits-wait 0.4.14 → 0.4.15
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/package.json +1 -1
- package/src/constants.ts +7 -0
- package/src/index.ts +12 -1
- package/src/prompt.ts +60 -1
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -10,6 +10,13 @@ export const PI_REMOVAL_ANCHORS = [
|
|
|
10
10
|
export const PI_IDENTITY_SENTENCE_PATTERN =
|
|
11
11
|
/(?:^|\n)\s*You are pi\b[^.!?\n]*(?:[.!?](?=\s|$)|(?=\n|$))/gi;
|
|
12
12
|
|
|
13
|
+
// Strips the host-harness identity clause pi prepends to its system prompt, e.g.
|
|
14
|
+
// "You are an expert coding assistant operating inside pi, a coding agent harness."
|
|
15
|
+
// The Claude Code identity block already establishes who the assistant is, so
|
|
16
|
+
// leaving this clause in tells the model (and Anthropic) it is running inside pi.
|
|
17
|
+
export const PI_HARNESS_IDENTITY_PATTERN =
|
|
18
|
+
/\s+operating inside pi,\s*a coding agent harness/gi;
|
|
19
|
+
|
|
13
20
|
export const CLAUDE_CODE_IDENTITY_PATTERN =
|
|
14
21
|
/(?:^|\n)\s*You are Claude Code, Anthropic's official CLI for Claude\.\s*/gi;
|
|
15
22
|
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { isInternalSyntheticModel } from "./models.js";
|
|
3
|
+
import { sanitiseAnthropicPayloadSystem } from "./prompt.js";
|
|
3
4
|
import { loadFallbackSettings } from "./settings.js";
|
|
4
5
|
import { state } from "./state.js";
|
|
5
6
|
import { registerWrappedApi } from "./stream.js";
|
|
6
7
|
|
|
7
|
-
export { sanitiseSystemPrompt } from "./prompt.js";
|
|
8
|
+
export { sanitiseAnthropicPayloadSystem, sanitiseSystemPrompt } from "./prompt.js";
|
|
8
9
|
export {
|
|
9
10
|
getRetryableError,
|
|
10
11
|
isAuthenticationRefreshError,
|
|
@@ -39,6 +40,16 @@ function registerContextApis(pi: ExtensionAPI, ctx: ExtensionContext): void {
|
|
|
39
40
|
export default function (pi: ExtensionAPI) {
|
|
40
41
|
state.extensionApi = pi;
|
|
41
42
|
|
|
43
|
+
// Anthropic now rejects Claude Pro/Max (OAuth) requests whose system prompt
|
|
44
|
+
// still carries the host agent's fingerprints (pi-coding-agent paths, "You
|
|
45
|
+
// are pi", etc.). pi-ai prepends the Claude Code identity block for OAuth
|
|
46
|
+
// tokens but passes the host system prompt through as a second block, which
|
|
47
|
+
// trips the check. Sanitise that block on the outbound payload right before
|
|
48
|
+
// it is sent. This hook fires for every provider request and only mutates
|
|
49
|
+
// Anthropic OAuth payloads (identified by the Claude Code identity block), so
|
|
50
|
+
// API-key Anthropic calls and non-Anthropic providers are untouched.
|
|
51
|
+
pi.on("before_provider_request", (event) => sanitiseAnthropicPayloadSystem(event.payload));
|
|
52
|
+
|
|
42
53
|
pi.on("model_select", (event) => {
|
|
43
54
|
if (state.suppressNextModelSelect) {
|
|
44
55
|
state.suppressNextModelSelect = false;
|
package/src/prompt.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import type { Api, Context, Model, SimpleStreamOptions } from "@mariozechner/pi-ai";
|
|
3
|
-
import { CLAUDE_CODE_IDENTITY, CLAUDE_CODE_IDENTITY_PATTERN, PI_IDENTITY_SENTENCE_PATTERN, PI_REMOVAL_ANCHORS } from "./constants.js";
|
|
3
|
+
import { CLAUDE_CODE_IDENTITY, CLAUDE_CODE_IDENTITY_PATTERN, PI_HARNESS_IDENTITY_PATTERN, PI_IDENTITY_SENTENCE_PATTERN, PI_REMOVAL_ANCHORS } from "./constants.js";
|
|
4
4
|
import { state } from "./state.js";
|
|
5
5
|
|
|
6
6
|
export function sanitiseSystemPrompt(raw: string): string {
|
|
@@ -13,6 +13,7 @@ export function sanitiseSystemPrompt(raw: string): string {
|
|
|
13
13
|
.join("\n\n")
|
|
14
14
|
.replace(CLAUDE_CODE_IDENTITY_PATTERN, "")
|
|
15
15
|
.replace(PI_IDENTITY_SENTENCE_PATTERN, "")
|
|
16
|
+
.replace(PI_HARNESS_IDENTITY_PATTERN, "")
|
|
16
17
|
.replace(/\n{3,}/g, "\n\n")
|
|
17
18
|
.trim();
|
|
18
19
|
}
|
|
@@ -87,3 +88,61 @@ export function anthropicSubscriptionContext(
|
|
|
87
88
|
: CLAUDE_CODE_IDENTITY,
|
|
88
89
|
};
|
|
89
90
|
}
|
|
91
|
+
|
|
92
|
+
interface SystemTextBlock {
|
|
93
|
+
type: string;
|
|
94
|
+
text?: unknown;
|
|
95
|
+
[key: string]: unknown;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isClaudeCodeIdentityBlock(block: unknown): block is SystemTextBlock {
|
|
99
|
+
if (!block || typeof block !== "object") return false;
|
|
100
|
+
const b = block as SystemTextBlock;
|
|
101
|
+
return b.type === "text" && typeof b.text === "string" && b.text.includes(CLAUDE_CODE_IDENTITY);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Sanitise the `system` blocks of an Anthropic provider request payload.
|
|
106
|
+
*
|
|
107
|
+
* Anthropic now rejects Claude Pro/Max (OAuth) requests whose system prompt
|
|
108
|
+
* still carries third-party-agent fingerprints (e.g. pi-coding-agent paths or
|
|
109
|
+
* "You are pi" identity). pi-ai already prepends the Claude Code identity as
|
|
110
|
+
* the first `system` block for OAuth tokens, but passes the host agent's full
|
|
111
|
+
* system prompt through as a second block unchanged, which trips the check.
|
|
112
|
+
*
|
|
113
|
+
* This runs from the `before_provider_request` extension hook, which fires for
|
|
114
|
+
* every provider request and whose return value replaces the outbound payload.
|
|
115
|
+
* It only touches payloads that already carry the Claude Code identity block
|
|
116
|
+
* (i.e. Anthropic OAuth requests), so API-key Anthropic calls and non-Anthropic
|
|
117
|
+
* providers are left untouched. Each remaining text block is run through
|
|
118
|
+
* `sanitiseSystemPrompt`; blocks that become empty are dropped.
|
|
119
|
+
*/
|
|
120
|
+
export function sanitiseAnthropicPayloadSystem(payload: unknown): unknown {
|
|
121
|
+
if (!payload || typeof payload !== "object") return payload;
|
|
122
|
+
const system = (payload as { system?: unknown }).system;
|
|
123
|
+
if (!Array.isArray(system)) return payload;
|
|
124
|
+
|
|
125
|
+
const identityIndex = system.findIndex(isClaudeCodeIdentityBlock);
|
|
126
|
+
if (identityIndex === -1) return payload;
|
|
127
|
+
|
|
128
|
+
const newSystem: unknown[] = [];
|
|
129
|
+
for (let i = 0; i < system.length; i++) {
|
|
130
|
+
const block = system[i];
|
|
131
|
+
if (i === identityIndex) {
|
|
132
|
+
newSystem.push(block);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (
|
|
136
|
+
block && typeof block === "object"
|
|
137
|
+
&& (block as SystemTextBlock).type === "text"
|
|
138
|
+
&& typeof (block as SystemTextBlock).text === "string"
|
|
139
|
+
) {
|
|
140
|
+
const sanitised = sanitiseSystemPrompt((block as SystemTextBlock).text as string);
|
|
141
|
+
if (sanitised) newSystem.push({ ...block, text: sanitised });
|
|
142
|
+
} else {
|
|
143
|
+
newSystem.push(block);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return { ...payload, system: newSystem };
|
|
148
|
+
}
|