billion-context-omp 0.3.0 → 0.3.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.
@@ -19,14 +19,6 @@ export interface StreamCompressCall {
19
19
  compressCallId: string;
20
20
  }[];
21
21
  }
22
- /** Most recent REJECTED compress call+result pair (issue #104): the kernel's
23
- * hide-compress-calls node strips orphaned calls (KEEP_LAST_ORPHANED=0) — a
24
- * rejected call creates no block, so BOTH the call and its result vanish
25
- * from the model's view on the next turn; it cannot see the rejection or
26
- * the loop-guard STOP and retries forever (observed: 92 in a row). The
27
- * transform re-appends this pair so the last attempt's outcome stays
28
- * visible. Returns null when no rejected call exists. */
29
- export declare function lastRejectedCompressPair(stream: AgentMessage[]): AgentMessage[] | null;
30
22
  export declare function findCompressCalls(message: AgentMessage): StreamCompressCall[];
31
23
  /** Extract a compress tool's arguments from a stream toolCall. Two call
32
24
  * shapes exist: (1) top-level — our tools are registered with
package/dist/runtime.d.ts CHANGED
@@ -2,13 +2,6 @@ import type { ExtensionContext } from "@oh-my-pi/pi-coding-agent";
2
2
  import { type CompressionCore, type CompressionState, type Config, type CoreMessage, type Prompts } from "acp-kernel";
3
3
  import { type AdapterConfig } from "./config.js";
4
4
  import type { BiliMessage } from "acp-kernel/wire";
5
- import { type AgentMessage } from "./messages.js";
6
- export interface FoldResult {
7
- state: CompressionState;
8
- coreMessages: CoreMessage[];
9
- originalById: Map<string, AgentMessage>;
10
- streamLen: number;
11
- }
12
5
  /** Core-space fold result (provider mode): no originalById — the output
13
6
  * rebuilds straight onto the wire via the kernel codecs. */
