billion-context-omp 0.2.0 → 0.2.2
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/index.js +72 -15
- package/dist/index.js.map +1 -1
- package/dist/instance-guard.d.ts +13 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3166,6 +3166,15 @@ function freshSlot(preserveFrom) {
|
|
|
3166
3166
|
}
|
|
3167
3167
|
return slot;
|
|
3168
3168
|
}
|
|
3169
|
+
function isViewFlip(foldedLen, lcp) {
|
|
3170
|
+
return foldedLen > 0 && lcp >= Math.floor(foldedLen / 2);
|
|
3171
|
+
}
|
|
3172
|
+
function preserveCompressedSlot(prev) {
|
|
3173
|
+
const slot = freshSlot(prev);
|
|
3174
|
+
slot.state = { ...slot.state, blocks: prev.state.blocks, messageRefs: prev.state.messageRefs, stats: prev.state.stats };
|
|
3175
|
+
slot.appliedCallIds = new Set(prev.appliedCallIds);
|
|
3176
|
+
return slot;
|
|
3177
|
+
}
|
|
3169
3178
|
function stateHasCompressCall(state, callId) {
|
|
3170
3179
|
return state.blocks.some((b) => b.compressCallId === callId);
|
|
3171
3180
|
}
|
|
@@ -3217,8 +3226,9 @@ function createRuntime(adapter) {
|
|
|
3217
3226
|
let lcp = 0;
|
|
3218
3227
|
while (lcp < Math.min(ids.length, slot.identities.length) && ids[lcp] === slot.identities[lcp]) lcp++;
|
|
3219
3228
|
if (lcp < slot.foldedLen) {
|
|
3220
|
-
|
|
3221
|
-
slot
|
|
3229
|
+
const flip = isViewFlip(slot.foldedLen, lcp);
|
|
3230
|
+
debug.event("fold-refold", { sid, foldedLen: slot.foldedLen, lcp, streamLen: ids.length, flip });
|
|
3231
|
+
slot = flip ? preserveCompressedSlot(slot) : freshSlot(slot);
|
|
3222
3232
|
slots.set(sid, slot);
|
|
3223
3233
|
lcp = 0;
|
|
3224
3234
|
}
|
|
@@ -3244,6 +3254,7 @@ function createRuntime(adapter) {
|
|
|
3244
3254
|
debug.event("fold-replay-skipped", { sid, callId: call.id });
|
|
3245
3255
|
continue;
|
|
3246
3256
|
}
|
|
3257
|
+
if (slot.appliedCallIds.has(call.id) || stateHasCompressCall(slot.state, call.id)) continue;
|
|
3247
3258
|
const stale = call.ranges.map((r, ri) => staleRange(r, ri, resultText, coreMessages, i, slot.state.messageRefs.byRef, slot.state.blocks)).find((s) => s !== false);
|
|
3248
3259
|
if (stale) {
|
|
3249
3260
|
debug.event("fold-replay-stale", { sid, callId: call.id, reason: stale });
|
|
@@ -4497,7 +4508,7 @@ async function statusReport(runtime, ctx) {
|
|
|
4497
4508
|
const coveredIds = collectCoveredMessageIds(state);
|
|
4498
4509
|
const sentTokens = estimateTokens(coreMessages, coveredIds) + systemPromptTokens;
|
|
4499
4510
|
const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: sentTokens });
|
|
4500
|
-
const versionStr = "0.2.
|
|
4511
|
+
const versionStr = "0.2.2" ? `billion-context-omp@${"0.2.2"}` : void 0;
|
|
4501
4512
|
return buildStatusPanel({
|
|
4502
4513
|
version: versionStr,
|
|
4503
4514
|
tokenCount: sessionTokens,
|
|
@@ -5040,9 +5051,44 @@ function wireToolGuardrails(pi, runtime) {
|
|
|
5040
5051
|
});
|
|
5041
5052
|
}
|
|
5042
5053
|
|
|
5054
|
+
// src/instance-guard.ts
|
|
5055
|
+
import { readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
5056
|
+
import { join as join4 } from "path";
|
|
5057
|
+
var MARKER_FILE = ".billion-context-omp-instance.json";
|
|
5058
|
+
var FRESH_MS = 6e4;
|
|
5059
|
+
function markerPath() {
|
|
5060
|
+
return join4(homeDir(), ".omp", MARKER_FILE);
|
|
5061
|
+
}
|
|
5062
|
+
function readMarker() {
|
|
5063
|
+
try {
|
|
5064
|
+
const raw = JSON.parse(readFileSync2(markerPath(), "utf8"));
|
|
5065
|
+
if (typeof raw?.path === "string" && typeof raw?.ts === "number") return raw;
|
|
5066
|
+
} catch {
|
|
5067
|
+
}
|
|
5068
|
+
return void 0;
|
|
5069
|
+
}
|
|
5070
|
+
function detectDualInstance(selfPath, now = Date.now()) {
|
|
5071
|
+
const m = readMarker();
|
|
5072
|
+
if (!m) return void 0;
|
|
5073
|
+
if (m.path === selfPath) return void 0;
|
|
5074
|
+
if (now - m.ts > FRESH_MS) return void 0;
|
|
5075
|
+
return m;
|
|
5076
|
+
}
|
|
5077
|
+
function stampInstance(selfPath, version, pid = process.pid, now = Date.now()) {
|
|
5078
|
+
try {
|
|
5079
|
+
writeFileSync(markerPath(), JSON.stringify({ path: selfPath, version, pid, ts: now }));
|
|
5080
|
+
} catch {
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
function stampAndDetect(selfPath, version, now = Date.now()) {
|
|
5084
|
+
const conflict = detectDualInstance(selfPath, now);
|
|
5085
|
+
stampInstance(selfPath, version, void 0, now);
|
|
5086
|
+
return conflict;
|
|
5087
|
+
}
|
|
5088
|
+
|
|
5043
5089
|
// src/update.ts
|
|
5044
5090
|
import { readFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
5045
|
-
import { join as
|
|
5091
|
+
import { join as join5, dirname as dirname3 } from "path";
|
|
5046
5092
|
import { fileURLToPath } from "url";
|
|
5047
5093
|
import { execFile } from "child_process";
|
|
5048
5094
|
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME3 } from "@oh-my-pi/pi-utils";
|
|
@@ -5050,7 +5096,7 @@ var PACKAGE_NAME = "billion-context-omp";
|
|
|
5050
5096
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
5051
5097
|
var SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/;
|
|
5052
5098
|
var CHECK_INTERVAL_MS = 3 * 60 * 1e3;
|
|
5053
|
-
var throttleFile = () =>
|
|
5099
|
+
var throttleFile = () => join5(homeDir(), CONFIG_DIR_NAME3, ".billion-context-omp-update-check");
|
|
5054
5100
|
var updateInFlight = false;
|
|
5055
5101
|
function parseVersion(v) {
|
|
5056
5102
|
return v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -5100,7 +5146,7 @@ function findNpmRoot(extDir) {
|
|
|
5100
5146
|
async function findExtensionDir() {
|
|
5101
5147
|
let dir = dirname3(fileURLToPath(import.meta.url));
|
|
5102
5148
|
for (; ; ) {
|
|
5103
|
-
const pkg = await readPackageJson(
|
|
5149
|
+
const pkg = await readPackageJson(join5(dir, "package.json"));
|
|
5104
5150
|
if (pkg?.name === PACKAGE_NAME) return dir;
|
|
5105
5151
|
const parent = dirname3(dir);
|
|
5106
5152
|
if (parent === dir) return void 0;
|
|
@@ -5170,7 +5216,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
5170
5216
|
const data = await res.json();
|
|
5171
5217
|
const latest = data.version;
|
|
5172
5218
|
if (!latest) return;
|
|
5173
|
-
const current = runtimeVersion ?? "0.2.
|
|
5219
|
+
const current = runtimeVersion ?? "0.2.2";
|
|
5174
5220
|
const hasUpdate = isNewer(latest, current);
|
|
5175
5221
|
debug.event("update-check", {
|
|
5176
5222
|
current,
|
|
@@ -5200,12 +5246,12 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
5200
5246
|
async function getRuntimeVersion() {
|
|
5201
5247
|
const extDir = await findExtensionDir();
|
|
5202
5248
|
if (!extDir) return void 0;
|
|
5203
|
-
const pkg = await readPackageJson(
|
|
5249
|
+
const pkg = await readPackageJson(join5(extDir, "package.json"));
|
|
5204
5250
|
return pkg?.version;
|
|
5205
5251
|
}
|
|
5206
5252
|
|
|
5207
5253
|
// src/dump.ts
|
|
5208
|
-
import { mkdirSync as mkdirSync2, writeFileSync, readdirSync, unlinkSync } from "fs";
|
|
5254
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readdirSync, unlinkSync } from "fs";
|
|
5209
5255
|
import * as path2 from "path";
|
|
5210
5256
|
import { CONFIG_DIR_NAME as CONFIG_DIR_NAME4 } from "@oh-my-pi/pi-utils";
|
|
5211
5257
|
var counters = {};
|
|
@@ -5250,7 +5296,7 @@ function dumpContextMessages(messages, meta) {
|
|
|
5250
5296
|
counters[dir] = seq + 1;
|
|
5251
5297
|
const name = `${String(seq).padStart(4, "0")}.json`;
|
|
5252
5298
|
const fullPath = path2.join(dir, name);
|
|
5253
|
-
|
|
5299
|
+
writeFileSync2(
|
|
5254
5300
|
fullPath,
|
|
5255
5301
|
JSON.stringify({
|
|
5256
5302
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5334,7 +5380,7 @@ function dumpProviderRequest(payload, meta) {
|
|
|
5334
5380
|
const name = `req_${String(seq).padStart(4, "0")}.json`;
|
|
5335
5381
|
const fullPath = path2.join(dir, name);
|
|
5336
5382
|
const summary = summarizeProviderPayload(payload);
|
|
5337
|
-
|
|
5383
|
+
writeFileSync2(
|
|
5338
5384
|
fullPath,
|
|
5339
5385
|
JSON.stringify({
|
|
5340
5386
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5359,8 +5405,8 @@ import { CONFIG_DIR_NAME as CONFIG_DIR_NAME5 } from "@oh-my-pi/pi-utils";
|
|
|
5359
5405
|
async function loadUserConfig(cwd) {
|
|
5360
5406
|
const home = homeDir();
|
|
5361
5407
|
const merged = {};
|
|
5362
|
-
for (const base of [
|
|
5363
|
-
const file =
|
|
5408
|
+
for (const base of [join8(home, CONFIG_DIR_NAME5), join8(cwd, CONFIG_DIR_NAME5)]) {
|
|
5409
|
+
const file = join8(base, "acp-omp.json");
|
|
5364
5410
|
const allowPrompts = base.startsWith(home);
|
|
5365
5411
|
try {
|
|
5366
5412
|
const raw = await fs.readFile(file, "utf8");
|
|
@@ -5378,7 +5424,7 @@ async function loadUserConfig(cwd) {
|
|
|
5378
5424
|
}
|
|
5379
5425
|
return merged;
|
|
5380
5426
|
}
|
|
5381
|
-
function
|
|
5427
|
+
function join8(...parts) {
|
|
5382
5428
|
return path3.join(...parts);
|
|
5383
5429
|
}
|
|
5384
5430
|
var KNOWN = /* @__PURE__ */ new Set([
|
|
@@ -5486,7 +5532,18 @@ function wireCompactionDisable(pi, runtime) {
|
|
|
5486
5532
|
function wireSessionLifecycle(pi, runtime) {
|
|
5487
5533
|
pi.on("session_start", async (_event, ctx) => {
|
|
5488
5534
|
const sid = ctx.sessionManager.getSessionId();
|
|
5489
|
-
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.
|
|
5535
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.2.2" : null });
|
|
5536
|
+
const selfPath = import.meta.url;
|
|
5537
|
+
const conflict = stampAndDetect(selfPath, true ? "0.2.2" : null);
|
|
5538
|
+
if (conflict) {
|
|
5539
|
+
logWarn("instance", { event: "dual-instance", self: selfPath, other: conflict.path, otherPid: conflict.pid, otherVersion: conflict.version });
|
|
5540
|
+
try {
|
|
5541
|
+
if (ctx.hasUI) {
|
|
5542
|
+
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).`);
|
|
5543
|
+
}
|
|
5544
|
+
} catch {
|
|
5545
|
+
}
|
|
5546
|
+
}
|
|
5490
5547
|
try {
|
|
5491
5548
|
const user = await loadUserConfig(ctx.cwd);
|
|
5492
5549
|
runtime.setAdapter(applyUserConfig(runtime.adapter, user));
|