@hicaru/pi-rlm 0.2.2 → 0.3.0
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 +20 -16
- package/README.ru.md +2 -2
- package/README.zh-CN.md +2 -2
- package/package.json +22 -19
- package/src/bridge/add-context.ts +322 -0
- package/src/bridge/subcall-handlers.ts +1 -1
- package/src/config/defaults.ts +2 -1
- package/src/config/settings.ts +5 -2
- package/src/context/anydoc.ts +67 -0
- package/src/context/listing.ts +70 -0
- package/src/context/md-cache.ts +112 -0
- package/src/context/merge.ts +97 -0
- package/src/context/namespace.ts +180 -0
- package/src/context/resolve.ts +122 -0
- package/src/context/source-dir.ts +166 -0
- package/src/context/source-doc.ts +71 -0
- package/src/context/source-git.ts +51 -0
- package/src/context/source-text.ts +45 -0
- package/src/context/types.ts +88 -0
- package/src/context/walk.ts +250 -0
- package/src/core/engine.ts +15 -19
- package/src/core/types.ts +7 -2
- package/src/index.ts +69 -42
- package/src/mode/rlm-mode.ts +5 -4
- package/src/prompts/glossary.ts +31 -28
- package/src/prompts/native.ts +4 -4
- package/src/prompts/system.ts +2 -2
- package/src/sandbox/context-file.ts +4 -4
- package/src/sandbox/interrupts.ts +25 -10
- package/src/sandbox/protocol.ts +13 -7
- package/src/sandbox/py/__pycache__/guards.cpython-314.pyc +0 -0
- package/src/sandbox/py/__pycache__/retrieval.cpython-314.pyc +0 -0
- package/src/sandbox/py/__pycache__/tasks.cpython-314.pyc +0 -0
- package/src/sandbox/py/guards.py +1 -1
- package/src/sandbox/py/retrieval.py +1 -1
- package/src/sandbox/py/tasks.py +17 -4
- package/src/sandbox/py/worker.py +68 -48
- package/src/sandbox/sandbox-manager.ts +18 -16
- package/src/sandbox/sandbox.ts +1 -1
- package/src/text/tokens.ts +3 -3
- package/src/tool/repl-details.ts +1 -1
- package/src/tool/repl-tool.ts +31 -19
- package/src/tool/rlm-tool.ts +1 -1
- package/src/ui/config-panel.ts +8 -4
- package/src/bridge/library.ts +0 -190
- package/src/context/library-context.ts +0 -339
- package/src/context/repomix-context.ts +0 -204
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* repomix-context — pre-packs the entire codebase into a structured JSON array
|
|
3
|
-
* for the RLM sandbox. Replaces the legacy filesystem-tool context
|
|
4
|
-
* (buildProjectManifest / listProjectFiles / gitLsFiles).
|
|
5
|
-
*
|
|
6
|
-
* Uses repomix internally (worker-thread pool, built-in gitignore support)
|
|
7
|
-
* and caches results in a module-level Map with TTL to avoid re-packing on
|
|
8
|
-
* every run within the same process.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { pack } from "repomix";
|
|
12
|
-
import type { PackResult as RepomixPackResult } from "repomix";
|
|
13
|
-
/** repomix's own config parameter type — `satisfies` keeps the literal checked against it. */
|
|
14
|
-
type PackConfig = NonNullable<Parameters<typeof pack>[1]>;
|
|
15
|
-
import { resolve } from "node:path";
|
|
16
|
-
import { tmpdir } from "node:os";
|
|
17
|
-
import { errorMessage } from "../util/errors.ts";
|
|
18
|
-
import { estimateTokens } from "../text/tokens.ts";
|
|
19
|
-
|
|
20
|
-
// ── Public types ──
|
|
21
|
-
|
|
22
|
-
export interface ContextFile {
|
|
23
|
-
readonly path: string;
|
|
24
|
-
readonly content: string;
|
|
25
|
-
readonly tokens: number;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface ContextBundle {
|
|
29
|
-
readonly files: readonly ContextFile[];
|
|
30
|
-
readonly totalFiles: number;
|
|
31
|
-
readonly totalTokens: number;
|
|
32
|
-
readonly totalChars: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface PackSuccess {
|
|
36
|
-
readonly ok: true;
|
|
37
|
-
readonly value: ContextBundle;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface PackFailure {
|
|
41
|
-
readonly ok: false;
|
|
42
|
-
readonly error: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export type PackResult = PackSuccess | PackFailure;
|
|
46
|
-
|
|
47
|
-
// ── Module-level cache ──
|
|
48
|
-
|
|
49
|
-
interface CacheEntry {
|
|
50
|
-
readonly bundle: ContextBundle;
|
|
51
|
-
readonly ts: number;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const cache = new Map<string, CacheEntry>();
|
|
55
|
-
const DEFAULT_CACHE_TTL_MS = 30_000;
|
|
56
|
-
|
|
57
|
-
function cacheKey(cwd: string): string {
|
|
58
|
-
return resolve(cwd);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function cacheGet(key: string, ttlMs: number): ContextBundle | undefined {
|
|
62
|
-
const entry = cache.get(key);
|
|
63
|
-
if (!entry) return undefined;
|
|
64
|
-
if (Date.now() - entry.ts > ttlMs) {
|
|
65
|
-
cache.delete(key);
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
return entry.bundle;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function cacheSet(key: string, bundle: ContextBundle): void {
|
|
72
|
-
cache.set(key, { bundle, ts: Date.now() });
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ── Core functions ──
|
|
76
|
-
|
|
77
|
-
export async function packRepository(
|
|
78
|
-
cwd: string,
|
|
79
|
-
signal?: AbortSignal,
|
|
80
|
-
ttlMs: number = DEFAULT_CACHE_TTL_MS,
|
|
81
|
-
): Promise<PackResult> {
|
|
82
|
-
if (signal?.aborted) return { ok: false, error: "aborted" };
|
|
83
|
-
|
|
84
|
-
const key = cacheKey(cwd);
|
|
85
|
-
const cached = cacheGet(key, ttlMs);
|
|
86
|
-
if (cached) return { ok: true, value: cached };
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
const result: RepomixPackResult = await Promise.race([
|
|
90
|
-
pack([cwd], {
|
|
91
|
-
input: { maxFileSize: 1048576 },
|
|
92
|
-
cwd,
|
|
93
|
-
output: {
|
|
94
|
-
filePath: `${tmpdir()}/repomix-out-${Date.now()}.txt`,
|
|
95
|
-
style: "plain",
|
|
96
|
-
filePathStyle: "cwd-relative",
|
|
97
|
-
parsableStyle: false,
|
|
98
|
-
headerText: undefined,
|
|
99
|
-
instructionFilePath: undefined,
|
|
100
|
-
fileSummary: false,
|
|
101
|
-
directoryStructure: false,
|
|
102
|
-
files: true,
|
|
103
|
-
removeComments: false,
|
|
104
|
-
removeEmptyLines: false,
|
|
105
|
-
compress: false,
|
|
106
|
-
topFilesLength: 5,
|
|
107
|
-
showLineNumbers: false,
|
|
108
|
-
truncateBase64: false,
|
|
109
|
-
copyToClipboard: false,
|
|
110
|
-
includeEmptyDirectories: undefined,
|
|
111
|
-
includeFullDirectoryStructure: false,
|
|
112
|
-
splitOutput: undefined,
|
|
113
|
-
tokenCountTree: false,
|
|
114
|
-
tokenBudget: undefined,
|
|
115
|
-
git: {
|
|
116
|
-
sortByChanges: true,
|
|
117
|
-
sortByChangesMaxCommits: 100,
|
|
118
|
-
includeDiffs: false,
|
|
119
|
-
includeLogs: false,
|
|
120
|
-
includeLogsCount: 50,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
include: [],
|
|
124
|
-
ignore: {
|
|
125
|
-
useGitignore: true,
|
|
126
|
-
useDotIgnore: true,
|
|
127
|
-
useDefaultPatterns: true,
|
|
128
|
-
customPatterns: [],
|
|
129
|
-
},
|
|
130
|
-
security: { enableSecurityCheck: false },
|
|
131
|
-
tokenCount: { encoding: "o200k_base" as const },
|
|
132
|
-
} satisfies PackConfig),
|
|
133
|
-
new Promise<never>((_, reject) => {
|
|
134
|
-
signal?.addEventListener("abort", () => reject(new Error("aborted")), { once: true });
|
|
135
|
-
}),
|
|
136
|
-
]);
|
|
137
|
-
|
|
138
|
-
const processedFiles = result.processedFiles;
|
|
139
|
-
const files = new Array<ContextFile>(processedFiles.length);
|
|
140
|
-
const tokenCounts = result.fileTokenCounts;
|
|
141
|
-
let totalTokens = 0;
|
|
142
|
-
let totalChars = 0;
|
|
143
|
-
|
|
144
|
-
for (let i = 0; i < processedFiles.length; i++) {
|
|
145
|
-
const file = processedFiles[i];
|
|
146
|
-
const tokens = tokenCounts[file.path] ?? estimateTokens(file.content.length);
|
|
147
|
-
files[i] = { path: file.path, content: file.content, tokens };
|
|
148
|
-
totalTokens += tokens;
|
|
149
|
-
totalChars += file.content.length;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const bundle: ContextBundle = {
|
|
153
|
-
files,
|
|
154
|
-
totalFiles: files.length,
|
|
155
|
-
totalTokens,
|
|
156
|
-
totalChars,
|
|
157
|
-
};
|
|
158
|
-
cacheSet(key, bundle);
|
|
159
|
-
return { ok: true, value: bundle };
|
|
160
|
-
} catch (err: unknown) {
|
|
161
|
-
if (signal?.aborted) return { ok: false, error: "aborted" };
|
|
162
|
-
return {
|
|
163
|
-
ok: false,
|
|
164
|
-
error: errorMessage(err),
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function serializeForSandbox(
|
|
170
|
-
bundle: ContextBundle,
|
|
171
|
-
): readonly ContextFile[] {
|
|
172
|
-
return bundle.files;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/** Maximum files shown in the compact LLM listing before truncation. */
|
|
176
|
-
const MAX_LLM_LISTING_FILES = 200;
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Produces a compact human-readable text block for the parent LLM's context window.
|
|
180
|
-
* Shows file paths and token estimates — NOT full file contents (those are too large
|
|
181
|
-
* for the context window). The LLM inspects files via repl() over the pre-loaded context variable.
|
|
182
|
-
*/
|
|
183
|
-
export function formatForLLM(bundle: ContextBundle): string {
|
|
184
|
-
const files = bundle.files.slice(0, MAX_LLM_LISTING_FILES);
|
|
185
|
-
const truncated = bundle.totalFiles > MAX_LLM_LISTING_FILES
|
|
186
|
-
? `... and ${bundle.totalFiles - MAX_LLM_LISTING_FILES} more files (truncated)`
|
|
187
|
-
: "";
|
|
188
|
-
|
|
189
|
-
const listing = files.map((f) =>
|
|
190
|
-
`${f.path} (${f.tokens.toLocaleString()} tok, ${f.content.length.toLocaleString()} chars)`,
|
|
191
|
-
).join("\n");
|
|
192
|
-
|
|
193
|
-
return [
|
|
194
|
-
`Repository context: ${bundle.totalFiles.toLocaleString()} files, ${bundle.totalTokens.toLocaleString()} estimated tokens, ${bundle.totalChars.toLocaleString()} total characters.`,
|
|
195
|
-
"",
|
|
196
|
-
listing,
|
|
197
|
-
truncated,
|
|
198
|
-
"",
|
|
199
|
-
"All file contents are pre-loaded in the REPL `context` variable — file-reading tools are disabled.",
|
|
200
|
-
"Use repl({code}) and delegate semantic reading to llm_query / llm_query_batched / llm_query_chunked.",
|
|
201
|
-
].join("\n");
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|