billion-context-pi 0.1.29 → 0.1.31
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/compat.d.ts +23 -0
- package/dist/index.js +102 -15
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +4 -2
- package/dist/update.d.ts +1 -0
- package/package.json +2 -1
package/dist/compat.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
/**
|
|
3
|
+
* Host compatibility layer for pi vs omp (oh-my-pi) API differences.
|
|
4
|
+
*
|
|
5
|
+
* pi: systemPrompt is string, getSystemPrompt() returns string
|
|
6
|
+
* omp: systemPrompt is string[], getSystemPrompt() returns string[]
|
|
7
|
+
*
|
|
8
|
+
* These helpers normalize the differences so the rest of the codebase
|
|
9
|
+
* can work with a consistent string interface.
|
|
10
|
+
*/
|
|
11
|
+
/** Normalize systemPrompt to a single string (join with newlines if array). */
|
|
12
|
+
export declare function normalizeSystemPrompt(input: string | string[] | undefined): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format systemPrompt for before_agent_start event handler.
|
|
15
|
+
* Always returns string to satisfy pi's type definition, but handles
|
|
16
|
+
* both string (pi) and string[] (omp) input types at runtime.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatSystemPromptForEvent(base: string | string[], append: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Get the system prompt as a single string, regardless of host type.
|
|
21
|
+
* Handles both pi (string) and omp (string[]) return types.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getSystemPromptText(ctx: ExtensionContext): string;
|
package/dist/index.js
CHANGED
|
@@ -2537,6 +2537,15 @@ function patchRefTag(original, core) {
|
|
|
2537
2537
|
if (!tag) return original;
|
|
2538
2538
|
const base = original;
|
|
2539
2539
|
if (base.role === "assistant") return original;
|
|
2540
|
+
const tagCore = tag.replace(/\s+$/, "");
|
|
2541
|
+
let bodyStart = tagCore.length;
|
|
2542
|
+
if (core.text && core.text.charAt(bodyStart) === "\n") bodyStart += 1;
|
|
2543
|
+
const coreBody = core.text ? core.text.slice(bodyStart) : "";
|
|
2544
|
+
const originalBody = extractText(base.content);
|
|
2545
|
+
const trimEnd = (s) => s.replace(/\s+$/, "");
|
|
2546
|
+
if (coreBody && trimEnd(coreBody) !== trimEnd(originalBody)) {
|
|
2547
|
+
return rebuildBodyFromCore(original, coreBody, tag);
|
|
2548
|
+
}
|
|
2540
2549
|
const rawBlocks = Array.isArray(base.content) ? base.content : typeof base.content === "string" ? [{ type: "text", text: base.content }] : [];
|
|
2541
2550
|
const peeled = peelRefTagBlocks(rawBlocks);
|
|
2542
2551
|
const newBlocks = [...peeled];
|
|
@@ -2560,6 +2569,23 @@ ${tag}` : tag };
|
|
|
2560
2569
|
content: [...peeled, { type: "text", text: tag }]
|
|
2561
2570
|
};
|
|
2562
2571
|
}
|
|
2572
|
+
function rebuildBodyFromCore(original, coreBody, tag) {
|
|
2573
|
+
const base = original;
|
|
2574
|
+
const text = `${coreBody.replace(/\s+$/, "")}
|
|
2575
|
+
|
|
2576
|
+
${tag}`;
|
|
2577
|
+
if (typeof base.content === "string") {
|
|
2578
|
+
return { ...original, content: text };
|
|
2579
|
+
}
|
|
2580
|
+
if (Array.isArray(base.content)) {
|
|
2581
|
+
const nonText = base.content.filter((b) => b.type !== "text");
|
|
2582
|
+
return {
|
|
2583
|
+
...original,
|
|
2584
|
+
content: [...nonText, { type: "text", text }]
|
|
2585
|
+
};
|
|
2586
|
+
}
|
|
2587
|
+
return { ...original, content: [{ type: "text", text }] };
|
|
2588
|
+
}
|
|
2563
2589
|
function peelRefTagBlocks(blocks) {
|
|
2564
2590
|
const out = [];
|
|
2565
2591
|
for (const block of blocks) {
|
|
@@ -2730,6 +2756,50 @@ function isPiHost(sm) {
|
|
|
2730
2756
|
const source = sm;
|
|
2731
2757
|
return typeof source.buildContextEntries === "function";
|
|
2732
2758
|
}
|
|
2759
|
+
function mergeLiveEntries(entries, live) {
|
|
2760
|
+
const persisted = entries.filter((e) => e.type === "message");
|
|
2761
|
+
const out = [];
|
|
2762
|
+
let p = 0;
|
|
2763
|
+
let unmatched = 0;
|
|
2764
|
+
for (let i = 0; i < live.length; i++) {
|
|
2765
|
+
const msg = live[i];
|
|
2766
|
+
let matched;
|
|
2767
|
+
let j = p;
|
|
2768
|
+
while (j < persisted.length && persisted[j].message.role !== msg.role) j++;
|
|
2769
|
+
if (j < persisted.length && sameMessage(persisted[j].message, msg)) {
|
|
2770
|
+
matched = persisted[j];
|
|
2771
|
+
p = j + 1;
|
|
2772
|
+
}
|
|
2773
|
+
if (matched) {
|
|
2774
|
+
out.push(matched);
|
|
2775
|
+
} else {
|
|
2776
|
+
unmatched++;
|
|
2777
|
+
out.push({
|
|
2778
|
+
type: "message",
|
|
2779
|
+
id: `live-${i}`,
|
|
2780
|
+
parentId: null,
|
|
2781
|
+
timestamp: String(msg.timestamp ?? Date.now()),
|
|
2782
|
+
message: msg
|
|
2783
|
+
});
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
if (unmatched > 0) logInfo("runtime", { event: "merge-live-entries", live: live.length, unmatched });
|
|
2787
|
+
return out;
|
|
2788
|
+
}
|
|
2789
|
+
function sameMessage(a, b) {
|
|
2790
|
+
const ra = a.role;
|
|
2791
|
+
const rb = b.role;
|
|
2792
|
+
if (ra !== rb) return false;
|
|
2793
|
+
const ca = a.content;
|
|
2794
|
+
const cb = b.content;
|
|
2795
|
+
if (ca === void 0 || cb === void 0) return false;
|
|
2796
|
+
try {
|
|
2797
|
+
return JSON.stringify(ca) === JSON.stringify(cb);
|
|
2798
|
+
} catch (e) {
|
|
2799
|
+
logWarn("runtime", { event: "message-compare-failed", error: e instanceof Error ? e.message : String(e) });
|
|
2800
|
+
return a === b;
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2733
2803
|
function createRuntime(adapter) {
|
|
2734
2804
|
const core = createCore({ countTokens: defaultCountTokens });
|
|
2735
2805
|
const store = new SessionStateStore();
|
|
@@ -2758,11 +2828,12 @@ function createRuntime(adapter) {
|
|
|
2758
2828
|
function configFor(ctx) {
|
|
2759
2829
|
return resolveConfig(adapterRef, liveContextLimit(ctx));
|
|
2760
2830
|
}
|
|
2761
|
-
async function stateFor(ctx) {
|
|
2831
|
+
async function stateFor(ctx, liveMessages) {
|
|
2762
2832
|
const sm = ctx.sessionManager;
|
|
2763
2833
|
const state = await store.load(sm.getSessionFile() ?? void 0, sm.getSessionId());
|
|
2764
2834
|
const entries = readContextEntries(sm);
|
|
2765
|
-
|
|
2835
|
+
const merged = isPiHost(sm) || !liveMessages || liveMessages.length === 0 ? entries : mergeLiveEntries(entries, liveMessages);
|
|
2836
|
+
return { state, coreMessages: entriesToCoreMessages(merged), entries: merged };
|
|
2766
2837
|
}
|
|
2767
2838
|
async function save(state, ctx) {
|
|
2768
2839
|
const sm = ctx.sessionManager;
|
|
@@ -7469,7 +7540,7 @@ function buildMessageOwnerMap(state) {
|
|
|
7469
7540
|
return m;
|
|
7470
7541
|
}
|
|
7471
7542
|
function estimateTokens2(text) {
|
|
7472
|
-
if (!text) return 0;
|
|
7543
|
+
if (typeof text !== "string" || !text) return 0;
|
|
7473
7544
|
const cjk = text.match(/[\u4e00-\u9fff\u3040-\u30ff\uac00-\ud7af]/g);
|
|
7474
7545
|
const cjkCount = cjk?.length ?? 0;
|
|
7475
7546
|
return cjkCount + Math.ceil((text.length - cjkCount) / 4);
|
|
@@ -8561,6 +8632,23 @@ function truncate2(s, n) {
|
|
|
8561
8632
|
return s.slice(0, n - 1) + "\u2026";
|
|
8562
8633
|
}
|
|
8563
8634
|
|
|
8635
|
+
// src/compat.ts
|
|
8636
|
+
function normalizeSystemPrompt(input) {
|
|
8637
|
+
if (input === void 0) return "";
|
|
8638
|
+
if (Array.isArray(input)) return input.join("\n");
|
|
8639
|
+
return input;
|
|
8640
|
+
}
|
|
8641
|
+
function formatSystemPromptForEvent(base, append) {
|
|
8642
|
+
const normalized = normalizeSystemPrompt(base);
|
|
8643
|
+
return `${normalized}
|
|
8644
|
+
|
|
8645
|
+
${append}`;
|
|
8646
|
+
}
|
|
8647
|
+
function getSystemPromptText(ctx) {
|
|
8648
|
+
const result = ctx.getSystemPrompt?.();
|
|
8649
|
+
return normalizeSystemPrompt(result);
|
|
8650
|
+
}
|
|
8651
|
+
|
|
8564
8652
|
// src/commands.ts
|
|
8565
8653
|
function makeCommands(runtime) {
|
|
8566
8654
|
return [
|
|
@@ -8648,7 +8736,7 @@ async function statusReport(runtime, ctx) {
|
|
|
8648
8736
|
const bd = nudge?.contextBreakdown;
|
|
8649
8737
|
const limit = config.modelContextLimit;
|
|
8650
8738
|
const classified = bd ? bd.system + bd.tool + bd.summaries + bd.code + bd.text : 0;
|
|
8651
|
-
const systemPromptText = ctx
|
|
8739
|
+
const systemPromptText = getSystemPromptText(ctx);
|
|
8652
8740
|
const systemPromptTokens = systemPromptText ? defaultCountTokens(systemPromptText) : 0;
|
|
8653
8741
|
const framework = bd ? Math.max(0, tokenCount - classified - systemPromptTokens) : 0;
|
|
8654
8742
|
const displayTotal = tokenCount;
|
|
@@ -8656,7 +8744,7 @@ async function statusReport(runtime, ctx) {
|
|
|
8656
8744
|
const activeBlocksList = state.blocks.filter((b) => b.active);
|
|
8657
8745
|
const totalBlocksList = state.blocks;
|
|
8658
8746
|
const lines = [];
|
|
8659
|
-
const versionStr = "0.1.
|
|
8747
|
+
const versionStr = "0.1.31" ? `billion-context-pi@${"0.1.31"}` : "";
|
|
8660
8748
|
lines.push("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E");
|
|
8661
8749
|
lines.push("\u2502 ACP Context Analysis \u2502");
|
|
8662
8750
|
lines.push("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F");
|
|
@@ -8961,11 +9049,12 @@ async function readPackageJson(path4) {
|
|
|
8961
9049
|
}
|
|
8962
9050
|
function findNpmRoot(extDir) {
|
|
8963
9051
|
let dir = dirname3(extDir);
|
|
8964
|
-
|
|
9052
|
+
for (; ; ) {
|
|
8965
9053
|
if (dir.endsWith("node_modules")) return dirname3(dir);
|
|
8966
|
-
|
|
9054
|
+
const parent = dirname3(dir);
|
|
9055
|
+
if (parent === dir) return void 0;
|
|
9056
|
+
dir = parent;
|
|
8967
9057
|
}
|
|
8968
|
-
return void 0;
|
|
8969
9058
|
}
|
|
8970
9059
|
async function findExtensionDir() {
|
|
8971
9060
|
let dir = dirname3(fileURLToPath(import.meta.url));
|
|
@@ -9021,7 +9110,7 @@ async function checkForUpdate(autoUpdate, notify) {
|
|
|
9021
9110
|
const data = await res.json();
|
|
9022
9111
|
const latest = data.version;
|
|
9023
9112
|
if (!latest) return;
|
|
9024
|
-
const current = runtimeVersion ?? "0.1.
|
|
9113
|
+
const current = runtimeVersion ?? "0.1.31";
|
|
9025
9114
|
const hasUpdate = isNewer(latest, current);
|
|
9026
9115
|
debug.event("update-check", {
|
|
9027
9116
|
current,
|
|
@@ -9260,7 +9349,7 @@ function wireSessionLifecycle(pi, runtime) {
|
|
|
9260
9349
|
runtime.store.invalidate();
|
|
9261
9350
|
runtime.clearNudgeTracking();
|
|
9262
9351
|
const sid = ctx.sessionManager.getSessionId();
|
|
9263
|
-
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.
|
|
9352
|
+
logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.31" : null });
|
|
9264
9353
|
try {
|
|
9265
9354
|
const user = await loadUserConfig(ctx.cwd);
|
|
9266
9355
|
runtime.setAdapter(applyUserConfig(runtime.adapter, user));
|
|
@@ -9289,7 +9378,7 @@ function wireContextTransform(pi, runtime) {
|
|
|
9289
9378
|
const sid = ctx.sessionManager.getSessionId();
|
|
9290
9379
|
const release = await runtime.acquireLock(sid);
|
|
9291
9380
|
try {
|
|
9292
|
-
const { state, coreMessages, entries } = await runtime.stateFor(ctx);
|
|
9381
|
+
const { state, coreMessages, entries } = await runtime.stateFor(ctx, event.messages);
|
|
9293
9382
|
const config = runtime.configFor(ctx);
|
|
9294
9383
|
const coveredIds = collectCoveredMessageIds(state);
|
|
9295
9384
|
const realUsage = ctx.getContextUsage?.();
|
|
@@ -9382,15 +9471,13 @@ function wireSystemPrompt(pi, runtime) {
|
|
|
9382
9471
|
const delegate = runtime.adapter.delegate !== false;
|
|
9383
9472
|
const prompt = delegate ? `${ACP_SYSTEM_PROMPT}
|
|
9384
9473
|
${ACP_DELEGATE_PROMPT}` : ACP_SYSTEM_PROMPT;
|
|
9385
|
-
return { systemPrompt:
|
|
9386
|
-
|
|
9387
|
-
${prompt}` };
|
|
9474
|
+
return { systemPrompt: formatSystemPromptForEvent(event.systemPrompt, prompt) };
|
|
9388
9475
|
});
|
|
9389
9476
|
}
|
|
9390
9477
|
function collectOriginals(entries) {
|
|
9391
9478
|
const map = /* @__PURE__ */ new Map();
|
|
9392
9479
|
for (const entry of entries) {
|
|
9393
|
-
if (entry.type === "message") {
|
|
9480
|
+
if (entry.type === "message" && entry.message) {
|
|
9394
9481
|
map.set(entry.id, entry.message);
|
|
9395
9482
|
} else if (entry.type === "custom_message") {
|
|
9396
9483
|
const content = typeof entry.content === "string" ? [{ type: "text", text: entry.content }] : entry.content;
|