billion-context-omp 0.2.5 → 0.2.6

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 CHANGED
@@ -65,11 +65,11 @@ Each message gets an invisible `<acp>` ref tag (`m00001`, `m00002`, ...) visible
65
65
 
66
66
  **The session stream is the single source of truth.** Compress calls live in the stream itself: every compress tool call's arguments (ranges + summaries) are re-applied deterministically on each LLM call, on restart, and on resume — no sidecar state file to drift out of sync. Position ids (`p1..pN`) and model-facing refs (`m00001..`) are re-derived from the stream every turn; prefix rewrites (retry, rewind, host compaction) are detected and safely re-folded, with fingerprint guards against replaying a call onto the wrong messages.
67
67
 
68
- omp's built-in `/compact` is intercepted and replaced by an ACP model-summarized compaction that also preserves prior compress-call summaries nothing is lost to the gap between the summary and the kept entries.
68
+ omp's built-in `/compact` is **the host's feature** it runs natively (user-initiated, between turns). ACP does not intercept it. Compression itself is the model's decision via the compress tool. If you want ACP to be the *only* compression authority, set `"compaction": { "enabled": false }` in omp settings to disable the host's auto-compact (the 80% threshold trigger); manual `/compact` still works whenever you want it.
69
69
 
70
70
  ## Plugin compatibility
71
71
 
72
- **Keep exactly one context-compression plugin installed.** If two compression extensions both rewrite the message list, they clobber each other's work — compressed ranges can be re-expanded or corrupted. omp's own `/compact` is already intercepted automatically by billion-context-omp, but any *third-party* compression/compaction extension should be uninstalled.
72
+ **Keep exactly one context-compression plugin installed.** If two compression extensions both rewrite the message list, they clobber each other's work — compressed ranges can be re-expanded or corrupted. Any *third-party* compression/compaction extension should be uninstalled.
73
73
 
74
74
  ## Model-facing tools
75
75
 
