@askalf/dario 4.8.123 → 4.8.125
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/cc-template.js +23 -2
- package/dist/model-catalog.js +28 -13
- package/dist/scrub-template.js +14 -3
- package/package.json +1 -1
package/dist/cc-template.js
CHANGED
|
@@ -148,14 +148,35 @@ export const CC_AGENT_IDENTITY = TEMPLATE.agent_identity;
|
|
|
148
148
|
export const CLIENT_SYSTEM_PREFACE = '\n\n---\n\nIMPORTANT: The operator of this session has supplied the following ' +
|
|
149
149
|
'task-specific instructions. For this conversation they OVERRIDE any ' +
|
|
150
150
|
'conflicting general behavior described above. Follow them exactly:\n\n';
|
|
151
|
+
// Memoize the stripped prompt by (base, level) (#642-audit): resolveSystemPrompt
|
|
152
|
+
// runs per request and stripBehavioralConstraints does ~12 regex passes over the
|
|
153
|
+
// ~25KB prompt. Keyed on the base STRING so a runtime template re-capture (a new
|
|
154
|
+
// base) correctly misses and re-strips. Bounded to a few bases; cleared if it
|
|
155
|
+
// somehow grows past a small cap.
|
|
156
|
+
const _stripCache = new Map();
|
|
157
|
+
function stripBehavioralConstraintsMemo(base, level) {
|
|
158
|
+
if (_stripCache.size > 8)
|
|
159
|
+
_stripCache.clear();
|
|
160
|
+
let byLevel = _stripCache.get(base);
|
|
161
|
+
if (!byLevel) {
|
|
162
|
+
byLevel = new Map();
|
|
163
|
+
_stripCache.set(base, byLevel);
|
|
164
|
+
}
|
|
165
|
+
let v = byLevel.get(level);
|
|
166
|
+
if (v === undefined) {
|
|
167
|
+
v = stripBehavioralConstraints(base, level);
|
|
168
|
+
byLevel.set(level, v);
|
|
169
|
+
}
|
|
170
|
+
return v;
|
|
171
|
+
}
|
|
151
172
|
export function resolveSystemPrompt(arg, model) {
|
|
152
173
|
const base = systemPromptForModel(model);
|
|
153
174
|
if (!arg || arg === 'verbatim')
|
|
154
175
|
return base;
|
|
155
176
|
if (arg === 'partial')
|
|
156
|
-
return
|
|
177
|
+
return stripBehavioralConstraintsMemo(base, 'partial');
|
|
157
178
|
if (arg === 'aggressive')
|
|
158
|
-
return
|
|
179
|
+
return stripBehavioralConstraintsMemo(base, 'aggressive');
|
|
159
180
|
return arg;
|
|
160
181
|
}
|
|
161
182
|
/**
|
package/dist/model-catalog.js
CHANGED
|
@@ -220,22 +220,37 @@ function envInt(name, dflt) {
|
|
|
220
220
|
}
|
|
221
221
|
async function fetchUpstreamBases(deps) {
|
|
222
222
|
const f = deps.fetchImpl ?? fetch;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (deps.upstreamApiKey) {
|
|
228
|
-
headers['x-api-key'] = deps.upstreamApiKey;
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
if (!deps.getToken)
|
|
232
|
-
throw new Error('no token source for catalog fetch');
|
|
233
|
-
headers['authorization'] = `Bearer ${await deps.getToken()}`;
|
|
234
|
-
headers['anthropic-beta'] = OAUTH_BETA;
|
|
235
|
-
}
|
|
223
|
+
// Arm the timeout FIRST so it bounds token acquisition too, not just the
|
|
224
|
+
// fetch (#642-audit): a hung getToken() (e.g. a stuck single-account OAuth
|
|
225
|
+
// refresh) would otherwise never settle, leaving the catalog `inflight` guard
|
|
226
|
+
// non-null forever and wedging every future refresh on the baked list.
|
|
236
227
|
const ctl = new AbortController();
|
|
237
228
|
const timer = setTimeout(() => ctl.abort(), deps.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS);
|
|
238
229
|
try {
|
|
230
|
+
const headers = {
|
|
231
|
+
accept: 'application/json',
|
|
232
|
+
'anthropic-version': ANTHROPIC_VERSION,
|
|
233
|
+
};
|
|
234
|
+
if (deps.upstreamApiKey) {
|
|
235
|
+
headers['x-api-key'] = deps.upstreamApiKey;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
if (!deps.getToken)
|
|
239
|
+
throw new Error('no token source for catalog fetch');
|
|
240
|
+
// Race token acquisition against the same abort deadline as the fetch.
|
|
241
|
+
const token = await Promise.race([
|
|
242
|
+
deps.getToken(),
|
|
243
|
+
new Promise((_, reject) => {
|
|
244
|
+
const onAbort = () => reject(new Error('catalog token acquisition timed out'));
|
|
245
|
+
if (ctl.signal.aborted)
|
|
246
|
+
onAbort();
|
|
247
|
+
else
|
|
248
|
+
ctl.signal.addEventListener('abort', onAbort, { once: true });
|
|
249
|
+
}),
|
|
250
|
+
]);
|
|
251
|
+
headers['authorization'] = `Bearer ${token}`;
|
|
252
|
+
headers['anthropic-beta'] = OAUTH_BETA;
|
|
253
|
+
}
|
|
239
254
|
const res = await f(`${ANTHROPIC_API}/v1/models?limit=100`, { headers, signal: ctl.signal });
|
|
240
255
|
if (!res.ok)
|
|
241
256
|
throw new Error(`upstream /v1/models ${res.status}`);
|
package/dist/scrub-template.js
CHANGED
|
@@ -141,7 +141,7 @@ function removeHostContextSections(systemPrompt) {
|
|
|
141
141
|
* drift signals and leaks the bake host's repo state.
|
|
142
142
|
*/
|
|
143
143
|
function removeGitStatusBlock(systemPrompt) {
|
|
144
|
-
return systemPrompt.replace(/\ngitStatus:[\s\S]*?(?=\n# |$)/, '');
|
|
144
|
+
return systemPrompt.replace(/\r?\ngitStatus:[\s\S]*?(?=\r?\n# |$)/, '');
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
147
|
* Strip one named top-level section (`\n# <name>\n` through the next
|
|
@@ -150,7 +150,9 @@ function removeGitStatusBlock(systemPrompt) {
|
|
|
150
150
|
*/
|
|
151
151
|
function removeSection(systemPrompt, name) {
|
|
152
152
|
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
153
|
-
|
|
153
|
+
// \r?\n tolerates a CRLF capture; [ \t]* tolerates trailing whitespace on the
|
|
154
|
+
// heading line — either would otherwise leave a host-context section unstripped.
|
|
155
|
+
const heading = new RegExp(`\\r?\\n# ${escaped}[ \\t]*\\r?\\n`);
|
|
154
156
|
let out = systemPrompt;
|
|
155
157
|
while (true) {
|
|
156
158
|
const m = heading.exec(out);
|
|
@@ -158,7 +160,7 @@ function removeSection(systemPrompt, name) {
|
|
|
158
160
|
return out;
|
|
159
161
|
const sectionStart = m.index;
|
|
160
162
|
const afterHeading = out.slice(sectionStart + m[0].length);
|
|
161
|
-
const nextHeading = /\n# /.exec(afterHeading);
|
|
163
|
+
const nextHeading = /\r?\n# /.exec(afterHeading);
|
|
162
164
|
const sectionEnd = nextHeading
|
|
163
165
|
? sectionStart + m[0].length + nextHeading.index
|
|
164
166
|
: out.length;
|
|
@@ -203,5 +205,14 @@ export function findUserPathHits(text) {
|
|
|
203
205
|
if (matches)
|
|
204
206
|
hits.push(...matches);
|
|
205
207
|
}
|
|
208
|
+
// A host-context section still present here means removeSection failed to
|
|
209
|
+
// strip it (e.g. a CRLF capture or a renamed heading). Flag it so the drift-
|
|
210
|
+
// gate fails the release rather than shipping the leak (#642-audit).
|
|
211
|
+
for (const name of HOST_CONTEXT_SECTION_HEADINGS) {
|
|
212
|
+
const esc = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
213
|
+
if (new RegExp(`\\r?\\n# ${esc}[ \\t]*\\r?\\n`).test(text)) {
|
|
214
|
+
hits.push(`# ${name} (host-context section not stripped)`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
206
217
|
return hits;
|
|
207
218
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.125",
|
|
4
4
|
"description": "Use your Claude Pro/Max subscription in any tool — Cursor, Cline, Aider, the Agent SDK, your scripts — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|