billion-context-omp 0.1.0 → 0.1.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/README.md +168 -30
- package/README.zh-CN.md +168 -30
- package/dist/auto-compress.d.ts +65 -0
- package/dist/commands.d.ts +8 -0
- package/dist/compat.d.ts +24 -0
- package/dist/compress-tool.d.ts +27 -0
- package/dist/config.d.ts +92 -0
- package/dist/decompress-tool.d.ts +15 -0
- package/dist/dump.d.ts +22 -0
- package/dist/footer-status.d.ts +2 -0
- package/dist/home.d.ts +2 -0
- package/dist/index.d.ts +5 -59
- package/dist/index.js +4760 -43
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +21 -0
- package/dist/messages.d.ts +65 -0
- package/dist/runtime.d.ts +34 -0
- package/dist/search-index.d.ts +18 -0
- package/dist/search-tool.d.ts +11 -0
- package/dist/status-tool.d.ts +17 -0
- package/dist/system-prompt.d.ts +2 -0
- package/dist/tokens.d.ts +16 -0
- package/dist/tool-guardrails.d.ts +13 -0
- package/dist/update.d.ts +2 -0
- package/dist/user-config.d.ts +26 -0
- package/package.json +74 -65
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare function setDebugEnabled(enabled: boolean): void;
|
|
2
|
+
export type LogLevel = "error" | "warn" | "info" | "debug";
|
|
3
|
+
/** No-op: writeLine uses appendFileSync (stateless per call), so there is no
|
|
4
|
+
* stream to close. Kept as a hook in case the backend switches to a
|
|
5
|
+
* persistent write stream. Called on session_shutdown. */
|
|
6
|
+
export declare function closeLogStream(): void;
|
|
7
|
+
export declare function logError(scope: string, fields: Record<string, unknown>): void;
|
|
8
|
+
export declare function logWarn(scope: string, fields: Record<string, unknown>): void;
|
|
9
|
+
export declare function logInfo(scope: string, fields: Record<string, unknown>): void;
|
|
10
|
+
export declare function logThrow(scope: string, err: unknown, extra?: Record<string, unknown>): void;
|
|
11
|
+
export declare const debug: {
|
|
12
|
+
readonly enabled: boolean;
|
|
13
|
+
readonly logFile: string;
|
|
14
|
+
event(scope: string, fields: Record<string, unknown>): void;
|
|
15
|
+
};
|
|
16
|
+
export declare const logger: {
|
|
17
|
+
error: typeof logError;
|
|
18
|
+
warn: typeof logWarn;
|
|
19
|
+
info: typeof logInfo;
|
|
20
|
+
debug(scope: string, fields: Record<string, unknown>): void;
|
|
21
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SessionEntry, SessionMessageEntry } from "@oh-my-pi/pi-coding-agent";
|
|
2
|
+
import type { CoreMessage } from "acp-kernel";
|
|
3
|
+
type AgentMessage = SessionMessageEntry["message"];
|
|
4
|
+
export type { AgentMessage };
|
|
5
|
+
export declare function entriesToCoreMessages(entries: SessionEntry[]): CoreMessage[];
|
|
6
|
+
export declare function streamToCoreMessages(stream: AgentMessage[]): CoreMessage[];
|
|
7
|
+
/** Map of toolCallId → result text for tool results in the stream. Used to
|
|
8
|
+
* skip replaying compress calls that were REJECTED live ("No changes
|
|
9
|
+
* applied") — only calls that actually created blocks should rebuild them. */
|
|
10
|
+
export declare function toolResultTexts(stream: AgentMessage[]): Map<string, string>;
|
|
11
|
+
export interface StreamCompressCall {
|
|
12
|
+
id: string;
|
|
13
|
+
ranges: {
|
|
14
|
+
startRef: string;
|
|
15
|
+
endRef: string;
|
|
16
|
+
summary: string;
|
|
17
|
+
topic?: string;
|
|
18
|
+
summaryMaxChars?: number;
|
|
19
|
+
compressCallId: string;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
export declare function findCompressCalls(message: AgentMessage): StreamCompressCall[];
|
|
23
|
+
export declare function extractText(content: unknown): string;
|
|
24
|
+
export declare function messageIdentity(message: unknown): string;
|
|
25
|
+
export declare function matchesStoredText(stored: string, visible: string): boolean;
|
|
26
|
+
export declare function coreOutToAgentMessages(coreOut: CoreMessage[], originalById: Map<string, AgentMessage>): AgentMessage[];
|
|
27
|
+
/** 1-based stream position encoded in a p-id ("p7" | "p7#tc1" → 7). */
|
|
28
|
+
export declare function rawPos(rawId: string): number;
|
|
29
|
+
/** Stable fingerprint of a covered span, computed from the deterministic core
|
|
30
|
+
* projection: hash of the first and last covered CoreMessages' content
|
|
31
|
+
* fields. Written into the compress tool's success result (which lives in
|
|
32
|
+
* the stream) and re-verified on fold replay — if a host-side rewrite
|
|
33
|
+
* (compaction, edit) shifted positions, the fingerprint mismatches and the
|
|
34
|
+
* call is skipped instead of silently compressing the wrong messages.
|
|
35
|
+
* Boundaries bind to the EXACT piece the ref names (parallel tool calls
|
|
36
|
+
* split one stream message into several pieces sharing a position —
|
|
37
|
+
* hashing "whatever is at that position" is position-collision-fragile). */
|
|
38
|
+
export declare function spanFingerprint(coreMessages: CoreMessage[], startId: string, endId: string): string;
|
|
39
|
+
export interface BlockLike {
|
|
40
|
+
blockId: string;
|
|
41
|
+
effectiveMessageIds: string[];
|
|
42
|
+
}
|
|
43
|
+
export declare function isBlockRef(ref: string): boolean;
|
|
44
|
+
/** Resolve a range boundary ref to the EXACT raw id of the piece it names.
|
|
45
|
+
* Message refs (mNNNNN) go through byRef; block refs (bN) resolve to the
|
|
46
|
+
* earliest (min) or latest (max) covered message's raw id. "" = unresolved. */
|
|
47
|
+
export declare function boundaryRaw(ref: string, byRef: Record<string, string>, blocks: BlockLike[], pick: "min" | "max"): string;
|
|
48
|
+
/** Ranges too small to carry a meaningful summary (kernel minSummaryLength
|
|
49
|
+
* is 50 chars; a 16-token message can't support one and nets a LOSS). The
|
|
50
|
+
* "compress all ranges in one call" nudge hint makes listing them a trap:
|
|
51
|
+
* the model bundles them, the batch fails atomically, nothing gets applied
|
|
52
|
+
* (observed live: 14-range batch rejected by a 43-char summary on a
|
|
53
|
+
* 16-token range). 200 tokens ≈ 800 chars of substance — comfortably above
|
|
54
|
+
* the summary floor while still listing every genuinely compressible range. */
|
|
55
|
+
export declare const VIABLE_RANGE_MIN_TOKENS = 200;
|
|
56
|
+
export declare function viableRanges<T extends {
|
|
57
|
+
tokens: number;
|
|
58
|
+
}>(ranges: T[]): T[];
|
|
59
|
+
/** One fingerprint per range (never filtered, "-" for unresolvable
|
|
60
|
+
* boundaries) so replay-side index lookup stays aligned even for mixed
|
|
61
|
+
* message/block boundary batches. Written into the compress tool result. */
|
|
62
|
+
export declare function rangeFingerprints(ranges: Array<{
|
|
63
|
+
startRef: string;
|
|
64
|
+
endRef: string;
|
|
65
|
+
}>, coreMessages: CoreMessage[], byRef: Record<string, string>, blocks: BlockLike[]): string[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@oh-my-pi/pi-coding-agent";
|
|
2
|
+
import { type CompressionCore, type CompressionState, type Config, type CoreMessage, type Prompts } from "acp-kernel";
|
|
3
|
+
import { type AdapterConfig } from "./config.js";
|
|
4
|
+
import { type AgentMessage } from "./messages.js";
|
|
5
|
+
export interface FoldResult {
|
|
6
|
+
state: CompressionState;
|
|
7
|
+
coreMessages: CoreMessage[];
|
|
8
|
+
originalById: Map<string, AgentMessage>;
|
|
9
|
+
streamLen: number;
|
|
10
|
+
}
|
|
11
|
+
export interface AcpRuntime {
|
|
12
|
+
core: CompressionCore;
|
|
13
|
+
adapter: AdapterConfig;
|
|
14
|
+
setAdapter(adapter: AdapterConfig): void;
|
|
15
|
+
prompts: Prompts;
|
|
16
|
+
setPrompts(prompts: Prompts): void;
|
|
17
|
+
liveContextLimit(ctx: ExtensionContext): number;
|
|
18
|
+
configFor(ctx: ExtensionContext): Config;
|
|
19
|
+
foldStream(ctx: ExtensionContext, stream: AgentMessage[]): FoldResult;
|
|
20
|
+
stateFor(ctx: ExtensionContext): Promise<{
|
|
21
|
+
state: CompressionState;
|
|
22
|
+
coreMessages: CoreMessage[];
|
|
23
|
+
}>;
|
|
24
|
+
commitFoldState(ctx: ExtensionContext, state: CompressionState, toolCallId?: string): void;
|
|
25
|
+
forgetSession(sid: string): void;
|
|
26
|
+
/** Rebuild blocks from the persisted session view at session_start so /acp
|
|
27
|
+
* and acp_status show them BEFORE the first LLM call of a resumed session.
|
|
28
|
+
* The slot is marked preview and always re-folded authoritatively at the
|
|
29
|
+
* first context event (the live stream is the truth source, not the
|
|
30
|
+
* persisted view). */
|
|
31
|
+
primeFold(ctx: ExtensionContext): void;
|
|
32
|
+
acquireLock(sid: string): Promise<() => void>;
|
|
33
|
+
}
|
|
34
|
+
export declare function createRuntime(adapter: AdapterConfig): AcpRuntime;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search index — bridges pi's session log into acp-kernel's search.
|
|
3
|
+
*
|
|
4
|
+
* Builds SearchDoc[] from:
|
|
5
|
+
* 1. All compression blocks (active AND inactive) — via blockDocs()
|
|
6
|
+
* 2. Historical messages that compression folded into a block summary.
|
|
7
|
+
*
|
|
8
|
+
* Which messages are searchable? Those covered by SOME block's
|
|
9
|
+
* effectiveMessageIds — i.e. messages that were compressed into a summary and
|
|
10
|
+
* are no longer individually visible. Messages still live in context (not in
|
|
11
|
+
* any block) are skipped: the model can already see them.
|
|
12
|
+
*
|
|
13
|
+
* We deliberately do NOT use pi's buildContextEntries for the visible check:
|
|
14
|
+
* ACP prunes messages itself (no pi `compaction` entry is written), so pi
|
|
15
|
+
* reports ALL entries as in-context. The ACP state is the source of truth.
|
|
16
|
+
*/
|
|
17
|
+
import { type CompressionState, type CoreMessage, type SearchDoc } from "acp-kernel";
|
|
18
|
+
export declare function buildSearchDocs(coreMessages: CoreMessage[], state: CompressionState): SearchDoc[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@oh-my-pi/pi-coding-agent";
|
|
2
|
+
import type { AcpRuntime } from "./runtime.js";
|
|
3
|
+
declare const SearchParams: import("@oh-my-pi/omptype").FluentType<{
|
|
4
|
+
limit?: number | undefined;
|
|
5
|
+
query: string;
|
|
6
|
+
}, {
|
|
7
|
+
limit?: number | undefined;
|
|
8
|
+
query: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function makeSearchTool(runtime: AcpRuntime): ToolDefinition<typeof SearchParams>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@oh-my-pi/pi-coding-agent";
|
|
2
|
+
import type { AcpRuntime } from "./runtime.js";
|
|
3
|
+
declare const StatusParams: import("@oh-my-pi/omptype").FluentType<{
|
|
4
|
+
limit?: number | undefined;
|
|
5
|
+
scope?: "compressed" | "uncompressed" | undefined;
|
|
6
|
+
sort?: "age" | "size" | "time" | "tool" | undefined;
|
|
7
|
+
tool?: string | undefined;
|
|
8
|
+
view?: "messages" | "ranges" | undefined;
|
|
9
|
+
}, {
|
|
10
|
+
limit?: number | undefined;
|
|
11
|
+
scope?: "compressed" | "uncompressed" | undefined;
|
|
12
|
+
sort?: "age" | "size" | "time" | "tool" | undefined;
|
|
13
|
+
tool?: string | undefined;
|
|
14
|
+
view?: "messages" | "ranges" | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function makeStatusTool(runtime: AcpRuntime): ToolDefinition<typeof StatusParams>;
|
|
17
|
+
export {};
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type CoreMessage } from "acp-kernel";
|
|
2
|
+
export declare function estimateTextTokens(text: string): number;
|
|
3
|
+
export declare function collectCoveredMessageIds(state: {
|
|
4
|
+
blocks: {
|
|
5
|
+
active: boolean;
|
|
6
|
+
effectiveMessageIds: string[];
|
|
7
|
+
}[];
|
|
8
|
+
}): Set<string>;
|
|
9
|
+
export declare function estimateTokens(messages: CoreMessage[], coveredIds?: Set<string>): number;
|
|
10
|
+
export declare function lastUserMessageId(entries: {
|
|
11
|
+
id: string;
|
|
12
|
+
message?: {
|
|
13
|
+
role?: string;
|
|
14
|
+
};
|
|
15
|
+
}[]): string | undefined;
|
|
16
|
+
export declare function formatTokens(n: number): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ExtensionAPI, type ToolResultEvent } from "@oh-my-pi/pi-coding-agent";
|
|
2
|
+
import type { AcpRuntime } from "./runtime.js";
|
|
3
|
+
export type BashToolResultEvent = Extract<ToolResultEvent, {
|
|
4
|
+
toolName: "bash";
|
|
5
|
+
}>;
|
|
6
|
+
export declare function isBashToolResult(e: ToolResultEvent): e is BashToolResultEvent;
|
|
7
|
+
export declare function resolveBashTimeout(input: {
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}, defaultTimeout: number | undefined): number | undefined;
|
|
10
|
+
export declare function capToolOutput(content: ToolResultEvent["content"], maxBytes: number | undefined, fullPath?: string): ToolResultEvent["content"] | undefined;
|
|
11
|
+
export declare function detectBashTimeout(content: ToolResultEvent["content"]): number | undefined;
|
|
12
|
+
export declare function appendTimeoutNotice(content: ToolResultEvent["content"], secs: number): ToolResultEvent["content"];
|
|
13
|
+
export declare function wireToolGuardrails(pi: ExtensionAPI, runtime: AcpRuntime): void;
|
package/dist/update.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Prompts } from "acp-kernel";
|
|
2
|
+
import type { AdapterConfig, CompressConfig, DelegateConfig } from "./config.js";
|
|
3
|
+
/** User-facing config keys (subset of AdapterConfig). Loaded from
|
|
4
|
+
* ~/.<CONFIG_DIR_NAME>/acp-omp.json (global) and <cwd>/.<CONFIG_DIR_NAME>/acp-omp.json
|
|
5
|
+
* (project-local overrides project-global). Project wins over global. */
|
|
6
|
+
export interface UserAcpConfig {
|
|
7
|
+
debug?: boolean;
|
|
8
|
+
autoUpdate?: boolean;
|
|
9
|
+
modelContextLimit?: number;
|
|
10
|
+
toolBashDefaultTimeout?: number;
|
|
11
|
+
toolOutputMaxBytes?: number;
|
|
12
|
+
delegate?: boolean | DelegateConfig;
|
|
13
|
+
compress?: CompressConfig;
|
|
14
|
+
displayUsage?: "merged" | "separate";
|
|
15
|
+
prompts?: Partial<Prompts>;
|
|
16
|
+
/** Model for /compact summaries, as "provider:modelId" (e.g.
|
|
17
|
+
* "zhipuai:glm-5.2"). Shortcut for compress.compressModel — normalized
|
|
18
|
+
* into the nested path at load time. */
|
|
19
|
+
compressModel?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Read global + project acp-omp.json, project overrides global. Returns {} on any
|
|
22
|
+
* error (missing file, bad JSON) — never throws. */
|
|
23
|
+
export declare function loadUserConfig(cwd: string): Promise<UserAcpConfig>;
|
|
24
|
+
/** Merge user config onto an adapter config: user config wins for the keys it
|
|
25
|
+
* sets. Used at session_start to apply runtime-discovered config. */
|
|
26
|
+
export declare function applyUserConfig(adapter: AdapterConfig, user: UserAcpConfig): AdapterConfig;
|
package/package.json
CHANGED
|
@@ -1,67 +1,76 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
2
|
+
"name": "billion-context-omp",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "One billion, not one million. Model-driven context management for the oh-my-pi (omp) coding agent.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"omp": {
|
|
14
|
+
"extensions": [
|
|
15
|
+
"./dist/index.js"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"README.zh-CN.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"homepage": "https://github.com/ranxianglei/billion-context-omp",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/ranxianglei/billion-context-omp.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/ranxianglei/billion-context-omp/issues"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"test": "bun scripts/test.ts",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"typecheck:tests": "tsc --noEmit -p tsconfig.test.json",
|
|
43
|
+
"typecheck:all": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
44
|
+
"build": "tsup && tsc --emitDeclarationOnly"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"pi",
|
|
48
|
+
"omp",
|
|
49
|
+
"oh-my-pi",
|
|
50
|
+
"acp",
|
|
51
|
+
"context",
|
|
52
|
+
"compression",
|
|
53
|
+
"context-management",
|
|
54
|
+
"llm",
|
|
55
|
+
"pi-package"
|
|
56
|
+
],
|
|
57
|
+
"author": "ranxianglei",
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"type": "module",
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"@oh-my-pi/pi-coding-agent": ">=17.0.0",
|
|
62
|
+
"@oh-my-pi/omptype": ">=17.0.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@oh-my-pi/omptype": "17.3.2",
|
|
66
|
+
"@oh-my-pi/pi-agent-core": "17.3.2",
|
|
67
|
+
"@oh-my-pi/pi-ai": "17.3.2",
|
|
68
|
+
"@oh-my-pi/pi-coding-agent": "17.3.2",
|
|
69
|
+
"@oh-my-pi/pi-utils": "17.3.2",
|
|
70
|
+
"@types/node": "^26.1.2",
|
|
71
|
+
"acp-kernel": "0.0.22",
|
|
72
|
+
"tsup": "^8.5.1",
|
|
73
|
+
"tsx": "^4.23.1",
|
|
74
|
+
"typescript": "^7.0.2"
|
|
75
|
+
}
|
|
67
76
|
}
|