@@ -123,7 +123,6 @@ Create `~/.omp/acp-omp.json` (global) and/or `<project>/.omp/acp-omp.json` (proj
123
123
  "debug": false,
124
124
  "autoUpdate": true,
125
125
  "modelContextLimit": 200000,
126
- "compressModel": "zhipuai:glm-5.2",
127
126
  "toolBashDefaultTimeout": 60,
128
127
  "toolOutputMaxBytes": 200000,
129
128
  "compress": {
@@ -145,10 +144,9 @@ Create `~/.omp/acp-omp.json` (global) and/or `<project>/.omp/acp-omp.json` (proj
145
144
  | Key | Default | Description |
146
145
  |-----|---------|-------------|
147
146
  | `debug` | `false` | Enable verbose **debug-level** events in the log. The always-on log (lifecycle events, errors, warnings) is written regardless; `debug` only adds extra diagnostics. Also enabled by env `ACP_DEBUG=1`. |
148
- | `transformMode` | `"context"` (default) or `"provider"` — where the compression surgery intercepts. `provider` transforms the provider wire payload (no feedback re-entry; experimental). |
147
+ | `transformMode` | `"provider"` (default since v0.2.6) or `"context"` — where the compression surgery intercepts. `provider` transforms the provider wire payload (request-local, structurally immune to feedback re-entry). `context` is the legacy rewrite-in-place mode. |
149
148
  | `autoUpdate` | `true` | On session start (throttled to one check per 3 minutes), check npm for a newer version and auto-install it. Disable to avoid all startup network calls. |
150
149
  | `modelContextLimit` | *(auto)* | Override the context limit (in tokens). Defaults to the model's `contextWindow`. |
151
- | `compressModel` | *(session model)* | `provider:modelId` used for `/compact` model-summarized compaction (e.g. `"zhipuai:glm-5.2"`). Defaults to the current session model when omitted. |
152
150
  | `toolBashDefaultTimeout` | `60` | Seconds injected into the `bash` tool when the model omits `timeout`. Without this a forgotten timeout can hang for thousands of seconds. `0` restores unbounded behavior. |
153
151
  | `toolOutputMaxBytes` | `200000` | Hard byte cap on tool result text (applied via the `tool_result` hook). Stops runaway output that omp's own caps can't catch. When it fires the model is told where the full output lives; set lower (e.g. `8192`) for a tighter context budget, or `0` to disable. |
154
152
  | `compress.maxContextLimit` | `"75%"` | Context usage threshold that triggers **forced compression** nudges (bypasses growth-gate + cadence). Accepts a ratio (`0.75`) or percent string (`"75%"`). Lower = compress earlier / more aggressively. |
package/README.zh-CN.md CHANGED
@@ -65,11 +65,11 @@ billion-context 拦截 omp 的 `context` 事件(每次 LLM 调用前触发)
65
65
 
66
66
  **会话流是唯一真相源。** compress 调用本身就存在于流中:每次 compress 工具调用的参数(区间 + 摘要)在每次 LLM 调用、重启、resume 时被确定性重放——没有会漂移失步的独立状态文件。位置 id(`p1..pN`)和面向模型的 ref(`m00001..`)每轮从流重新推导;前缀改写(retry、rewind、宿主 compaction)会被检测并安全重折叠,指纹守卫防止把调用重放到错误的消息上。
67
67
 
68
- omp 内置的 `/compact` 被拦截,替换为 ACP 模型摘要式 compaction,它同时保留之前的 compress 调用摘要——摘要与保留条目之间的空隙不会丢任何东西。
68
+ omp 内置的 `/compact` **是宿主的功能**——原生运行(用户手动发起、轮间执行),ACP 不拦截。压缩本身由模型通过 compress 工具主动决策。若想让 ACP 成为*唯一*压缩主体,在 omp settings 里设 `"compaction": { "enabled": false }` 关掉宿主自动压缩(80% 阈值触发);手动 `/compact` 随时可用。
69
69
 
70
70
  ## 插件兼容性
71
71
 
72
- **只安装一个上下文压缩插件。** 若两个压缩扩展都改写消息列表,它们会互相破坏对方的工作——被压缩的区间可能被重新展开或损坏。omp 自己的 `/compact` 已被 billion-context-omp 自动拦截,但任何*第三方*压缩/compaction 扩展都应卸载。
72
+ **只安装一个上下文压缩插件。** 若两个压缩扩展都改写消息列表,它们会互相破坏对方的工作——被压缩的区间可能被重新展开或损坏。任何*第三方*压缩/compaction 扩展都应卸载。
73
73
 
74
74
  ## 面向模型的工具
75
75
 
@@ -123,7 +123,6 @@ billion-context-omp 开箱即用,无需配置。可选键写入 JSON 配置文
123
123
  "debug": false,
124
124
  "autoUpdate": true,
125
125
  "modelContextLimit": 200000,
126
- "compressModel": "zhipuai:glm-5.2",
127
126
  "toolBashDefaultTimeout": 60,
128
127
  "toolOutputMaxBytes": 200000,
129
128
  "compress": {
@@ -147,7 +146,7 @@ billion-context-omp 开箱即用,无需配置。可选键写入 JSON 配置文
147
146
  | `debug` | `false` | 开启**debug 级**详细日志事件。常开日志(生命周期事件、错误、警告)无论如何都会写;`debug` 只增加诊断信息。也可用环境变量 `ACP_DEBUG=1` 开启。 |
148
147
  | `autoUpdate` | `true` | 会话启动时(节流为每 3 分钟最多一次)检查 npm 是否有新版本并自动安装。关闭可避免所有启动期网络请求。 |
149
148
  | `modelContextLimit` | *(自动)* | 覆盖上下文上限(token 数)。默认取模型的 `contextWindow`。 |
150
- | `compressModel` | *(会话模型)* | `/compact` 模型摘要式压缩使用的 `provider:modelId`(如 `"zhipuai:glm-5.2"`)。缺省用当前会话模型。 |
149
+ | `transformMode` | `"provider"`(v0.2.6 起默认)或 `"context"` | 压缩手术拦截位置。`provider` 变换 provider wire 载荷(请求局部,结构性免疫回灌环路)。`context` 是旧版原地改写模式。 |
151
150
  | `toolBashDefaultTimeout` | `60` | 模型省略 `timeout` 时注入 `bash` 工具的秒数。没有它,一次忘记的 timeout 可能挂起数千秒。`0` 恢复无限制。 |
152
151
  | `toolOutputMaxBytes` | `200000` | 工具结果文本的硬字节上限(经 `tool_result` 钩子实施)。拦截 omp 自身上限管不住的失控输出。触发时模型会被告知完整输出在哪;调低(如 `8192`)可更省上下文,`0` 禁用。 |
153
152
  | `compress.maxContextLimit` | `"75%"` | 触发**强制压缩**提醒的上下文用量阈值(绕过增长门控与节拍)。接受比例(`0.75`)或百分比字符串(`"75%"`)。越低 = 越早/越激进压缩。 |
package/dist/config.d.ts CHANGED
@@ -27,12 +27,15 @@ export interface CompressConfig {
27
27
  * (live model context window, protected tools, state persistence).
28
28
  */
29
29
  export interface AdapterConfig {
30
- /** Where the compression surgery intercepts (issue #52). "context" (default)
31
- * rewrites the context event battle-tested, but omp's recap/subagent
32
- * pipelines can re-feed our output as input (feedback-view loops).
33
- * "provider" leaves the agent array untouched and transforms the WIRE
34
- * payload at before_provider_request request-local, no re-entry; unknown
35
- * provider formats pass through untransformed (fail-open). */
30
+ /** Where the compression surgery intercepts (issue #52). "provider"
31
+ * (default since v0.2.6) leaves the agent array untouched and transforms
32
+ * the WIRE payload at before_provider_request request-local, no
33
+ * re-entry, structurally immune to omp's feedback-view loops (the recap /
34
+ * subagent re-feed pathology, issues #22/#52). Unknown provider formats
35
+ * pass through untransformed (fail-open). "context" rewrites the context
36
+ * event — battle-tested legacy mode, kept for compat.
37
+ * Existing setups pin the mode explicitly via `transformMode` in
38
+ * ~/.omp/acp-omp.json; unset now resolves to "provider". */
36
39
  transformMode?: "context" | "provider";
37
40
  /** When omitted, the adapter reads `ctx.model.contextWindow` live each turn.
38
41
  * Set explicitly for tests/headless runs. */
package/dist/index.js CHANGED
@@ -3663,7 +3663,7 @@ function createRuntime(adapter) {
3663
3663
  if (view.length === 0) return;
3664
3664
  let stream = view;
3665
3665
  let wire = false;
3666
- if ((adapterRef.transformMode ?? "context") === "provider" && ctx.model?.api === "openai-completions") {
3666
+ if ((adapterRef.transformMode ?? "provider") === "provider" && ctx.model?.api === "openai-completions") {
3667
3667
  const base = getSystemPromptText(ctx);
3668
3668
  const acp = buildAcpSystemPrompt(promptsRef);
3669
3669
  stream = viewToWireStream(view, base.includes(acp) ? base : `${base}
@@ -4903,7 +4903,7 @@ async function statusReport(runtime, ctx) {
4903
4903
  const coveredIds = collectCoveredMessageIds(state);
4904
4904
  const sentTokens = estimateTokens(coreMessages, coveredIds) + systemPromptTokens;
4905
4905
  const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: sentTokens });
4906
- const versionStr = "0.2.5" ? `billion-context-omp@${"0.2.5"}` : void 0;
4906
+ const versionStr = "0.2.6" ? `billion-context-omp@${"0.2.6"}` : void 0;
4907
4907
  return buildStatusPanel({
4908
4908
  version: versionStr,
4909
4909
  tokenCount: sessionTokens,
@@ -5193,7 +5193,7 @@ async function checkForUpdate(autoUpdate, notify) {
5193
5193
  const data = await res.json();
5194
5194
  const latest = data.version;
5195
5195
  if (!latest) return;
5196
- const current = runtimeVersion ?? "0.2.5";
5196
+ const current = runtimeVersion ?? "0.2.6";
5197
5197
  const hasUpdate = isNewer(latest, current);
5198
5198
  debug.event("update-check", {
5199
5199
  current,
@@ -5469,9 +5469,9 @@ var index_default = createAcpExtension();
5469
5469
  function wireSessionLifecycle(pi, runtime) {
5470
5470
  pi.on("session_start", async (_event, ctx) => {
5471
5471
  const sid = ctx.sessionManager.getSessionId();
5472
- logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.5" : null });
5472
+ logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.6" : null });
5473
5473
  const selfPath = import.meta.url;
5474
- const conflict = stampAndDetect(selfPath, true ? "0.2.5" : null);
5474
+ const conflict = stampAndDetect(selfPath, true ? "0.2.6" : null);
5475
5475
  if (conflict) {
5476
5476
  logWarn("instance", { event: "dual-instance", self: selfPath, other: conflict.path, otherPid: conflict.pid, otherVersion: conflict.version });
5477
5477
  try {
@@ -5638,7 +5638,7 @@ ${rendered.text}${example}`);
5638
5638
  }
5639
5639
  function wireContextTransform(pi, runtime) {
5640
5640
  pi.on("context", async (event, ctx) => {
5641
- if ((runtime.adapter.transformMode ?? "context") === "provider") {
5641
+ if ((runtime.adapter.transformMode ?? "provider") === "provider") {
5642
5642
  debug.event("context-observer-skip", { sid: ctx.sessionManager.getSessionId(), msgs: event.messages?.length ?? 0 });
5643
5643
  return void 0;
5644
5644
  }
@@ -5649,7 +5649,7 @@ function wireContextTransform(pi, runtime) {
5649
5649
  }
5650
5650
  function wireProviderTransform(pi, runtime) {
5651
5651
  pi.on("before_provider_request", async (event, ctx) => {
5652
- if ((runtime.adapter.transformMode ?? "context") !== "provider") return void 0;
5652
+ if ((runtime.adapter.transformMode ?? "provider") !== "provider") return void 0;
5653
5653
  const payload = event.payload;
5654
5654
  if (payload === null || typeof payload !== "object" || !Array.isArray(payload.messages)) return void 0;
5655
5655
  const sid = ctx.sessionManager?.getSessionId?.() ?? "";