14
7
  export interface CoreFoldResult {
@@ -24,22 +17,17 @@ export interface AcpRuntime {
24
17
  setPrompts(prompts: Prompts): void;
25
18
  liveContextLimit(ctx: ExtensionContext): number;
26
19
  configFor(ctx: ExtensionContext): Config;
27
- foldStream(ctx: ExtensionContext, stream: AgentMessage[]): FoldResult;
28
20
  /** Core-space fold (provider mode): the wire payload already parsed to
29
- * BiliMessage[] by the kernel codec; same incremental LCP + replay
30
- * semantics as foldStream, content-hash id space (wire-fold.ts). */
21
+ * BiliMessage[] by the kernel codec; incremental LCP + replay semantics,
22
+ * content-hash id space (wire-fold.ts). */
31
23
  foldStreamCore(ctx: ExtensionContext, stream: BiliMessage[]): CoreFoldResult;
32
24
  stateFor(ctx: ExtensionContext): Promise<{
33
25
  state: CompressionState;
34
26
  coreMessages: CoreMessage[];
35
27
  }>;
36
- /** Commit the folded state to the slot space the session's CURRENT mode
37
- * folds in (provider -> core slot, context -> context slot) — the mirror
38
- * of stateFor: a commit must land where the next read goes (issue #90). */
28
+ /** Commit the folded state to the core slot the mirror of stateFor: a
29
+ * commit must land where the next read goes (issue #90). */
39
30
  commitFoldState(ctx: ExtensionContext, state: CompressionState, toolCallId?: string): void;
40
- /** Record the identity sequence of the last rebuilt output so the next
41
- * foldStream can recognize omp re-feeding it (issue #52). */
42
- recordRebuiltOutput(ctx: ExtensionContext, rebuilt: AgentMessage[]): void;
43
31
  /** Track the per-session streak of consecutively REJECTED compress calls.
44
32
  * `ok=false` increments and returns the new streak; `ok=true` resets to 0.
45
33
  * A re-fold (rewritten stream prefix) drops the slot and starts at 0. */
@@ -48,6 +36,22 @@ export interface AcpRuntime {
48
36
  * mode folds in (issue #104: the nudge must not demand compression while
49
37
  * compress calls are being rejected in a row). */
50
38
  rejectStreakFor(ctx: ExtensionContext): number;
39
+ /** Restore the fold slot from the previous process's checkpoint (issue
40
+ * #130). Returns true when the session already has a live in-memory slot
41
+ * (in-process switch back — never clobbered) or a valid checkpoint was
42
+ * loaded. Callers skip the primeFold mirror: a mirror that guesses the
43
+ * host's view→wire projection lands in a different fingerprint space,
44
+ * which is exactly the bug the checkpoint exists to fix. */
45
+ restoreFold(ctx: ExtensionContext): boolean;
46
+ /** Debounced checkpoint of the live fold slot. Called from the live fold
47
+ * path only (wire fold, turn commit, compress commit) — preview/mirror
48
+ * slots are never persisted. No-op when persistence is disabled. */
49
+ scheduleFoldSnapshot(ctx: ExtensionContext): void;
50
+ /** Synchronously flush the session's checkpoint. For session_shutdown:
51
+ * the host may exit as soon as the handler returns, so a debounced save
52
+ * would be dropped with the process. Returns false when the write
53
+ * failed (the in-memory slot is unaffected either way). */
54
+ flushFoldSync(sid: string): boolean;
51
55
  forgetSession(sid: string): void;
52
56
  /** Rebuild blocks from the persisted session at session_start so /acp and
53
57
  * acp_status show them BEFORE the first LLM call of a resumed session.
@@ -1,20 +1,17 @@
1
- import type { AdapterConfig } from "./config.js";
1
+ export declare const MIN_HOST_VERSION: readonly [number, number, number];
2
2
  export declare function hostVersionAtLeast(min: readonly [number, number, number], version?: string): boolean;
3
- export declare function resolveTransformMode(adapter: Pick<AdapterConfig, "transformMode">, model: {
4
- api?: string;
5
- } | undefined, hostVersion?: string): "context" | "provider";
3
+ /** True when the running host meets the minimum version omp requires. */
4
+ export declare function hostMeetsMinimum(version?: string): boolean;
6
5
  export interface ProviderDeliveryWarning {
7
6
  key: string;
8
7
  reason: string;
9
8
  message: string;
10
9
  }
11
- /** An explicit transformMode "provider" is an escape hatch for patched hosts
12
- * but on stock hosts some APIs silently deliver NOTHING: before 17.3.8 the
13
- * host drops the before_provider_request replacement on openai-completions /
14
- * bedrock / cursor (upstream can1357/oh-my-pi#8717, issue #83), and bedrock /
15
- * cursor bodies still have no codec path even on newer hosts. The unset
16
- * default already avoids all of this; only an explicit override can land
17
- * here, so surface why instead of failing silently (ework issue #3). */
18
- export declare function providerDeliveryWarning(adapter: Pick<AdapterConfig, "transformMode">, model: {
10
+ /** Compression is delivered only where the kernel has a codec for the wire
11
+ * body. On stock hosts the other APIs (bedrock / cursor / google / devin /
12
+ * unknown) have no codec path yet — the payload passes through untransformed
13
+ * and compression is silently a no-op. Surface why instead of failing
14
+ * silently (issue #83; kernel codecs tracked upstream). */
15
+ export declare function providerDeliveryWarning(model: {
19
16
  api?: string;
20
- } | undefined, hostVersion?: string): ProviderDeliveryWarning | undefined;
17
+ } | undefined): ProviderDeliveryWarning | undefined;
@@ -6,7 +6,6 @@ import type { AdapterConfig, CompressConfig, DelegateConfig } from "./config.js"
6
6
  export interface UserAcpConfig {
7
7
  debug?: boolean;
8
8
  autoUpdate?: boolean;
9
- transformMode?: "context" | "provider";
10
9
  modelContextLimit?: number;
11
10
  toolBashDefaultTimeout?: number;
12
11
  toolOutputMaxBytes?: number;
@@ -1,14 +1,27 @@
1
- import { type BiliMessage } from "acp-kernel/wire";
1
+ import { type BiliMessage, type MirrorMessage, type ResponsesProjection } from "acp-kernel/wire";
2
2
  import { type CompressionState, type Config, type CoreMessage } from "acp-kernel";
3
3
  import type { AgentMessage, BlockLike, StreamCompressCall } from "./messages.js";
4
- export type ProviderWireFormat = "anthropic" | "openai";
4
+ export type ProviderWireFormat = "anthropic" | "openai" | "responses";
5
5
  /** Kernel format detection narrowed to the formats the omp pipeline can
6
- * rebuild onto the wire. null = fail-open (pass the payload through). */
6
+ * rebuild onto the wire. null = fail-open (pass the payload through).
7
+ * The kernel's detectWireFormat only recognizes `input` arrays as
8
+ * "responses"; string inputs (a single user message) are also responses
9
+ * bodies (the kernel's responsesToCore handles them), so we add that case. */
7
10
  export declare function detectProviderWireFormat(payload: unknown): ProviderWireFormat | null;
8
11
  export declare function payloadToCore(payload: unknown, fmt: ProviderWireFormat): {
9
12
  msgs: BiliMessage[];
10
13
  cacheControls?: Map<string, unknown>;
14
+ systemText?: string;
11
15
  };
16
+ /** Parse a responses body into the kernel's projection (layout + core pieces).
17
+ * The projection is needed for the rebuild (patchResponsesInput) — it carries
18
+ * the original item layout so the round-trip preserves opaque items and
19
+ * patches text in place rather than rebuilding from scratch. */
20
+ export declare function responsesProjection(payload: unknown): ResponsesProjection;
21
+ /** Rebuild the responses `input` from the projection + transformed core
22
+ * messages. Returns a string when the original input was a string (and the
23
+ * transform kept it a single user text piece); otherwise an item array. */
24
+ export declare function responsesRebuild(projection: ResponsesProjection, msgs: BiliMessage[]): string | unknown[];
12
25
  export declare function coreToPayloadMessages(msgs: BiliMessage[], fmt: ProviderWireFormat, cacheControls?: Map<string, unknown>): unknown[];
13
26
  export type Representability = {
14
27
  ok: true;
@@ -29,6 +42,16 @@ export declare function payloadRepresentable(payload: unknown, fmt: ProviderWire
29
42
  * the details and flips "" back to null; this pass re-attaches both so the
30
43
  * post-surgery body keeps the host's wire contract. */
31
44
  export declare function restoreOpenaiWireFidelity(originalMessages: unknown[], rebuilt: unknown[]): unknown[];
45
+ /** Re-attach the leading system/developer messages the kernel hoisted out of
46
+ * the fold id space (acp-kernel 0.0.37). The rebuilt message list no longer
47
+ * carries them; without this pass, a compression covering the old system
48
+ * piece dropped the model's system prompt from the wire entirely (observed
49
+ * on glm-5.3: post-compression requests went from systemLen 45151 to 0).
50
+ * Original messages are re-attached verbatim so the host's wire shape —
51
+ * system vs developer roles, message count, name fields — survives
52
+ * byte-for-byte. Mirrors the anthropic path, where the top-level system
53
+ * field never enters the fold at all. */
54
+ export declare function restoreOpenaiSystemPrefix(originalMessages: unknown[], rebuilt: unknown[]): unknown[];
32
55
  export type WireTagRenderScope = {
33
56
  config: Config;
34
57
  tokenCount: number;
@@ -60,11 +83,6 @@ export declare function coreIdentity(msg: BiliMessage): string;
60
83
  * checks (compress results stay ref-BLOCKED) resolve the name here. */
61
84
  export declare function toolCallNames(msgs: BiliMessage[]): Map<string, string>;
62
85
  export declare function toolResultTextsCore(msgs: BiliMessage[]): Map<string, string>;
63
- /** Core-space twin of lastRejectedCompressPair (issue #104): the most recent
64
- * rejected compress call+result pair, re-appended to the wire output so the
65
- * model sees the outcome of its last attempt (hide-compress-calls strips
66
- * orphaned calls and their results). Null when no rejected call exists. */
67
- export declare function lastRejectedPairCore(msgs: BiliMessage[]): BiliMessage[] | null;
68
86
  /** Compress calls carried by a core tool-call piece. Same two shapes as the
69
87
  * AgentMessage stream (direct compress; legacy xd://compress via write),
70
88
  * with the arguments JSON-encoded in the piece's text. */
@@ -138,15 +156,21 @@ export declare function rangePositionsCore(ranges: Array<{
138
156
  startRef: string;
139
157
  endRef: string;
140
158
  }>, coreMessages: CoreMessage[], byRef: Record<string, string>, blocks: BlockLike[]): string[];
141
- /** Rebuild the WIRE-SHAPE projection of the persisted session (the mirror
142
- * of the host's convertToLlm for openai chat) and parse it with the kernel
143
- * codec, so primeFold (provider mode) folds exactly the space the live
144
- * provider requests fold: system prompt first (it takes m00001), one
145
- * tool-result piece per tool result, thinking dropped (issue #64). */
159
+ /** Map the persisted session view onto the kernel's neutral MirrorMessage:
160
+ * the only omp-side shape knowledge left in this module ref-tag
161
+ * stripping (a persisted-format concern, messages.ts) and the pi block
162
+ * types. Every wire-shape rule (system placement, reasoning_content vs
163
+ * thinking blocks vs summary_text, tool_result folding, whitespace
164
+ * handling) lives single-sourced in the acp-kernel mirror constructors
165
+ * (≥0.0.35, PR #114). */
166
+ export declare function toMirrorView(view: AgentMessage[]): MirrorMessage[];
167
+ /** primeFold openai/completions mirror (issue #64): system first, thinking
168
+ * as the `reasoning_content` field (issue #103); inline `<think>` hosts
169
+ * land in the same identity space via kernel normalization (PR #112). */
146
170
  export declare function viewToCoreStream(view: AgentMessage[], systemText: string): BiliMessage[];
147
- /** Anthropic-flavoured wire mirror for primeFold: the live anthropic
148
- * request carries the system prompt as the TOP-LEVEL `system` field (out
149
- * of the fold space) and folds tool results into user messages — mirror
150
- * exactly that, or the preview lands in a different ref space than the
151
- * live request (issue #64). */
171
+ /** primeFold anthropic/messages mirror (issue #64): system out of the fold
172
+ * space, tool results folded into user messages, signed thinking blocks. */
152
173
  export declare function viewToAnthropicCore(view: AgentMessage[]): BiliMessage[];
174
+ /** primeFold responses mirror (issue #64, responses variant): system in the
175
+ * top-level `instructions` field, conversation as the `input` item array. */
176
+ export declare function viewToResponsesCore(view: AgentMessage[], systemText: string): BiliMessage[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "billion-context-omp",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "One billion, not one million. Model-driven context management for the oh-my-pi (omp) coding agent.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -68,8 +68,7 @@
68
68
  "@oh-my-pi/pi-coding-agent": "17.3.8",
69
69
  "@oh-my-pi/pi-utils": "17.3.8",
70
70
  "@types/node": "^26.1.2",
71
- "acp-kernel": "0.0.31",
72
- "billion-context-kit": "0.2.0",
71
+ "acp-kernel": "0.0.41",
73
72
  "bun-types": "^1.3.14",
74
73
  "tsup": "^8.5.1",
75
74
  "tsx": "^4.23.1",