billion-context-pi 0.1.75-pr.493.309 → 0.1.75
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.md +0 -8
- package/README.zh-CN.md +0 -8
- package/dist/abort.d.ts +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/index.js +195 -12
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/strip-images.d.ts +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,14 +76,6 @@ pi install npm:billion-context-pi
|
|
|
76
76
|
|
|
77
77
|
That's it. The extension auto-loads on next Pi startup. No configuration needed — it reads your model's context window automatically.
|
|
78
78
|
|
|
79
|
-
**Prefer a stable channel?** Install with the `stable` dist-tag instead:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
pi install npm:billion-context-pi@stable
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Stable releases are cut explicitly (less often than regular releases). Stable installs auto-update to the newest *stable* release only — regular releases and dev prereleases never reach them. Plain installs track `latest`. Switch channels at any time by reinstalling with the other spec.
|
|
86
|
-
|
|
87
79
|
> **Using another sub-agent extension?** billion-context-pi ships its own `acp_delegate` sub-agent tool (see below) at a fraction of the context cost (~600 tok vs ~7K tok/turn). Two delegation tools in one session only make the model's choice noisier, so pick one:
|
|
88
80
|
> - **Use ACP's delegate** — remove the other extension: `pi remove npm:pi-subagents`
|
|
89
81
|
> - **Keep your own sub-agent** — turn ACP's delegate off in `acp.json`: `{ "delegate": false }` (see *Using your own sub-agent instead* below)
|
package/README.zh-CN.md
CHANGED
|
@@ -75,14 +75,6 @@ pi install npm:billion-context-pi
|
|
|
75
75
|
|
|
76
76
|
完成。扩展在下次 Pi 启动时自动加载。无需配置 —— 它会自动读取模型的上下文窗口。
|
|
77
77
|
|
|
78
|
-
**想用 stable 通道?** 改用 `stable` dist-tag 安装:
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
pi install npm:billion-context-pi@stable
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
stable 版本是显式指定发布的(频率低于常规发版)。stable 安装的自动更新只追最新的 *stable* 正式版 —— 常规正式版和 dev 预发布版都不会推给它们。普通安装跟踪 `latest`。随时可以用另一个 spec 重装来切换通道。
|
|
85
|
-
|
|
86
78
|
> **你另有子代理扩展?** billion-context-pi 自带 `acp_delegate` 子代理工具(见下文),上下文成本极低(~600 tok vs ~7K tok/轮)。同一会话里两套委派工具只会让模型的选择更混乱,二选一:
|
|
87
79
|
> - **用 ACP 的 delegate** —— 卸载另一个扩展:`pi remove npm:pi-subagents`
|
|
88
80
|
> - **保留你自己的子代理** —— 在 `acp.json` 里关掉 ACP 的 delegate:`{ "delegate": false }`(见下文*改用你自己的子代理*)
|
package/dist/abort.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function assertNotAborted(signal: AbortSignal | undefined): void;
|
package/dist/config.d.ts
CHANGED
|
@@ -152,6 +152,16 @@ export interface CompressSettings {
|
|
|
152
152
|
* overrides only; a pack's `toolPrompts` follow the base selection (tool
|
|
153
153
|
* definitions freeze at extension load, before the model is known). */
|
|
154
154
|
promptPack?: string;
|
|
155
|
+
/** Opt-in wire-level strip of historical image payloads (issue #321, kernel
|
|
156
|
+
* #215). Default: false (images ride along verbatim, current behavior).
|
|
157
|
+
* When true, every message older than `stripImagesKeepRecent` has its image
|
|
158
|
+
* parts dropped from the outbound provider body (image-only messages
|
|
159
|
+
* collapse to a "[image]" text placeholder). Host-side policy only — the
|
|
160
|
+
* strip primitive lives in acp-kernel's wire layer. */
|
|
161
|
+
stripImages?: boolean;
|
|
162
|
+
/** How many of the MOST RECENT messages keep their image payloads when
|
|
163
|
+
* `stripImages` is enabled. Default: 5. Ignored when stripImages is off. */
|
|
164
|
+
stripImagesKeepRecent?: number;
|
|
155
165
|
}
|
|
156
166
|
/** Per-provider compression overrides. Carries the same tuning fields as the
|
|
157
167
|
* global level, plus an optional per-model map keyed by model id. */
|
package/dist/index.js
CHANGED
|
@@ -5631,7 +5631,9 @@ function mergeCompress(global, provider, model) {
|
|
|
5631
5631
|
drop: model?.reasoning?.drop ?? provider?.reasoning?.drop ?? global?.reasoning?.drop,
|
|
5632
5632
|
threshold: model?.reasoning?.threshold ?? provider?.reasoning?.threshold ?? global?.reasoning?.threshold
|
|
5633
5633
|
},
|
|
5634
|
-
promptPack: model?.promptPack ?? provider?.promptPack ?? global?.promptPack
|
|
5634
|
+
promptPack: model?.promptPack ?? provider?.promptPack ?? global?.promptPack,
|
|
5635
|
+
stripImages: model?.stripImages ?? provider?.stripImages ?? global?.stripImages,
|
|
5636
|
+
stripImagesKeepRecent: model?.stripImagesKeepRecent ?? provider?.stripImagesKeepRecent ?? global?.stripImagesKeepRecent
|
|
5635
5637
|
};
|
|
5636
5638
|
}
|
|
5637
5639
|
function resolveCompress(compress, provider, modelId) {
|
|
@@ -7331,6 +7333,13 @@ function createRuntime(adapter) {
|
|
|
7331
7333
|
}
|
|
7332
7334
|
return gated;
|
|
7333
7335
|
}
|
|
7336
|
+
function stripImagesFor(ctx) {
|
|
7337
|
+
const m2 = ctx.model;
|
|
7338
|
+
const c = resolveCompress(adapterRef.compress, m2?.provider, m2?.id);
|
|
7339
|
+
const raw = Number(c.stripImagesKeepRecent);
|
|
7340
|
+
const keepRecent = Number.isFinite(raw) && raw >= 0 ? Math.floor(raw) : 5;
|
|
7341
|
+
return { enabled: c.stripImages === true, keepRecent };
|
|
7342
|
+
}
|
|
7334
7343
|
async function reloadConfig(cwd) {
|
|
7335
7344
|
let user;
|
|
7336
7345
|
try {
|
|
@@ -7434,7 +7443,7 @@ function createRuntime(adapter) {
|
|
|
7434
7443
|
return promptsRef;
|
|
7435
7444
|
}, setPrompts: (p) => {
|
|
7436
7445
|
promptsRef = p;
|
|
7437
|
-
}, markNudgeShown, nudgeShownFor, nudgeShownTokensFor, clearNudgeTracking, clearNudgeTokenStamps, noteCompressOutcomes, compressRetryCappedFor, clearCompressRetryTracking, liveContextLimit, configFor, reasoningDropFor, reloadConfig, stateFor, save, deriveChildState: deriveChild, acquireLock, overflowFor, overflowDrop, noteDeadCompress, clearDeadCompress, throttleFor, throttleDrop, noteTokenScale, dropTokenScale, noteHostUsage, dropHostUsageSamples, noteSizeDivergence, dropSizeDivergence, noteTerminalEscape, dropTerminalEscape, noteTruncationSkipped, dropTruncationSkipped };
|
|
7446
|
+
}, markNudgeShown, nudgeShownFor, nudgeShownTokensFor, clearNudgeTracking, clearNudgeTokenStamps, noteCompressOutcomes, compressRetryCappedFor, clearCompressRetryTracking, liveContextLimit, configFor, reasoningDropFor, reloadConfig, stateFor, save, deriveChildState: deriveChild, acquireLock, overflowFor, overflowDrop, noteDeadCompress, clearDeadCompress, throttleFor, throttleDrop, noteTokenScale, dropTokenScale, noteHostUsage, dropHostUsageSamples, noteSizeDivergence, dropSizeDivergence, noteTerminalEscape, dropTerminalEscape, noteTruncationSkipped, dropTruncationSkipped, stripImagesFor };
|
|
7438
7447
|
}
|
|
7439
7448
|
|
|
7440
7449
|
// node_modules/typebox/build/system/memory/memory.mjs
|
|
@@ -11888,6 +11897,14 @@ function adjustedTokenCount(core, messages, state, config, prelim, imageTokensBy
|
|
|
11888
11897
|
return view.drifted ? view.viewTokens : prelim;
|
|
11889
11898
|
}
|
|
11890
11899
|
|
|
11900
|
+
// src/abort.ts
|
|
11901
|
+
function assertNotAborted(signal) {
|
|
11902
|
+
if (!signal?.aborted) return;
|
|
11903
|
+
const err = new Error("Operation aborted");
|
|
11904
|
+
err.name = "AbortError";
|
|
11905
|
+
throw err;
|
|
11906
|
+
}
|
|
11907
|
+
|
|
11891
11908
|
// src/compat.ts
|
|
11892
11909
|
function normalizeSystemPrompt(input) {
|
|
11893
11910
|
if (input === void 0) return "";
|
|
@@ -11959,11 +11976,11 @@ function makeCompressTool(runtime, overrides) {
|
|
|
11959
11976
|
"Never compress content the current step is actively using."
|
|
11960
11977
|
],
|
|
11961
11978
|
parameters: CompressParams,
|
|
11962
|
-
async execute(toolCallId, params,
|
|
11979
|
+
async execute(toolCallId, params, signal, _onUpdate, ctx) {
|
|
11963
11980
|
if (runtime.refused) return { details: void 0, content: [{ type: "text", text: runtime.refusalMessage ?? UNSUPPORTED_HOST_MESSAGE }] };
|
|
11964
11981
|
let result;
|
|
11965
11982
|
try {
|
|
11966
|
-
result = await handleCompress(params, runtime, ctx, toolCallId);
|
|
11983
|
+
result = await handleCompress(params, runtime, ctx, toolCallId, signal);
|
|
11967
11984
|
} catch (e) {
|
|
11968
11985
|
logThrow("compress", e, { sid: ctx.sessionManager.getSessionId(), ranges: typeof params.content === "string" ? "string" : params.content?.length ?? 0 });
|
|
11969
11986
|
throw e;
|
|
@@ -12219,12 +12236,14 @@ function tierReadyHint(state, config) {
|
|
|
12219
12236
|
}
|
|
12220
12237
|
return "";
|
|
12221
12238
|
}
|
|
12222
|
-
async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
12239
|
+
async function handleCompress(args, runtime, ctx, toolCallId, signal) {
|
|
12240
|
+
assertNotAborted(signal);
|
|
12223
12241
|
const maybeRanges = normalizeRanges(args);
|
|
12224
12242
|
if (typeof maybeRanges === "string") throw new Error(maybeRanges);
|
|
12225
12243
|
const ranges = maybeRanges;
|
|
12226
12244
|
if (ranges.length === 0) return "No ranges provided.";
|
|
12227
12245
|
const { state: initialState, coreMessages, entries } = await runtime.stateFor(ctx);
|
|
12246
|
+
assertNotAborted(signal);
|
|
12228
12247
|
const config = runtime.configFor(ctx);
|
|
12229
12248
|
const modelId = ctx.model?.id ?? "default";
|
|
12230
12249
|
const systemPromptText = getSystemPromptText(ctx);
|
|
@@ -12281,6 +12300,7 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
|
|
|
12281
12300
|
state,
|
|
12282
12301
|
config
|
|
12283
12302
|
});
|
|
12303
|
+
assertNotAborted(signal);
|
|
12284
12304
|
const rewriteSpans = applied.result.blocksCreated > 0 ? tier3OnlyRewrite(applied.state.blocks.slice(-applied.result.blocksCreated), applied.state.blocks) : null;
|
|
12285
12305
|
if (rewriteSpans) {
|
|
12286
12306
|
await runtime.save(state, ctx);
|
|
@@ -12389,11 +12409,11 @@ function makeDecompressTool(runtime, overrides) {
|
|
|
12389
12409
|
"Use full:true to recurse through all nested tiers to original messages."
|
|
12390
12410
|
],
|
|
12391
12411
|
parameters: DecompressParams,
|
|
12392
|
-
async execute(_toolCallId, params,
|
|
12412
|
+
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
12393
12413
|
if (runtime.refused) return { details: void 0, content: [{ type: "text", text: runtime.refusalMessage ?? UNSUPPORTED_HOST_MESSAGE }] };
|
|
12394
12414
|
let result;
|
|
12395
12415
|
try {
|
|
12396
|
-
result = await handleDecompress(params, runtime, ctx);
|
|
12416
|
+
result = await handleDecompress(params, runtime, ctx, signal);
|
|
12397
12417
|
} catch (e) {
|
|
12398
12418
|
logThrow("decompress", e, { sid: ctx.sessionManager.getSessionId(), blockId: params.blockId });
|
|
12399
12419
|
throw e;
|
|
@@ -12506,8 +12526,10 @@ ${text}`;
|
|
|
12506
12526
|
headPreview(text)
|
|
12507
12527
|
].join("\n");
|
|
12508
12528
|
}
|
|
12509
|
-
async function handleDecompress(args, runtime, ctx) {
|
|
12529
|
+
async function handleDecompress(args, runtime, ctx, signal) {
|
|
12530
|
+
assertNotAborted(signal);
|
|
12510
12531
|
const { state, coreMessages } = await runtime.stateFor(ctx);
|
|
12532
|
+
assertNotAborted(signal);
|
|
12511
12533
|
const arg = (args.blockId ?? "").trim();
|
|
12512
12534
|
const owner = state.blocks.find((b2) => b2.effectiveMessageIds.includes(arg));
|
|
12513
12535
|
if (owner) {
|
|
@@ -12536,6 +12558,7 @@ ${text}`;
|
|
|
12536
12558
|
logError("decompress", { sid: ctx.sessionManager.getSessionId(), event: "block-path-rejected", blockId, toFile: args.toFile });
|
|
12537
12559
|
return targetPath.error;
|
|
12538
12560
|
}
|
|
12561
|
+
assertNotAborted(signal);
|
|
12539
12562
|
await mkdir(AUTO_DIR, { recursive: true }).catch(() => {
|
|
12540
12563
|
});
|
|
12541
12564
|
await writeFile(targetPath, text, "utf8");
|
|
@@ -19727,8 +19750,148 @@ function degenerationNotice(runs2) {
|
|
|
19727
19750
|
};
|
|
19728
19751
|
}
|
|
19729
19752
|
|
|
19730
|
-
//
|
|
19753
|
+
// node_modules/acp-kernel/dist/wire/index.js
|
|
19731
19754
|
import { createHash as createHash2 } from "crypto";
|
|
19755
|
+
function hashId(s) {
|
|
19756
|
+
return createHash2("sha256").update(s, "utf8").digest("hex").slice(0, 16);
|
|
19757
|
+
}
|
|
19758
|
+
function createSubagentNamespaces() {
|
|
19759
|
+
const anchors = /* @__PURE__ */ new Map();
|
|
19760
|
+
return {
|
|
19761
|
+
namespaceFor(identityValue, instructions) {
|
|
19762
|
+
if (typeof instructions !== "string" || instructions.trim().length === 0) return identityValue;
|
|
19763
|
+
const fp = hashId(instructions);
|
|
19764
|
+
const anchor = anchors.get(identityValue);
|
|
19765
|
+
if (anchor === void 0) {
|
|
19766
|
+
anchors.set(identityValue, fp);
|
|
19767
|
+
return identityValue;
|
|
19768
|
+
}
|
|
19769
|
+
return anchor === fp ? identityValue : `${identityValue}|sub:${fp}`;
|
|
19770
|
+
}
|
|
19771
|
+
};
|
|
19772
|
+
}
|
|
19773
|
+
var defaultNamespaces = createSubagentNamespaces();
|
|
19774
|
+
var IMAGE_PLACEHOLDER = "[image]";
|
|
19775
|
+
function isObj(v2) {
|
|
19776
|
+
return typeof v2 === "object" && v2 !== null;
|
|
19777
|
+
}
|
|
19778
|
+
function isImagePart(protocol, part) {
|
|
19779
|
+
if (!isObj(part)) return false;
|
|
19780
|
+
if (protocol === "responses") return part.type === "input_image";
|
|
19781
|
+
if (protocol === "openai") return part.type === "image_url";
|
|
19782
|
+
if (protocol === "google")
|
|
19783
|
+
return isObj(part.inlineData) || isObj(part.fileData);
|
|
19784
|
+
return part.type === "image";
|
|
19785
|
+
}
|
|
19786
|
+
function placeholderContent(protocol) {
|
|
19787
|
+
if (protocol === "google") return [{ text: IMAGE_PLACEHOLDER }];
|
|
19788
|
+
const type = protocol === "responses" ? "input_text" : "text";
|
|
19789
|
+
return [{ type, text: IMAGE_PLACEHOLDER }];
|
|
19790
|
+
}
|
|
19791
|
+
function stripHistoricalImages(body, protocol, keepRecent) {
|
|
19792
|
+
if (!protocol || !isObj(body)) return { body, removed: 0 };
|
|
19793
|
+
const recentCount = Math.max(0, Math.floor(keepRecent));
|
|
19794
|
+
if (protocol === "responses") {
|
|
19795
|
+
const input = body.input;
|
|
19796
|
+
if (!Array.isArray(input)) return { body, removed: 0 };
|
|
19797
|
+
const cutoff2 = input.length - recentCount;
|
|
19798
|
+
let removed2 = 0;
|
|
19799
|
+
let touched2 = false;
|
|
19800
|
+
const nextInput = input.map((item, i) => {
|
|
19801
|
+
if (i < cutoff2 && isObj(item) && Array.isArray(item.content)) {
|
|
19802
|
+
const content = item.content;
|
|
19803
|
+
const imgs = content.filter((p) => isImagePart("responses", p)).length;
|
|
19804
|
+
if (imgs > 0) {
|
|
19805
|
+
removed2 += imgs;
|
|
19806
|
+
touched2 = true;
|
|
19807
|
+
const kept = content.filter((p) => !isImagePart("responses", p));
|
|
19808
|
+
return {
|
|
19809
|
+
...item,
|
|
19810
|
+
content: kept.length > 0 ? kept : placeholderContent("responses")
|
|
19811
|
+
};
|
|
19812
|
+
}
|
|
19813
|
+
}
|
|
19814
|
+
return item;
|
|
19815
|
+
});
|
|
19816
|
+
if (!touched2) return { body, removed: 0 };
|
|
19817
|
+
return { body: { ...body, input: nextInput }, removed: removed2 };
|
|
19818
|
+
}
|
|
19819
|
+
if (protocol === "google") {
|
|
19820
|
+
const contents = body.contents;
|
|
19821
|
+
if (!Array.isArray(contents)) return { body, removed: 0 };
|
|
19822
|
+
const cutoff2 = contents.length - recentCount;
|
|
19823
|
+
let removed2 = 0;
|
|
19824
|
+
let touched2 = false;
|
|
19825
|
+
const nextContents = contents.map((c, i) => {
|
|
19826
|
+
if (i < cutoff2 && isObj(c) && Array.isArray(c.parts)) {
|
|
19827
|
+
const parts = c.parts;
|
|
19828
|
+
const imgs = parts.filter((p) => isImagePart("google", p)).length;
|
|
19829
|
+
if (imgs > 0) {
|
|
19830
|
+
removed2 += imgs;
|
|
19831
|
+
touched2 = true;
|
|
19832
|
+
const kept = parts.filter((p) => !isImagePart("google", p));
|
|
19833
|
+
return {
|
|
19834
|
+
...c,
|
|
19835
|
+
parts: kept.length > 0 ? kept : placeholderContent("google")
|
|
19836
|
+
};
|
|
19837
|
+
}
|
|
19838
|
+
}
|
|
19839
|
+
return c;
|
|
19840
|
+
});
|
|
19841
|
+
if (!touched2) return { body, removed: 0 };
|
|
19842
|
+
return { body: { ...body, contents: nextContents }, removed: removed2 };
|
|
19843
|
+
}
|
|
19844
|
+
const messages = body.messages;
|
|
19845
|
+
if (!Array.isArray(messages)) return { body, removed: 0 };
|
|
19846
|
+
const cutoff = messages.length - recentCount;
|
|
19847
|
+
let removed = 0;
|
|
19848
|
+
let touched = false;
|
|
19849
|
+
const nextMessages = messages.map((m2, i) => {
|
|
19850
|
+
if (i < cutoff && isObj(m2) && Array.isArray(m2.content)) {
|
|
19851
|
+
const content = m2.content;
|
|
19852
|
+
const imgs = content.filter((p) => isImagePart(protocol, p)).length;
|
|
19853
|
+
if (imgs > 0) {
|
|
19854
|
+
removed += imgs;
|
|
19855
|
+
touched = true;
|
|
19856
|
+
const kept = content.filter((p) => !isImagePart(protocol, p));
|
|
19857
|
+
return {
|
|
19858
|
+
...m2,
|
|
19859
|
+
content: kept.length > 0 ? kept : placeholderContent(protocol)
|
|
19860
|
+
};
|
|
19861
|
+
}
|
|
19862
|
+
}
|
|
19863
|
+
return m2;
|
|
19864
|
+
});
|
|
19865
|
+
if (!touched) return { body, removed: 0 };
|
|
19866
|
+
return { body: { ...body, messages: nextMessages }, removed };
|
|
19867
|
+
}
|
|
19868
|
+
|
|
19869
|
+
// src/strip-images.ts
|
|
19870
|
+
function apiToStripProtocol(api) {
|
|
19871
|
+
switch (api) {
|
|
19872
|
+
case "anthropic-messages":
|
|
19873
|
+
return "anthropic";
|
|
19874
|
+
case "openai-completions":
|
|
19875
|
+
return "openai";
|
|
19876
|
+
case "openai-responses":
|
|
19877
|
+
case "azure-openai-responses":
|
|
19878
|
+
case "openai-codex-responses":
|
|
19879
|
+
return "responses";
|
|
19880
|
+
default:
|
|
19881
|
+
return null;
|
|
19882
|
+
}
|
|
19883
|
+
}
|
|
19884
|
+
function applyStripImages(body, api, settings2) {
|
|
19885
|
+
if (!settings2.enabled) return { removed: 0 };
|
|
19886
|
+
const protocol = apiToStripProtocol(api);
|
|
19887
|
+
if (!protocol) return { removed: 0 };
|
|
19888
|
+
const result = stripHistoricalImages(body, protocol, settings2.keepRecent);
|
|
19889
|
+
if (result.removed === 0) return { removed: 0 };
|
|
19890
|
+
return { body: result.body, removed: result.removed };
|
|
19891
|
+
}
|
|
19892
|
+
|
|
19893
|
+
// src/tool-guardrails.ts
|
|
19894
|
+
import { createHash as createHash3 } from "crypto";
|
|
19732
19895
|
function isBashToolResult(e) {
|
|
19733
19896
|
return e.toolName === "bash";
|
|
19734
19897
|
}
|
|
@@ -19829,7 +19992,7 @@ function canonicalStringify(value) {
|
|
|
19829
19992
|
function repetitionFingerprint(toolName, input) {
|
|
19830
19993
|
const payload = `${toolName}\0${canonicalStringify(input ?? {})}`;
|
|
19831
19994
|
try {
|
|
19832
|
-
return
|
|
19995
|
+
return createHash3("sha1").update(payload).digest("hex");
|
|
19833
19996
|
} catch {
|
|
19834
19997
|
return `unhashable:${toolName}`;
|
|
19835
19998
|
}
|
|
@@ -19942,13 +20105,13 @@ import { join as join15, dirname as dirname10 } from "path";
|
|
|
19942
20105
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
19943
20106
|
import { execFile } from "child_process";
|
|
19944
20107
|
import { homedir as homedir9 } from "os";
|
|
19945
|
-
import { createHash as
|
|
20108
|
+
import { createHash as createHash4 } from "crypto";
|
|
19946
20109
|
var PACKAGE_NAME = "billion-context-pi";
|
|
19947
20110
|
var registryUrl = (tag) => `https://registry.npmjs.org/${PACKAGE_NAME}/${encodeURIComponent(tag)}`;
|
|
19948
20111
|
var SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/;
|
|
19949
20112
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
19950
20113
|
function locationKey(location) {
|
|
19951
|
-
return
|
|
20114
|
+
return createHash4("sha256").update(location).digest("hex").slice(0, 12);
|
|
19952
20115
|
}
|
|
19953
20116
|
var throttleFileFor = (extDir) => {
|
|
19954
20117
|
if (process.env.ACP_UPDATE_THROTTLE_FILE) return process.env.ACP_UPDATE_THROTTLE_FILE;
|
|
@@ -20364,6 +20527,7 @@ function createAcpExtension(adapter = {}) {
|
|
|
20364
20527
|
wireDelegateReadTracking(pi);
|
|
20365
20528
|
wireSessionLifecycle(pi, runtime, standDownIfProxied);
|
|
20366
20529
|
wireContextTransform(pi, runtime, standDownIfProxied);
|
|
20530
|
+
wireBeforeProviderRequest(pi, runtime, standDownIfProxied);
|
|
20367
20531
|
wireSystemPrompt(pi, runtime);
|
|
20368
20532
|
wireToolGuardrails(pi, runtime);
|
|
20369
20533
|
wireOverflowSelfHeal(pi, runtime);
|
|
@@ -20533,6 +20697,25 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
|
|
|
20533
20697
|
});
|
|
20534
20698
|
}
|
|
20535
20699
|
var lastDegNoticeKey = null;
|
|
20700
|
+
function wireBeforeProviderRequest(pi, runtime, standDownIfProxied) {
|
|
20701
|
+
pi.on("before_provider_request", async (event, ctx) => {
|
|
20702
|
+
if (runtime.refused) return;
|
|
20703
|
+
if (standDownIfProxied(ctx)) return;
|
|
20704
|
+
const settings2 = runtime.stripImagesFor(ctx);
|
|
20705
|
+
if (!settings2.enabled) return;
|
|
20706
|
+
const outcome = applyStripImages(event.payload, ctx.model?.api, settings2);
|
|
20707
|
+
if (outcome.removed > 0) {
|
|
20708
|
+
logInfo("strip-images", {
|
|
20709
|
+
sid: ctx.sessionManager.getSessionId(),
|
|
20710
|
+
event: "stripped",
|
|
20711
|
+
removed: outcome.removed,
|
|
20712
|
+
keepRecent: settings2.keepRecent
|
|
20713
|
+
});
|
|
20714
|
+
return outcome.body;
|
|
20715
|
+
}
|
|
20716
|
+
return;
|
|
20717
|
+
});
|
|
20718
|
+
}
|
|
20536
20719
|
function wireContextTransform(pi, runtime, standDownIfProxied) {
|
|
20537
20720
|
pi.on("context", async (event, ctx) => {
|
|
20538
20721
|
if (runtime.refused) return;
|