billion-context-omp 0.2.9 → 0.3.1
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/compress-tool.d.ts +1 -0
- package/dist/index.js +323 -111
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +4 -0
- package/dist/transform-mode.d.ts +15 -0
- package/dist/update.d.ts +19 -0
- package/dist/wire-fold.d.ts +7 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -574,7 +574,7 @@ function truncateLargeToolOutputs(messages, tokenCount, config, countTokens, opt
|
|
|
574
574
|
);
|
|
575
575
|
return { messages: updated, truncatedCount, savedTokens };
|
|
576
576
|
}
|
|
577
|
-
var KEEP_LAST_ORPHANED =
|
|
577
|
+
var KEEP_LAST_ORPHANED = 2;
|
|
578
578
|
function rangeKey(startRef, endRef) {
|
|
579
579
|
return `${startRef}::${endRef}`;
|
|
580
580
|
}
|
|
@@ -3005,6 +3005,27 @@ function resolveTransformMode(adapter, model, hostVersion = VERSION) {
|
|
|
3005
3005
|
if (api === "openai-completions" && hostVersionAtLeast(OPENAI_COMPLETIONS_VIABLE_FROM, hostVersion)) return "provider";
|
|
3006
3006
|
return "context";
|
|
3007
3007
|
}
|
|
3008
|
+
function providerDeliveryWarning(adapter, model, hostVersion = VERSION) {
|
|
3009
|
+
if (adapter.transformMode !== "provider") return void 0;
|
|
3010
|
+
const api = model?.api;
|
|
3011
|
+
const dropWarning = (target) => ({
|
|
3012
|
+
key: `drop:${target}`,
|
|
3013
|
+
reason: `host < 17.3.8 drops the before_provider_request replacement on ${target} (fixed upstream pi-ai 17.3.8, can1357/oh-my-pi#8717)`,
|
|
3014
|
+
message: `\u26A0 billion-context-omp: transformMode "provider" is set, but this host (pi-ai < 17.3.8) discards the rewritten payload on ${target} \u2014 compression is NOT applied. Upgrade the host (omp update) or remove the transformMode override.`
|
|
3015
|
+
});
|
|
3016
|
+
if (api === "openai-completions" && !hostVersionAtLeast(OPENAI_COMPLETIONS_VIABLE_FROM, hostVersion)) {
|
|
3017
|
+
return dropWarning(api);
|
|
3018
|
+
}
|
|
3019
|
+
if (api === "amazon-bedrock" || api === "cursor") {
|
|
3020
|
+
if (!hostVersionAtLeast(OPENAI_COMPLETIONS_VIABLE_FROM, hostVersion)) return dropWarning(api);
|
|
3021
|
+
return {
|
|
3022
|
+
key: `nocodec:${api}`,
|
|
3023
|
+
reason: `${api} honors the replacement from 17.3.8 but its wire body has no codec path yet (issue #83)`,
|
|
3024
|
+
message: `\u26A0 billion-context-omp: transformMode "provider" is set, but the ${api} wire body has no codec path yet (#83) \u2014 compression is NOT applied. Remove the transformMode override to use context mode.`
|
|
3025
|
+
};
|
|
3026
|
+
}
|
|
3027
|
+
return void 0;
|
|
3028
|
+
}
|
|
3008
3029
|
|
|
3009
3030
|
// node_modules/acp-kernel/dist/wire/index.js
|
|
3010
3031
|
import { createHash } from "crypto";
|
|
@@ -3817,6 +3838,13 @@ function unrepresentableOpenaiMessage(message) {
|
|
|
3817
3838
|
if (typeof role !== "string" || !OPENAI_CODEC_ROLES.has(role)) {
|
|
3818
3839
|
return `openai role ${JSON.stringify(role) ?? "missing"}`;
|
|
3819
3840
|
}
|
|
3841
|
+
for (const field of ["function_call", "audio", "annotations"]) {
|
|
3842
|
+
if (message[field] !== void 0) {
|
|
3843
|
+
return `openai ${field} field is dropped by the rebuild`;
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
const refusal = message.refusal;
|
|
3847
|
+
if (refusal !== null && refusal !== void 0) return "openai refusal content is dropped by the rebuild";
|
|
3820
3848
|
const content = message.content;
|
|
3821
3849
|
if (content == null || typeof content === "string") return null;
|
|
3822
3850
|
if (!Array.isArray(content)) return "content neither string nor part array";
|
|
@@ -3833,6 +3861,39 @@ function unrepresentableOpenaiMessage(message) {
|
|
|
3833
3861
|
}
|
|
3834
3862
|
return null;
|
|
3835
3863
|
}
|
|
3864
|
+
function restoreOpenaiWireFidelity(originalMessages, rebuilt) {
|
|
3865
|
+
const detailsByCall = /* @__PURE__ */ new Map();
|
|
3866
|
+
for (const message of originalMessages) {
|
|
3867
|
+
if (message === null || typeof message !== "object") continue;
|
|
3868
|
+
const calls = message.tool_calls;
|
|
3869
|
+
const details = message.reasoning_details;
|
|
3870
|
+
if (!Array.isArray(calls) || !Array.isArray(details) || details.length === 0) continue;
|
|
3871
|
+
for (const call of calls) {
|
|
3872
|
+
const id = call?.id;
|
|
3873
|
+
if (typeof id === "string" && !detailsByCall.has(id)) detailsByCall.set(id, details);
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
return rebuilt.map((message) => {
|
|
3877
|
+
if (message === null || typeof message !== "object") return message;
|
|
3878
|
+
const m = message;
|
|
3879
|
+
if (m.role !== "assistant") return message;
|
|
3880
|
+
const calls = Array.isArray(m.tool_calls) ? m.tool_calls : [];
|
|
3881
|
+
const attached = [];
|
|
3882
|
+
for (const call of calls) {
|
|
3883
|
+
const id = call?.id;
|
|
3884
|
+
if (typeof id !== "string") continue;
|
|
3885
|
+
const d = detailsByCall.get(id);
|
|
3886
|
+
if (d) attached.push(...d);
|
|
3887
|
+
}
|
|
3888
|
+
const hasReasoningField = m.reasoning_content !== void 0 || m.reasoning !== void 0 || m.reasoning_text !== void 0;
|
|
3889
|
+
const emptyContent = m.content === null && (calls.length > 0 || hasReasoningField);
|
|
3890
|
+
if (attached.length === 0 && !emptyContent) return message;
|
|
3891
|
+
const out = { ...m };
|
|
3892
|
+
if (emptyContent) out.content = "";
|
|
3893
|
+
if (attached.length > 0) out.reasoning_details = attached;
|
|
3894
|
+
return out;
|
|
3895
|
+
});
|
|
3896
|
+
}
|
|
3836
3897
|
var renderRefsAll = createRenderRefsNode("all");
|
|
3837
3898
|
function applyWireTagContract(msgs, state, scope) {
|
|
3838
3899
|
const stripAssistantTags = (m) => m.contentType === "text" && m.role === "assistant" ? { ...m, text: stripRefTag(m.text ?? "") } : m;
|
|
@@ -3991,22 +4052,23 @@ function viewToCoreStream(view, systemText) {
|
|
|
3991
4052
|
if (text) messages.push({ role: "user", content: text });
|
|
3992
4053
|
} else if (m.role === "assistant") {
|
|
3993
4054
|
const blocks = Array.isArray(m.content) ? m.content : [];
|
|
3994
|
-
const
|
|
3995
|
-
|
|
3996
|
-
);
|
|
4055
|
+
const typed = blocks;
|
|
4056
|
+
const calls = typed.filter((b) => b !== null && typeof b === "object" && b.type === "toolCall");
|
|
4057
|
+
const reasoning = typed.filter((b) => b !== null && typeof b === "object" && b.type === "thinking" && typeof b.thinking === "string" && b.thinking.trim().length > 0).map((b) => b.thinking).join("\n");
|
|
3997
4058
|
const text = extractViewText(m.content);
|
|
3998
4059
|
if (calls.length > 0) {
|
|
3999
4060
|
messages.push({
|
|
4000
4061
|
role: "assistant",
|
|
4001
4062
|
content: text,
|
|
4063
|
+
...reasoning ? { reasoning_content: reasoning } : {},
|
|
4002
4064
|
tool_calls: calls.map((c) => ({
|
|
4003
4065
|
id: c.id,
|
|
4004
4066
|
type: "function",
|
|
4005
4067
|
function: { name: c.name ?? "", arguments: JSON.stringify(c.arguments ?? {}) }
|
|
4006
4068
|
}))
|
|
4007
4069
|
});
|
|
4008
|
-
} else if (text) {
|
|
4009
|
-
messages.push({ role: "assistant", content: text });
|
|
4070
|
+
} else if (text || reasoning) {
|
|
4071
|
+
messages.push({ role: "assistant", content: text, ...reasoning ? { reasoning_content: reasoning } : {} });
|
|
4010
4072
|
}
|
|
4011
4073
|
} else if (m.role === "toolResult") {
|
|
4012
4074
|
messages.push({ role: "tool", tool_call_id: m.toolCallId ?? "", content: extractViewText(m.content) });
|
|
@@ -4027,20 +4089,27 @@ function viewToAnthropicCore(view) {
|
|
|
4027
4089
|
if (text) messages.push({ role: "user", content: [{ type: "text", text }] });
|
|
4028
4090
|
} else if (m.role === "assistant") {
|
|
4029
4091
|
const blocks = Array.isArray(m.content) ? m.content : [];
|
|
4030
|
-
const
|
|
4031
|
-
(b) => b !== null && typeof b === "object" && b.type === "toolCall"
|
|
4032
|
-
);
|
|
4033
|
-
const text = extractViewText(m.content);
|
|
4092
|
+
const typed = blocks;
|
|
4034
4093
|
const content = [];
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4094
|
+
for (const b of typed) {
|
|
4095
|
+
if (b === null || typeof b !== "object") continue;
|
|
4096
|
+
if (b.type === "thinking" && typeof b.thinking === "string" && b.thinking.trim().length > 0) {
|
|
4097
|
+
content.push({
|
|
4098
|
+
type: "thinking",
|
|
4099
|
+
thinking: b.thinking,
|
|
4100
|
+
...typeof b.thinkingSignature === "string" && b.thinkingSignature ? { signature: b.thinkingSignature } : {}
|
|
4101
|
+
});
|
|
4102
|
+
} else if (b.type === "text" && typeof b.text === "string" && stripRefTag(b.text).trim().length > 0) {
|
|
4103
|
+
content.push({ type: "text", text: stripRefTag(b.text) });
|
|
4104
|
+
} else if (b.type === "toolCall") {
|
|
4105
|
+
let input = {};
|
|
4106
|
+
try {
|
|
4107
|
+
input = b.arguments && typeof b.arguments === "object" ? b.arguments : JSON.parse(JSON.stringify(b.arguments ?? {}));
|
|
4108
|
+
} catch {
|
|
4109
|
+
input = {};
|
|
4110
|
+
}
|
|
4111
|
+
content.push({ type: "tool_use", id: b.id, name: b.name ?? "", input });
|
|
4042
4112
|
}
|
|
4043
|
-
content.push({ type: "tool_use", id: c.id, name: c.name ?? "", input });
|
|
4044
4113
|
}
|
|
4045
4114
|
if (content.length > 0) messages.push({ role: "assistant", content });
|
|
4046
4115
|
} else if (m.role === "toolResult") {
|
|
@@ -4353,6 +4422,9 @@ ${acp}`);
|
|
|
4353
4422
|
slot.rejectStreak = ok ? 0 : slot.rejectStreak + 1;
|
|
4354
4423
|
return slot.rejectStreak;
|
|
4355
4424
|
}
|
|
4425
|
+
function rejectStreakFor(ctx) {
|
|
4426
|
+
return slotForMode(ctx, sidOf(ctx)).rejectStreak;
|
|
4427
|
+
}
|
|
4356
4428
|
return {
|
|
4357
4429
|
core,
|
|
4358
4430
|
get adapter() {
|
|
@@ -4375,6 +4447,7 @@ ${acp}`);
|
|
|
4375
4447
|
commitFoldState,
|
|
4376
4448
|
recordRebuiltOutput,
|
|
4377
4449
|
noteCompressOutcome,
|
|
4450
|
+
rejectStreakFor,
|
|
4378
4451
|
forgetSession,
|
|
4379
4452
|
primeFold,
|
|
4380
4453
|
acquireLock
|
|
@@ -5562,7 +5635,7 @@ async function statusReport(runtime, ctx) {
|
|
|
5562
5635
|
const coveredIds = collectCoveredMessageIds(state);
|
|
5563
5636
|
const sentTokens = estimateTokens(coreMessages, coveredIds) + systemPromptTokens;
|
|
5564
5637
|
const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: sentTokens });
|
|
5565
|
-
const versionStr = "0.
|
|
5638
|
+
const versionStr = "0.3.1" ? `billion-context-omp@${"0.3.1"}` : void 0;
|
|
5566
5639
|
return buildStatusPanel({
|
|
5567
5640
|
version: versionStr,
|
|
5568
5641
|
tokenCount: sessionTokens,
|
|
@@ -5727,7 +5800,7 @@ function stampAndDetect(selfPath, version, now = Date.now()) {
|
|
|
5727
5800
|
}
|
|
5728
5801
|
|
|
5729
5802
|
// src/update.ts
|
|
5730
|
-
import { readFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
5803
|
+
import { readFile, writeFile as writeFile2, mkdir as mkdir2, access } from "fs/promises";
|
|
5731
5804
|
import { join as join4, dirname as dirname3 } from "path";
|
|
5732
5805
|
import { fileURLToPath } from "url";
|
|
5733
5806
|
import { execFile } from "child_process";
|
|
@@ -5793,43 +5866,112 @@ async function findExtensionDir() {
|
|
|
5793
5866
|
dir = parent;
|
|
5794
5867
|
}
|
|
5795
5868
|
}
|
|
5796
|
-
|
|
5869
|
+
var runNpmImpl = (args, cwd) => new Promise((resolve2) => {
|
|
5870
|
+
execFile(
|
|
5871
|
+
"npm",
|
|
5872
|
+
args,
|
|
5873
|
+
{ cwd, timeout: 6e4, shell: process.platform === "win32", maxBuffer: 4 * 1024 * 1024 },
|
|
5874
|
+
(err, stdout, stderr) => {
|
|
5875
|
+
if (err) logWarn("update", { event: "install-exec-failed", error: err.message, stderr: String(stderr).slice(0, 300) });
|
|
5876
|
+
resolve2({ code: err ? 1 : 0, stdout: String(stdout), stderr: String(stderr) });
|
|
5877
|
+
}
|
|
5878
|
+
);
|
|
5879
|
+
});
|
|
5880
|
+
var runNpm = runNpmImpl;
|
|
5881
|
+
var runNodeImpl = (args) => new Promise((resolve2) => {
|
|
5882
|
+
execFile(
|
|
5883
|
+
process.execPath,
|
|
5884
|
+
args,
|
|
5885
|
+
{ timeout: 15e3, maxBuffer: 4 * 1024 * 1024, shell: false },
|
|
5886
|
+
(err, stdout, stderr) => {
|
|
5887
|
+
resolve2({ code: err ? 1 : 0, stdout: String(stdout), stderr: String(stderr) });
|
|
5888
|
+
}
|
|
5889
|
+
);
|
|
5890
|
+
});
|
|
5891
|
+
var runNode = runNodeImpl;
|
|
5892
|
+
function declaredEntries(pkg) {
|
|
5893
|
+
const entries = /* @__PURE__ */ new Set();
|
|
5894
|
+
for (const ext of pkg.omp?.extensions ?? []) {
|
|
5895
|
+
if (typeof ext === "string") entries.add(ext);
|
|
5896
|
+
}
|
|
5897
|
+
const dot = pkg.exports?.["."];
|
|
5898
|
+
if (typeof dot === "string") entries.add(dot);
|
|
5899
|
+
else if (dot && typeof dot.import === "string") entries.add(dot.import);
|
|
5900
|
+
if (typeof pkg.main === "string") entries.add(pkg.main);
|
|
5901
|
+
return [...entries];
|
|
5902
|
+
}
|
|
5903
|
+
async function verifyInstall(npmDir, latest) {
|
|
5904
|
+
const extDir = join4(npmDir, "node_modules", PACKAGE_NAME);
|
|
5905
|
+
const pkg = await readPackageJson(join4(extDir, "package.json"));
|
|
5906
|
+
if (!pkg) return { ok: false, reason: "package-json-missing" };
|
|
5907
|
+
if (pkg.version !== latest) return { ok: false, reason: `version-mismatch:${pkg.version ?? "none"}` };
|
|
5908
|
+
const entries = declaredEntries(pkg);
|
|
5909
|
+
if (entries.length === 0) return { ok: false, reason: "no-entry-declared" };
|
|
5910
|
+
for (const rel of entries) {
|
|
5911
|
+
try {
|
|
5912
|
+
await access(join4(extDir, rel));
|
|
5913
|
+
} catch {
|
|
5914
|
+
return { ok: false, reason: `entry-missing:${rel}` };
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
const smokeEntry = pkg.omp?.extensions?.[0] ?? entries[0];
|
|
5918
|
+
if (!smokeEntry) return { ok: false, reason: "no-entry-declared" };
|
|
5919
|
+
const smoke = `const{pathToFileURL}=require("node:url");import(pathToFileURL(process.argv[1]).href).then(()=>{},(e)=>{console.error(e&&e.stack||e);process.exit(1)});`;
|
|
5920
|
+
const r = await runNode(["-e", smoke, join4(extDir, smokeEntry)]);
|
|
5921
|
+
if (r.code !== 0) return { ok: false, reason: `entry-import-failed:${r.stderr.slice(0, 500)}` };
|
|
5922
|
+
return { ok: true };
|
|
5923
|
+
}
|
|
5924
|
+
var installArgs = (version) => [
|
|
5925
|
+
"install",
|
|
5926
|
+
`${PACKAGE_NAME}@${version}`,
|
|
5927
|
+
// --no-save: the auto-updater must never mutate the host's package.json
|
|
5928
|
+
// or lockfile.
|
|
5929
|
+
"--no-save",
|
|
5930
|
+
"--silent",
|
|
5931
|
+
"--no-audit",
|
|
5932
|
+
"--no-fund"
|
|
5933
|
+
];
|
|
5934
|
+
async function autoInstallLatest(latest, npmDirOverride) {
|
|
5797
5935
|
if (!SEMVER_RE.test(latest)) {
|
|
5798
5936
|
logWarn("update", { event: "install-abort", reason: "semver", latest });
|
|
5799
|
-
return
|
|
5937
|
+
return "failed";
|
|
5800
5938
|
}
|
|
5801
5939
|
const extDir = await findExtensionDir();
|
|
5802
5940
|
if (!extDir) {
|
|
5803
5941
|
logWarn("update", { event: "install-abort", reason: "extdir-not-found", moduleUrl: import.meta.url });
|
|
5804
|
-
return
|
|
5942
|
+
return "failed";
|
|
5805
5943
|
}
|
|
5806
|
-
const npmDir = findNpmRoot(extDir);
|
|
5944
|
+
const npmDir = npmDirOverride ?? findNpmRoot(extDir);
|
|
5807
5945
|
if (!npmDir) {
|
|
5808
5946
|
logWarn("update", { event: "install-abort", reason: "npmroot-not-found", extDir });
|
|
5809
|
-
return
|
|
5947
|
+
return "failed";
|
|
5810
5948
|
}
|
|
5949
|
+
const prevVersion = (await readPackageJson(join4(npmDir, "node_modules", PACKAGE_NAME, "package.json")))?.version ?? "0.3.1";
|
|
5811
5950
|
try {
|
|
5812
5951
|
const keepAlive = setInterval(() => {
|
|
5813
5952
|
}, 500);
|
|
5814
5953
|
try {
|
|
5815
|
-
const
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
);
|
|
5825
|
-
|
|
5826
|
-
|
|
5954
|
+
const res = await runNpm(installArgs(latest), npmDir);
|
|
5955
|
+
if (res.code !== 0) {
|
|
5956
|
+
logWarn("update", { event: "auto-install-failed", latest, stderr: res.stderr.slice(0, 2e3) });
|
|
5957
|
+
return "failed";
|
|
5958
|
+
}
|
|
5959
|
+
const verify = await verifyInstall(npmDir, latest);
|
|
5960
|
+
if (!verify.ok) {
|
|
5961
|
+
const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.3.1";
|
|
5962
|
+
logWarn("update", { event: "auto-install-verify-failed", latest, reason: verify.reason, rollbackTo });
|
|
5963
|
+
const rb = await runNpm(installArgs(rollbackTo), npmDir);
|
|
5964
|
+
logInfo("update", { event: "rollback", from: latest, to: rollbackTo, ok: rb.code === 0 });
|
|
5965
|
+
return "rolled-back";
|
|
5966
|
+
}
|
|
5967
|
+
logInfo("update", { event: "auto-installed", from: prevVersion, to: latest });
|
|
5968
|
+
return "ok";
|
|
5827
5969
|
} finally {
|
|
5828
5970
|
clearInterval(keepAlive);
|
|
5829
5971
|
}
|
|
5830
5972
|
} catch (e) {
|
|
5831
5973
|
logWarn("update", { event: "install-throw", error: e instanceof Error ? e.message : String(e) });
|
|
5832
|
-
return
|
|
5974
|
+
return "failed";
|
|
5833
5975
|
}
|
|
5834
5976
|
}
|
|
5835
5977
|
async function checkForUpdate(autoUpdate, notify) {
|
|
@@ -5856,7 +5998,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
5856
5998
|
const data = await res.json();
|
|
5857
5999
|
const latest = data.version;
|
|
5858
6000
|
if (!latest) return;
|
|
5859
|
-
const current = runtimeVersion ?? "0.
|
|
6001
|
+
const current = runtimeVersion ?? "0.3.1";
|
|
5860
6002
|
const hasUpdate = isNewer(latest, current);
|
|
5861
6003
|
debug.event("update-check", {
|
|
5862
6004
|
current,
|
|
@@ -5865,16 +6007,16 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
5865
6007
|
});
|
|
5866
6008
|
logInfo("update", { event: "check", current, latest, hasUpdate });
|
|
5867
6009
|
if (hasUpdate) {
|
|
5868
|
-
const
|
|
5869
|
-
if (
|
|
6010
|
+
const outcome = await autoInstallLatest(latest);
|
|
6011
|
+
if (!notify) return;
|
|
6012
|
+
if (outcome === "ok") {
|
|
6013
|
+
notify(`\x1B[32m\u2714 ACP auto-updated ${current} \u2192 ${latest}. Restart omp to finish.\x1B[0m`);
|
|
6014
|
+
} else if (outcome === "rolled-back") {
|
|
5870
6015
|
notify(
|
|
5871
|
-
`\x1B[
|
|
5872
|
-
);
|
|
5873
|
-
logInfo("update", { event: "auto-installed", from: current, to: latest });
|
|
5874
|
-
} else if (!installed && notify) {
|
|
5875
|
-
notify(
|
|
5876
|
-
`${PACKAGE_NAME} ${latest} available (you have ${current}). Run: omp install ${PACKAGE_NAME}@latest`
|
|
6016
|
+
`\x1B[33m\u26A0 ${PACKAGE_NAME} ${latest} failed verification and was rolled back. Keeping ${current}. A later release will auto-update.\x1B[0m`
|
|
5877
6017
|
);
|
|
6018
|
+
} else {
|
|
6019
|
+
notify(`${PACKAGE_NAME} ${latest} available (you have ${current}). Run: omp install ${PACKAGE_NAME}@latest`);
|
|
5878
6020
|
}
|
|
5879
6021
|
}
|
|
5880
6022
|
} catch (e) {
|
|
@@ -6112,10 +6254,11 @@ function applyUserConfig(adapter, user) {
|
|
|
6112
6254
|
function createAcpExtension(adapter = {}) {
|
|
6113
6255
|
return (pi) => {
|
|
6114
6256
|
const runtime = createRuntime(adapter);
|
|
6257
|
+
const warnDelivery = makeDeliveryWarner();
|
|
6115
6258
|
wireSessionLifecycle(pi, runtime);
|
|
6116
|
-
wireContextTransform(pi, runtime);
|
|
6259
|
+
wireContextTransform(pi, runtime, warnDelivery);
|
|
6117
6260
|
wireSystemPrompt(pi, runtime);
|
|
6118
|
-
wireProviderTransform(pi, runtime);
|
|
6261
|
+
wireProviderTransform(pi, runtime, warnDelivery);
|
|
6119
6262
|
wireProviderDebug(pi);
|
|
6120
6263
|
wireToolGuardrails(pi, runtime);
|
|
6121
6264
|
pi.registerTool(makeCompressTool(runtime));
|
|
@@ -6129,26 +6272,14 @@ function createAcpExtension(adapter = {}) {
|
|
|
6129
6272
|
}
|
|
6130
6273
|
var index_default = createAcpExtension();
|
|
6131
6274
|
function wireSessionLifecycle(pi, runtime) {
|
|
6132
|
-
|
|
6275
|
+
const prepareAndPrime = async (ctx, phase) => {
|
|
6133
6276
|
const sid = ctx.sessionManager.getSessionId();
|
|
6134
|
-
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.9" : null });
|
|
6135
|
-
const selfPath = import.meta.url;
|
|
6136
|
-
const conflict = stampAndDetect(selfPath, true ? "0.2.9" : null);
|
|
6137
|
-
if (conflict) {
|
|
6138
|
-
logWarn("instance", { event: "dual-instance", self: selfPath, other: conflict.path, otherPid: conflict.pid, otherVersion: conflict.version });
|
|
6139
|
-
try {
|
|
6140
|
-
if (ctx.hasUI) {
|
|
6141
|
-
ctx.ui.notify(`\u26A0 billion-context-omp loaded TWICE (also from ${conflict.path}). Two instances corrupt compression state \u2014 remove one (check 'omp plugin list' vs config.yml extensions).`);
|
|
6142
|
-
}
|
|
6143
|
-
} catch {
|
|
6144
|
-
}
|
|
6145
|
-
}
|
|
6146
6277
|
try {
|
|
6147
6278
|
const user = await loadUserConfig(ctx.cwd);
|
|
6148
6279
|
runtime.setAdapter(applyUserConfig(runtime.adapter, user));
|
|
6149
6280
|
if (runtime.adapter.debug !== void 0) setDebugEnabled(runtime.adapter.debug);
|
|
6150
6281
|
} catch (e) {
|
|
6151
|
-
logThrow("config", e, { sid, phase
|
|
6282
|
+
logThrow("config", e, { sid, phase });
|
|
6152
6283
|
}
|
|
6153
6284
|
try {
|
|
6154
6285
|
runtime.setPrompts(resolvePrompts(runtime.adapter.prompts, { acknowledgeRisk: runtime.adapter.acknowledgePromptsRisk === true }));
|
|
@@ -6157,10 +6288,35 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
6157
6288
|
runtime.setPrompts(defaultPrompts);
|
|
6158
6289
|
}
|
|
6159
6290
|
runtime.primeFold(ctx);
|
|
6291
|
+
};
|
|
6292
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
6293
|
+
const sid = ctx.sessionManager.getSessionId();
|
|
6294
|
+
const modelInfo = ctx.model;
|
|
6295
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.3.1" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
|
|
6296
|
+
const selfPath = import.meta.url;
|
|
6297
|
+
const conflict = stampAndDetect(selfPath, true ? "0.3.1" : null);
|
|
6298
|
+
if (conflict) {
|
|
6299
|
+
logWarn("instance", { event: "dual-instance", self: selfPath, other: conflict.path, otherPid: conflict.pid, otherVersion: conflict.version });
|
|
6300
|
+
try {
|
|
6301
|
+
if (ctx.hasUI) {
|
|
6302
|
+
ctx.ui.notify(`\u26A0 billion-context-omp loaded TWICE (also from ${conflict.path}). Two instances corrupt compression state \u2014 remove one (check 'omp plugin list' vs config.yml extensions).`);
|
|
6303
|
+
}
|
|
6304
|
+
} catch {
|
|
6305
|
+
}
|
|
6306
|
+
}
|
|
6307
|
+
await prepareAndPrime(ctx, "session_start");
|
|
6160
6308
|
void checkForUpdate(runtime.adapter.autoUpdate ?? true, (msg) => {
|
|
6161
6309
|
if (ctx.hasUI) ctx.ui.notify(msg);
|
|
6162
6310
|
}).catch((e) => logThrow("update", e, { sid, phase: "session_start" }));
|
|
6163
6311
|
});
|
|
6312
|
+
pi.on("session_switch", async (event, ctx) => {
|
|
6313
|
+
logInfo("session", { event: "switch", sid: ctx.sessionManager.getSessionId(), reason: event.reason, previous: event.previousSessionFile ?? null });
|
|
6314
|
+
await prepareAndPrime(ctx, "session_switch");
|
|
6315
|
+
});
|
|
6316
|
+
pi.on("session_branch", async (_event, ctx) => {
|
|
6317
|
+
logInfo("session", { event: "branch", sid: ctx.sessionManager.getSessionId() });
|
|
6318
|
+
await prepareAndPrime(ctx, "session_branch");
|
|
6319
|
+
});
|
|
6164
6320
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
6165
6321
|
try {
|
|
6166
6322
|
runtime.forgetSession(ctx.sessionManager.getSessionId());
|
|
@@ -6204,6 +6360,7 @@ async function transformStream(ctx, runtime, input, mode) {
|
|
|
6204
6360
|
runtime.commitFoldState(ctx, turn.state);
|
|
6205
6361
|
logInfo("turn", {
|
|
6206
6362
|
sid,
|
|
6363
|
+
model: ctx.model?.id ?? null,
|
|
6207
6364
|
inMsgs: coreMessages.length,
|
|
6208
6365
|
outMsgs: turn.messages.length,
|
|
6209
6366
|
tokens: tokenCount,
|
|
@@ -6242,38 +6399,48 @@ async function transformStream(ctx, runtime, input, mode) {
|
|
|
6242
6399
|
if (turn.nudge?.shouldInject) {
|
|
6243
6400
|
const lastUser = [...input].reverse().find((m) => m.role === "user");
|
|
6244
6401
|
const tailText = lastUser ? JSON.stringify(lastUser.content ?? "") : "";
|
|
6245
|
-
const isFeedbackView = tailText.includes("efficiency nudge to compress early") || tailText.includes("Context limit reached");
|
|
6402
|
+
const isFeedbackView = tailText.includes("efficiency nudge to compress early") || tailText.includes("Context limit reached") || tailText.includes("compress calls were rejected in a row");
|
|
6246
6403
|
if (isFeedbackView) {
|
|
6247
6404
|
debug.event("nudge-feedback-skip", { sid: ctx.sessionManager.getSessionId(), msgs: input.length });
|
|
6248
6405
|
} else {
|
|
6249
6406
|
const emergency = turn.nudge.breakdown?.emergencyOverride === 1;
|
|
6407
|
+
const rejectStreak = runtime.rejectStreakFor(ctx);
|
|
6250
6408
|
const epochReset = turn.state.nudge.lastPerMessageNudgeTokens !== preTurnNudgeBaseline;
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
const suppressed = !emergency && prevShown > 0 && tokenCount - prevShown < cadenceFloor;
|
|
6254
|
-
if (suppressed) {
|
|
6255
|
-
turn.state.nudge.lastNudgeShownTokens = prevShown;
|
|
6409
|
+
if (rejectStreak >= LOOP_GUARD_STOP) {
|
|
6410
|
+
turn.state.nudge.lastNudgeShownTokens = epochReset ? 0 : preTurnNudgeShownTokens;
|
|
6256
6411
|
turn.state.nudge.lastShownByTier = preTurnNudgeShownByTier;
|
|
6257
|
-
logInfo("nudge", { sid, event: "cadence-suppressed", growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6258
|
-
debug.event("nudge-suppressed", { sid, growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6259
|
-
} else {
|
|
6260
6412
|
nudgeInjected = true;
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6413
|
+
rebuilt.push(holdMessage(rejectStreak));
|
|
6414
|
+
logInfo("nudge", { sid, event: "hold-injected", streak: rejectStreak, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6415
|
+
debug.event("nudge-hold", { sid, streak: rejectStreak });
|
|
6416
|
+
} else {
|
|
6417
|
+
const prevShown = epochReset ? 0 : preTurnNudgeShownTokens;
|
|
6418
|
+
const cadenceFloor = turn.nudge.breakdown?.growthFloor ?? 0;
|
|
6419
|
+
const suppressed = !emergency && prevShown > 0 && tokenCount - prevShown < cadenceFloor;
|
|
6420
|
+
if (suppressed) {
|
|
6421
|
+
turn.state.nudge.lastNudgeShownTokens = prevShown;
|
|
6422
|
+
turn.state.nudge.lastShownByTier = preTurnNudgeShownByTier;
|
|
6423
|
+
logInfo("nudge", { sid, event: "cadence-suppressed", growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6424
|
+
debug.event("nudge-suppressed", { sid, growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6425
|
+
} else {
|
|
6426
|
+
nudgeInjected = true;
|
|
6427
|
+
{
|
|
6428
|
+
turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
|
|
6429
|
+
const rendered = renderNudgeText(turn.nudge, runtime.prompts);
|
|
6430
|
+
const top = [...turn.nudge.compressibleRanges].sort((a, b) => b.tokens - a.tokens)[0];
|
|
6431
|
+
const example = top ? `
|
|
6266
6432
|
|
|
6267
6433
|
Example: compress({ content: [{ startId: "${top.startRef}", endId: "${top.endRef}", summary: "..." }] })` : "";
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6434
|
+
rebuilt.push(nudgeMessage(turn.nudge, turn.state.blocks.filter((b) => b.active), runtime.prompts, example));
|
|
6435
|
+
if (emergency) {
|
|
6436
|
+
logWarn("nudge", { sid: ctx.sessionManager.getSessionId(), event: "emergency-inject", pct: Math.round(turn.nudge.contextUsage * 100), voice: rendered.voice, compressible: turn.nudge.compressibleRanges.length });
|
|
6437
|
+
}
|
|
6438
|
+
if (debugOn2 && ctx.hasUI) {
|
|
6439
|
+
ctx.ui.notify(`[ACP nudge \u2192 context]${emergency ? " [EMERGENCY]" : ""}
|
|
6274
6440
|
${rendered.text}${example}`);
|
|
6441
|
+
}
|
|
6442
|
+
debug.event("nudge-injected", { sid: ctx.sessionManager.getSessionId(), voice: rendered.voice, channels: ["context", debugOn2 ? "terminal" : null].filter(Boolean), emergency, text: rendered.text + example });
|
|
6275
6443
|
}
|
|
6276
|
-
debug.event("nudge-injected", { sid: ctx.sessionManager.getSessionId(), voice: rendered.voice, channels: ["context", debugOn2 ? "terminal" : null].filter(Boolean), emergency, text: rendered.text + example });
|
|
6277
6444
|
}
|
|
6278
6445
|
}
|
|
6279
6446
|
}
|
|
@@ -6298,10 +6465,13 @@ ${rendered.text}${example}`);
|
|
|
6298
6465
|
}).catch((e) => logThrow("update", e, { sid, phase: "context" }));
|
|
6299
6466
|
return result;
|
|
6300
6467
|
}
|
|
6301
|
-
function wireContextTransform(pi, runtime) {
|
|
6468
|
+
function wireContextTransform(pi, runtime, warnDelivery) {
|
|
6302
6469
|
pi.on("context", async (event, ctx) => {
|
|
6303
6470
|
if (resolveTransformMode(runtime.adapter, ctx.model) === "provider") {
|
|
6304
|
-
|
|
6471
|
+
const sid = ctx.sessionManager.getSessionId();
|
|
6472
|
+
debug.event("context-observer-skip", { sid, msgs: event.messages?.length ?? 0 });
|
|
6473
|
+
const warning = providerDeliveryWarning(runtime.adapter, ctx.model);
|
|
6474
|
+
if (warning) warnDelivery(ctx, sid, warning);
|
|
6305
6475
|
return void 0;
|
|
6306
6476
|
}
|
|
6307
6477
|
const result = await transformStream(ctx, runtime, event.messages ?? [], "context");
|
|
@@ -6309,7 +6479,20 @@ function wireContextTransform(pi, runtime) {
|
|
|
6309
6479
|
return { messages: result.rebuilt };
|
|
6310
6480
|
});
|
|
6311
6481
|
}
|
|
6312
|
-
function
|
|
6482
|
+
function makeDeliveryWarner() {
|
|
6483
|
+
const warned = /* @__PURE__ */ new Set();
|
|
6484
|
+
return (ctx, sid, warning) => {
|
|
6485
|
+
const dedup = `${sid}:${warning.key}`;
|
|
6486
|
+
if (warned.has(dedup)) return;
|
|
6487
|
+
warned.add(dedup);
|
|
6488
|
+
logWarn("provider-transform", { sid, event: "undelivered", reason: warning.reason });
|
|
6489
|
+
try {
|
|
6490
|
+
if (ctx.hasUI) ctx.ui.notify(warning.message);
|
|
6491
|
+
} catch {
|
|
6492
|
+
}
|
|
6493
|
+
};
|
|
6494
|
+
}
|
|
6495
|
+
function wireProviderTransform(pi, runtime, warnDelivery) {
|
|
6313
6496
|
pi.on("before_provider_request", async (event, ctx) => {
|
|
6314
6497
|
if (resolveTransformMode(runtime.adapter, ctx.model) !== "provider") return void 0;
|
|
6315
6498
|
const payload = event.payload;
|
|
@@ -6318,6 +6501,13 @@ function wireProviderTransform(pi, runtime) {
|
|
|
6318
6501
|
const fmt2 = detectProviderWireFormat(payload);
|
|
6319
6502
|
if (fmt2 === null) {
|
|
6320
6503
|
debug.event("provider-transform-unknown-format", { sid });
|
|
6504
|
+
if (runtime.adapter.transformMode === "provider") {
|
|
6505
|
+
warnDelivery(ctx, sid, {
|
|
6506
|
+
key: "unknown-wire-format",
|
|
6507
|
+
reason: "explicit provider mode but the wire body has no codec path (unknown format) \u2014 payload passes through",
|
|
6508
|
+
message: '\u26A0 billion-context-omp: transformMode "provider" is set, but this wire body has no codec path \u2014 compression is NOT applied here. Remove the override to use context mode.'
|
|
6509
|
+
});
|
|
6510
|
+
}
|
|
6321
6511
|
return void 0;
|
|
6322
6512
|
}
|
|
6323
6513
|
const representable = payloadRepresentable(payload, fmt2);
|
|
@@ -6331,13 +6521,15 @@ function wireProviderTransform(pi, runtime) {
|
|
|
6331
6521
|
if (msgs.length === 0) return void 0;
|
|
6332
6522
|
const result = await transformStreamCore(ctx, runtime, msgs, fmt2);
|
|
6333
6523
|
if (!result) return void 0;
|
|
6334
|
-
const
|
|
6335
|
-
const
|
|
6524
|
+
const inMessages = payload.messages ?? [];
|
|
6525
|
+
const rebuilt = fmt2 === "openai" ? restoreOpenaiWireFidelity(inMessages, coreToPayloadMessages(result.coreOut, fmt2, cacheControls)) : coreToPayloadMessages(result.coreOut, fmt2, cacheControls);
|
|
6526
|
+
const outMsgs = rebuilt.length;
|
|
6527
|
+
const inMsgs = inMessages.length;
|
|
6336
6528
|
if (outMsgs !== inMsgs) {
|
|
6337
6529
|
logInfo("provider-transform", { sid, fmt: fmt2, inMsgs, outMsgs, nudge: result.nudgeInjected ? "injected" : "idle" });
|
|
6338
6530
|
}
|
|
6339
6531
|
debug.event("provider-transform", { sid, fmt: fmt2, inMsgs, outMsgs, nudgeInjected: result.nudgeInjected });
|
|
6340
|
-
return { ...payload, messages:
|
|
6532
|
+
return { ...payload, messages: rebuilt };
|
|
6341
6533
|
} catch (e) {
|
|
6342
6534
|
logThrow("provider-transform", e, { sid, fmt: fmt2 });
|
|
6343
6535
|
return void 0;
|
|
@@ -6415,38 +6607,48 @@ async function transformStreamCore(ctx, runtime, wireMsgs, fmt2) {
|
|
|
6415
6607
|
if (turn.nudge?.shouldInject) {
|
|
6416
6608
|
const lastUser = [...wireMsgs].reverse().find((m) => m.role === "user");
|
|
6417
6609
|
const tailText = lastUser ? lastUser.text ?? "" : "";
|
|
6418
|
-
const isFeedbackView = tailText.includes("efficiency nudge to compress early") || tailText.includes("Context limit reached");
|
|
6610
|
+
const isFeedbackView = tailText.includes("efficiency nudge to compress early") || tailText.includes("Context limit reached") || tailText.includes("compress calls were rejected in a row");
|
|
6419
6611
|
if (isFeedbackView) {
|
|
6420
6612
|
debug.event("nudge-feedback-skip", { sid, msgs: wireMsgs.length });
|
|
6421
6613
|
} else {
|
|
6422
6614
|
const emergency = turn.nudge.breakdown?.emergencyOverride === 1;
|
|
6423
6615
|
const epochReset = turn.state.nudge.lastPerMessageNudgeTokens !== preTurnNudgeBaseline;
|
|
6424
|
-
const
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
if (suppressed) {
|
|
6428
|
-
turn.state.nudge.lastNudgeShownTokens = prevShown;
|
|
6616
|
+
const rejectStreak = runtime.rejectStreakFor(ctx);
|
|
6617
|
+
if (rejectStreak >= LOOP_GUARD_STOP) {
|
|
6618
|
+
turn.state.nudge.lastNudgeShownTokens = epochReset ? 0 : preTurnNudgeShownTokens;
|
|
6429
6619
|
turn.state.nudge.lastShownByTier = preTurnNudgeShownByTier;
|
|
6430
|
-
logInfo("nudge", { sid, event: "cadence-suppressed", growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6431
|
-
debug.event("nudge-suppressed", { sid, growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6432
|
-
} else {
|
|
6433
6620
|
nudgeInjected = true;
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6621
|
+
coreOut.push({ id: `acp_hold_${Date.now()}`, role: "user", contentType: "text", text: holdText(rejectStreak) });
|
|
6622
|
+
logInfo("nudge", { sid, event: "hold-injected", streak: rejectStreak, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6623
|
+
debug.event("nudge-hold", { sid, streak: rejectStreak });
|
|
6624
|
+
} else {
|
|
6625
|
+
const prevShown = epochReset ? 0 : preTurnNudgeShownTokens;
|
|
6626
|
+
const cadenceFloor = turn.nudge.breakdown?.growthFloor ?? 0;
|
|
6627
|
+
const suppressed = !emergency && prevShown > 0 && tokenCount - prevShown < cadenceFloor;
|
|
6628
|
+
if (suppressed) {
|
|
6629
|
+
turn.state.nudge.lastNudgeShownTokens = prevShown;
|
|
6630
|
+
turn.state.nudge.lastShownByTier = preTurnNudgeShownByTier;
|
|
6631
|
+
logInfo("nudge", { sid, event: "cadence-suppressed", growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6632
|
+
debug.event("nudge-suppressed", { sid, growth: tokenCount - prevShown, floor: cadenceFloor, pct: Math.round(turn.nudge.contextUsage * 100), reason: turn.nudge.reason });
|
|
6633
|
+
} else {
|
|
6634
|
+
nudgeInjected = true;
|
|
6635
|
+
turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
|
|
6636
|
+
const rendered = renderNudgeText(turn.nudge, runtime.prompts);
|
|
6637
|
+
const top = [...turn.nudge.compressibleRanges].sort((a, b) => b.tokens - a.tokens)[0];
|
|
6638
|
+
const example = top ? `
|
|
6438
6639
|
|
|
6439
6640
|
Example: compress({ content: [{ startId: "${top.startRef}", endId: "${top.endRef}", summary: "..." }] })` : "";
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6641
|
+
if (emergency) {
|
|
6642
|
+
logWarn("nudge", { sid, event: "emergency-inject", pct: Math.round(turn.nudge.contextUsage * 100), voice: rendered.voice, compressible: turn.nudge.compressibleRanges.length });
|
|
6643
|
+
}
|
|
6644
|
+
const debugOn2 = debug.enabled;
|
|
6645
|
+
if (debugOn2 && ctx.hasUI) {
|
|
6646
|
+
ctx.ui.notify(`[ACP nudge \u2192 context]${emergency ? " [EMERGENCY]" : ""}
|
|
6446
6647
|
${rendered.text}${example}`);
|
|
6648
|
+
}
|
|
6649
|
+
debug.event("nudge-injected", { sid, voice: rendered.voice, channels: ["wire", debugOn2 ? "terminal" : null].filter(Boolean), emergency, text: rendered.text + example });
|
|
6650
|
+
coreOut.push({ id: `acp_nudge_${Date.now()}`, role: "user", contentType: "text", text: nudgeText(turn.nudge, turn.state.blocks.filter((b) => b.active), runtime.prompts, example) });
|
|
6447
6651
|
}
|
|
6448
|
-
debug.event("nudge-injected", { sid, voice: rendered.voice, channels: ["wire", debugOn2 ? "terminal" : null].filter(Boolean), emergency, text: rendered.text + example });
|
|
6449
|
-
coreOut.push({ id: `acp_nudge_${Date.now()}`, role: "user", contentType: "text", text: nudgeText(turn.nudge, turn.state.blocks.filter((b) => b.active), runtime.prompts, example) });
|
|
6450
6652
|
}
|
|
6451
6653
|
}
|
|
6452
6654
|
}
|
|
@@ -6522,6 +6724,16 @@ function nudgeMessage(nudge, blocks, prompts, example) {
|
|
|
6522
6724
|
timestamp: Date.now()
|
|
6523
6725
|
};
|
|
6524
6726
|
}
|
|
6727
|
+
function holdText(streak) {
|
|
6728
|
+
return `[ACP hold] Your last ${streak} compress calls were rejected in a row. Do NOT call compress again now and do NOT retry the same range \u2014 the compress reminder is suspended until context actually changes. Continue the actual task. If context still needs relief, run acp_status first and target ONLY a range that meets the minimum size.`;
|
|
6729
|
+
}
|
|
6730
|
+
function holdMessage(streak) {
|
|
6731
|
+
return {
|
|
6732
|
+
role: "user",
|
|
6733
|
+
content: [{ type: "text", text: holdText(streak) }],
|
|
6734
|
+
timestamp: Date.now()
|
|
6735
|
+
};
|
|
6736
|
+
}
|
|
6525
6737
|
export {
|
|
6526
6738
|
createAcpExtension,
|
|
6527
6739
|
index_default as default
|