contextos-mcp 0.4.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/LICENSE +21 -0
- package/README.md +260 -0
- package/bin/mcp.mjs +61 -0
- package/bin/swarm.mjs +45 -0
- package/dist/agents/aider.d.ts +12 -0
- package/dist/agents/aider.js +192 -0
- package/dist/agents/aider.js.map +1 -0
- package/dist/agents/claude-code.d.ts +9 -0
- package/dist/agents/claude-code.js +236 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/codex.d.ts +14 -0
- package/dist/agents/codex.js +203 -0
- package/dist/agents/codex.js.map +1 -0
- package/dist/agents/direct-llm.d.ts +22 -0
- package/dist/agents/direct-llm.js +254 -0
- package/dist/agents/direct-llm.js.map +1 -0
- package/dist/agents/mock.d.ts +10 -0
- package/dist/agents/mock.js +170 -0
- package/dist/agents/mock.js.map +1 -0
- package/dist/agents/opencode.d.ts +23 -0
- package/dist/agents/opencode.js +631 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/provider.d.ts +11 -0
- package/dist/agents/provider.js +31 -0
- package/dist/agents/provider.js.map +1 -0
- package/dist/compression/compressor.d.ts +28 -0
- package/dist/compression/compressor.js +268 -0
- package/dist/compression/compressor.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/contextos/loader.d.ts +46 -0
- package/dist/contextos/loader.js +120 -0
- package/dist/contextos/loader.js.map +1 -0
- package/dist/contextos/selector.d.ts +46 -0
- package/dist/contextos/selector.js +80 -0
- package/dist/contextos/selector.js.map +1 -0
- package/dist/core/action-dispatcher.d.ts +15 -0
- package/dist/core/action-dispatcher.js +28 -0
- package/dist/core/action-dispatcher.js.map +1 -0
- package/dist/core/action-schema.d.ts +72 -0
- package/dist/core/action-schema.js +86 -0
- package/dist/core/action-schema.js.map +1 -0
- package/dist/core/repl-interface.d.ts +48 -0
- package/dist/core/repl-interface.js +5 -0
- package/dist/core/repl-interface.js.map +1 -0
- package/dist/core/repl.d.ts +59 -0
- package/dist/core/repl.js +353 -0
- package/dist/core/repl.js.map +1 -0
- package/dist/core/rlm.d.ts +65 -0
- package/dist/core/rlm.js +564 -0
- package/dist/core/rlm.js.map +1 -0
- package/dist/core/runtime.py +470 -0
- package/dist/core/types.d.ts +265 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +75 -0
- package/dist/env.js.map +1 -0
- package/dist/hooks/runner.d.ts +43 -0
- package/dist/hooks/runner.js +173 -0
- package/dist/hooks/runner.js.map +1 -0
- package/dist/labs/cli.d.ts +15 -0
- package/dist/labs/cli.js +295 -0
- package/dist/labs/cli.js.map +1 -0
- package/dist/labs/episodic-memory.d.ts +132 -0
- package/dist/labs/episodic-memory.js +391 -0
- package/dist/labs/episodic-memory.js.map +1 -0
- package/dist/labs/interactive-swarm.d.ts +20 -0
- package/dist/labs/interactive-swarm.js +1173 -0
- package/dist/labs/interactive-swarm.js.map +1 -0
- package/dist/labs/interactive.d.ts +10 -0
- package/dist/labs/interactive.js +2099 -0
- package/dist/labs/interactive.js.map +1 -0
- package/dist/labs/ts-analyzer.d.ts +74 -0
- package/dist/labs/ts-analyzer.js +379 -0
- package/dist/labs/ts-analyzer.js.map +1 -0
- package/dist/labs/viewer.d.ts +12 -0
- package/dist/labs/viewer.js +1284 -0
- package/dist/labs/viewer.js.map +1 -0
- package/dist/main.d.ts +15 -0
- package/dist/main.js +247 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/server.d.ts +16 -0
- package/dist/mcp/server.js +192775 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +117 -0
- package/dist/mcp/session.js +450 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/state.d.ts +42 -0
- package/dist/mcp/state.js +537 -0
- package/dist/mcp/state.js.map +1 -0
- package/dist/mcp/tools/contextos.d.ts +17 -0
- package/dist/mcp/tools/contextos.js +583 -0
- package/dist/mcp/tools/contextos.js.map +1 -0
- package/dist/mcp/tools.d.ts +15 -0
- package/dist/mcp/tools.js +393 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/orchestration/reviewer-gate.d.ts +43 -0
- package/dist/orchestration/reviewer-gate.js +280 -0
- package/dist/orchestration/reviewer-gate.js.map +1 -0
- package/dist/orchestration/reviewer-prompt.d.ts +18 -0
- package/dist/orchestration/reviewer-prompt.js +67 -0
- package/dist/orchestration/reviewer-prompt.js.map +1 -0
- package/dist/orchestration/verification-runner.d.ts +53 -0
- package/dist/orchestration/verification-runner.js +352 -0
- package/dist/orchestration/verification-runner.js.map +1 -0
- package/dist/plugins/adapter.d.ts +11 -0
- package/dist/plugins/adapter.js +11 -0
- package/dist/plugins/adapter.js.map +1 -0
- package/dist/plugins/core/archive.d.ts +9 -0
- package/dist/plugins/core/archive.js +128 -0
- package/dist/plugins/core/archive.js.map +1 -0
- package/dist/plugins/core/digest.d.ts +11 -0
- package/dist/plugins/core/digest.js +70 -0
- package/dist/plugins/core/digest.js.map +1 -0
- package/dist/plugins/core/grants.d.ts +22 -0
- package/dist/plugins/core/grants.js +90 -0
- package/dist/plugins/core/grants.js.map +1 -0
- package/dist/plugins/core/index.d.ts +10 -0
- package/dist/plugins/core/index.js +11 -0
- package/dist/plugins/core/index.js.map +1 -0
- package/dist/plugins/core/pinning.d.ts +15 -0
- package/dist/plugins/core/pinning.js +86 -0
- package/dist/plugins/core/pinning.js.map +1 -0
- package/dist/plugins/core/types.d.ts +105 -0
- package/dist/plugins/core/types.js +22 -0
- package/dist/plugins/core/types.js.map +1 -0
- package/dist/plugins/core/updater.d.ts +16 -0
- package/dist/plugins/core/updater.js +64 -0
- package/dist/plugins/core/updater.js.map +1 -0
- package/dist/plugins/loader.d.ts +65 -0
- package/dist/plugins/loader.js +110 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/prompts/orchestrator.d.ts +6 -0
- package/dist/prompts/orchestrator.js +114 -0
- package/dist/prompts/orchestrator.js.map +1 -0
- package/dist/routing/model-resolver.d.ts +27 -0
- package/dist/routing/model-resolver.js +265 -0
- package/dist/routing/model-resolver.js.map +1 -0
- package/dist/routing/model-router.d.ts +130 -0
- package/dist/routing/model-router.js +515 -0
- package/dist/routing/model-router.js.map +1 -0
- package/dist/runtime/attestations.cjs +260 -0
- package/dist/runtime/reviewer-pipeline.cjs +319 -0
- package/dist/runtime/sandbox.cjs +468 -0
- package/dist/runtime/state-machine.cjs +885 -0
- package/dist/runtime/thread-store.cjs +175 -0
- package/dist/runtime/transactional-git.cjs +315 -0
- package/dist/runtime/verification-pipeline.cjs +435 -0
- package/dist/sandbox/execution.d.ts +165 -0
- package/dist/sandbox/execution.js +497 -0
- package/dist/sandbox/execution.js.map +1 -0
- package/dist/security/file-policy.d.ts +22 -0
- package/dist/security/file-policy.js +53 -0
- package/dist/security/file-policy.js.map +1 -0
- package/dist/security/repository-boundary.d.ts +21 -0
- package/dist/security/repository-boundary.js +119 -0
- package/dist/security/repository-boundary.js.map +1 -0
- package/dist/security/secret-filter.d.ts +36 -0
- package/dist/security/secret-filter.js +149 -0
- package/dist/security/secret-filter.js.map +1 -0
- package/dist/swarm.d.ts +14 -0
- package/dist/swarm.js +624 -0
- package/dist/swarm.js.map +1 -0
- package/dist/threads/cache.d.ts +64 -0
- package/dist/threads/cache.js +241 -0
- package/dist/threads/cache.js.map +1 -0
- package/dist/threads/manager.d.ts +94 -0
- package/dist/threads/manager.js +914 -0
- package/dist/threads/manager.js.map +1 -0
- package/dist/ui/banner.d.ts +14 -0
- package/dist/ui/banner.js +42 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/dashboard.d.ts +33 -0
- package/dist/ui/dashboard.js +135 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/index.d.ts +11 -0
- package/dist/ui/index.js +12 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/log.d.ts +39 -0
- package/dist/ui/log.js +126 -0
- package/dist/ui/log.js.map +1 -0
- package/dist/ui/onboarding.d.ts +14 -0
- package/dist/ui/onboarding.js +755 -0
- package/dist/ui/onboarding.js.map +1 -0
- package/dist/ui/run-log.d.ts +50 -0
- package/dist/ui/run-log.js +60 -0
- package/dist/ui/run-log.js.map +1 -0
- package/dist/ui/spinner.d.ts +41 -0
- package/dist/ui/spinner.js +172 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/streaming-feed.d.ts +72 -0
- package/dist/ui/streaming-feed.js +386 -0
- package/dist/ui/streaming-feed.js.map +1 -0
- package/dist/ui/summary.d.ts +18 -0
- package/dist/ui/summary.js +113 -0
- package/dist/ui/summary.js.map +1 -0
- package/dist/ui/text-input.d.ts +19 -0
- package/dist/ui/text-input.js +266 -0
- package/dist/ui/text-input.js.map +1 -0
- package/dist/ui/theme.d.ts +63 -0
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/command-exists.d.ts +11 -0
- package/dist/utils/command-exists.js +41 -0
- package/dist/utils/command-exists.js.map +1 -0
- package/dist/utils/process-security.d.ts +19 -0
- package/dist/utils/process-security.js +90 -0
- package/dist/utils/process-security.js.map +1 -0
- package/dist/utils/rolling-buffer.d.ts +16 -0
- package/dist/utils/rolling-buffer.js +30 -0
- package/dist/utils/rolling-buffer.js.map +1 -0
- package/dist/utils/safe-spawn.d.ts +13 -0
- package/dist/utils/safe-spawn.js +49 -0
- package/dist/utils/safe-spawn.js.map +1 -0
- package/dist/worktree/manager.d.ts +69 -0
- package/dist/worktree/manager.js +593 -0
- package/dist/worktree/manager.js.map +1 -0
- package/dist/worktree/merge.d.ts +58 -0
- package/dist/worktree/merge.js +389 -0
- package/dist/worktree/merge.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent Python REPL manager for swarm-code.
|
|
3
|
+
*
|
|
4
|
+
* Spawns a single Python subprocess running `runtime.py` and keeps it alive
|
|
5
|
+
* across multiple RLM iterations. Communication uses line-delimited JSON
|
|
6
|
+
* over stdin/stdout.
|
|
7
|
+
*
|
|
8
|
+
* Extended from rlm-cli with thread_request and merge_request handlers.
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
11
|
+
import * as os from "node:os";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import * as readline from "node:readline";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
/**
|
|
16
|
+
* Verify Python 3 is available. Throws a clear error if not found.
|
|
17
|
+
*/
|
|
18
|
+
function ensurePython(cmd) {
|
|
19
|
+
try {
|
|
20
|
+
const version = execFileSync(cmd, ["--version"], {
|
|
21
|
+
encoding: "utf-8",
|
|
22
|
+
timeout: 5000,
|
|
23
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
24
|
+
}).trim();
|
|
25
|
+
const major = Number.parseInt(version.replace(/^Python\s*/, "").split(".")[0], 10);
|
|
26
|
+
if (major < 3) {
|
|
27
|
+
throw new Error(`swarm-code requires Python 3 but found ${version}. Install Python 3.x from https://python.org`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (err.code === "ENOENT") {
|
|
32
|
+
throw new Error(`swarm-code requires Python 3 but "${cmd}" was not found on PATH. Install Python 3.x from https://python.org`);
|
|
33
|
+
}
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export * from "./repl-interface.js";
|
|
38
|
+
// ── REPL class ──────────────────────────────────────────────────────────────
|
|
39
|
+
export class PythonRepl {
|
|
40
|
+
proc = null;
|
|
41
|
+
rl = null;
|
|
42
|
+
llmQueryHandler = null;
|
|
43
|
+
threadHandler = null;
|
|
44
|
+
mergeHandler = null;
|
|
45
|
+
/**
|
|
46
|
+
* Pending resolvers for messages we're waiting on from Python.
|
|
47
|
+
* Each entry maps a unique key (requestId or message type) to a one-shot resolve/reject pair.
|
|
48
|
+
* Using requestId prevents collisions when two messages of the same type are in-flight.
|
|
49
|
+
*/
|
|
50
|
+
pending = new Map();
|
|
51
|
+
/** Whether the REPL subprocess is alive. */
|
|
52
|
+
get isAlive() {
|
|
53
|
+
return this.proc !== null && this.proc.exitCode === null;
|
|
54
|
+
}
|
|
55
|
+
getLanguage() {
|
|
56
|
+
return "python";
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Start the Python subprocess and wait for it to signal readiness.
|
|
60
|
+
*/
|
|
61
|
+
async start(signal) {
|
|
62
|
+
if (this.isAlive)
|
|
63
|
+
return;
|
|
64
|
+
const runtimePath = path.join(path.dirname(fileURLToPath(import.meta.url)), "runtime.py");
|
|
65
|
+
const pythonCmd = process.platform === "win32" ? "python" : "python3";
|
|
66
|
+
ensurePython(pythonCmd);
|
|
67
|
+
const homeDir = os.homedir();
|
|
68
|
+
this.proc = spawn(pythonCmd, [runtimePath], {
|
|
69
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
70
|
+
env: {
|
|
71
|
+
// Only pass what Python actually needs — not API keys or secrets
|
|
72
|
+
PATH: process.env.PATH,
|
|
73
|
+
HOME: homeDir,
|
|
74
|
+
USERPROFILE: homeDir, // Windows uses USERPROFILE
|
|
75
|
+
PYTHONUNBUFFERED: "1",
|
|
76
|
+
// Windows needs SystemRoot/SYSTEMROOT for Python to find DLLs
|
|
77
|
+
...(process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {}),
|
|
78
|
+
...(process.env.SYSTEMROOT ? { SYSTEMROOT: process.env.SYSTEMROOT } : {}),
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
this.rl = readline.createInterface({ input: this.proc.stdout });
|
|
82
|
+
this.rl.on("line", (line) => this.handleLine(line));
|
|
83
|
+
this.proc.stderr.on("data", (chunk) => {
|
|
84
|
+
const text = chunk.toString();
|
|
85
|
+
if (text.trim()) {
|
|
86
|
+
process.stderr.write(`[swarm-repl-python] ${text}`);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
this.proc.on("close", () => {
|
|
90
|
+
this.cleanup();
|
|
91
|
+
});
|
|
92
|
+
if (signal) {
|
|
93
|
+
signal.addEventListener("abort", () => {
|
|
94
|
+
this.shutdown();
|
|
95
|
+
}, { once: true });
|
|
96
|
+
}
|
|
97
|
+
await this.waitForMessage("ready");
|
|
98
|
+
}
|
|
99
|
+
/** Register the callback that handles llm_query() calls from Python. */
|
|
100
|
+
setLlmQueryHandler(handler) {
|
|
101
|
+
this.llmQueryHandler = handler;
|
|
102
|
+
}
|
|
103
|
+
/** Register the callback that handles thread() calls from Python. */
|
|
104
|
+
setThreadHandler(handler) {
|
|
105
|
+
this.threadHandler = handler;
|
|
106
|
+
}
|
|
107
|
+
/** Register the callback that handles merge_threads() calls from Python. */
|
|
108
|
+
setMergeHandler(handler) {
|
|
109
|
+
this.mergeHandler = handler;
|
|
110
|
+
}
|
|
111
|
+
/** Inject the full context string into the Python REPL. */
|
|
112
|
+
async setContext(text) {
|
|
113
|
+
this.send({ type: "set_context", value: text });
|
|
114
|
+
await this.waitForMessage("context_set");
|
|
115
|
+
}
|
|
116
|
+
/** Reset the Final sentinel variable. */
|
|
117
|
+
async resetFinal() {
|
|
118
|
+
this.send({ type: "reset_final" });
|
|
119
|
+
await this.waitForMessage("final_reset");
|
|
120
|
+
}
|
|
121
|
+
/** Execute a code snippet and return the result. */
|
|
122
|
+
async execute(code) {
|
|
123
|
+
this.send({ type: "exec", code });
|
|
124
|
+
const msg = (await this.waitForMessage("exec_done"));
|
|
125
|
+
return {
|
|
126
|
+
stdout: msg.stdout,
|
|
127
|
+
stderr: msg.stderr,
|
|
128
|
+
hasFinal: msg.has_final,
|
|
129
|
+
finalValue: msg.final_value,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** Gracefully shut down the Python subprocess. */
|
|
133
|
+
shutdown() {
|
|
134
|
+
if (this.proc && this.proc.exitCode === null) {
|
|
135
|
+
const proc = this.proc;
|
|
136
|
+
try {
|
|
137
|
+
this.send({ type: "shutdown" });
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// stdin may already be closed
|
|
141
|
+
}
|
|
142
|
+
if (process.platform === "win32") {
|
|
143
|
+
// Windows: SIGTERM is ignored, kill immediately
|
|
144
|
+
try {
|
|
145
|
+
proc.kill("SIGKILL");
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
/* already dead */
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Unix: give Python 500ms to exit gracefully, then force kill
|
|
153
|
+
const killTimer = setTimeout(() => {
|
|
154
|
+
try {
|
|
155
|
+
if (proc.exitCode === null)
|
|
156
|
+
proc.kill("SIGKILL");
|
|
157
|
+
}
|
|
158
|
+
catch { }
|
|
159
|
+
}, 500);
|
|
160
|
+
proc.on("exit", () => clearTimeout(killTimer));
|
|
161
|
+
try {
|
|
162
|
+
proc.kill("SIGTERM");
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
/* already dead */
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
this.cleanup();
|
|
170
|
+
}
|
|
171
|
+
// ── Internal ─────────────────────────────────────────────────────────────
|
|
172
|
+
send(msg) {
|
|
173
|
+
if (!this.proc || !this.proc.stdin || this.proc.stdin.destroyed) {
|
|
174
|
+
throw new Error("REPL subprocess is not running");
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
this.proc.stdin.write(`${JSON.stringify(msg)}\n`);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
throw new Error("REPL subprocess stdin write failed");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
handleLine(line) {
|
|
184
|
+
const trimmed = line.trim();
|
|
185
|
+
if (!trimmed)
|
|
186
|
+
return;
|
|
187
|
+
let msg;
|
|
188
|
+
try {
|
|
189
|
+
msg = JSON.parse(trimmed);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Handle async message types (don't go through pending)
|
|
195
|
+
if (msg.type === "llm_query") {
|
|
196
|
+
this.handleLlmQueryMessage(msg).catch((err) => {
|
|
197
|
+
process.stderr.write(`[swarm] llm_query handler error: ${err?.message || err}\n`);
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (msg.type === "thread_request") {
|
|
202
|
+
this.handleThreadRequestMessage(msg).catch((err) => {
|
|
203
|
+
process.stderr.write(`[swarm] thread_request handler error: ${err?.message || err}\n`);
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (msg.type === "merge_request") {
|
|
208
|
+
this.handleMergeRequestMessage(msg).catch((err) => {
|
|
209
|
+
process.stderr.write(`[swarm] merge_request handler error: ${err?.message || err}\n`);
|
|
210
|
+
});
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// Dispatch by msg.id first (request-response pairs), then fall back to msg.type
|
|
214
|
+
// (singleton messages like ready, context_set, final_reset, exec_done)
|
|
215
|
+
const id = msg.id;
|
|
216
|
+
const key = id && this.pending.has(id) ? id : msg.type;
|
|
217
|
+
const entry = this.pending.get(key);
|
|
218
|
+
if (entry) {
|
|
219
|
+
this.pending.delete(key);
|
|
220
|
+
entry.resolve(msg);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async handleLlmQueryMessage(msg) {
|
|
224
|
+
if (!this.llmQueryHandler) {
|
|
225
|
+
this.send({
|
|
226
|
+
type: "llm_result",
|
|
227
|
+
id: msg.id,
|
|
228
|
+
result: "[ERROR] No LLM query handler registered",
|
|
229
|
+
});
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const result = await this.llmQueryHandler(msg.sub_context, msg.instruction);
|
|
234
|
+
this.send({ type: "llm_result", id: msg.id, result });
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
const errorText = err instanceof Error ? err.message : String(err);
|
|
238
|
+
this.send({
|
|
239
|
+
type: "llm_result",
|
|
240
|
+
id: msg.id,
|
|
241
|
+
result: `[ERROR] LLM query failed: ${errorText}`,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async handleThreadRequestMessage(msg) {
|
|
246
|
+
if (!this.threadHandler) {
|
|
247
|
+
this.send({
|
|
248
|
+
type: "thread_result",
|
|
249
|
+
id: msg.id,
|
|
250
|
+
result: "[ERROR] No thread handler registered. Run in swarm mode to use thread().",
|
|
251
|
+
success: false,
|
|
252
|
+
files_changed: [],
|
|
253
|
+
duration_ms: 0,
|
|
254
|
+
});
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
const result = await this.threadHandler(msg.task, msg.context, msg.agent_backend, msg.model, msg.files || []);
|
|
259
|
+
this.send({
|
|
260
|
+
type: "thread_result",
|
|
261
|
+
id: msg.id,
|
|
262
|
+
result: result.result,
|
|
263
|
+
success: result.success,
|
|
264
|
+
files_changed: result.filesChanged,
|
|
265
|
+
duration_ms: result.durationMs,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
const errorText = err instanceof Error ? err.message : String(err);
|
|
270
|
+
this.send({
|
|
271
|
+
type: "thread_result",
|
|
272
|
+
id: msg.id,
|
|
273
|
+
result: `[ERROR] Thread failed: ${errorText}`,
|
|
274
|
+
success: false,
|
|
275
|
+
files_changed: [],
|
|
276
|
+
duration_ms: 0,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async handleMergeRequestMessage(msg) {
|
|
281
|
+
if (!this.mergeHandler) {
|
|
282
|
+
this.send({
|
|
283
|
+
type: "merge_result",
|
|
284
|
+
id: msg.id,
|
|
285
|
+
result: "[ERROR] No merge handler registered. Run in swarm mode to use merge_threads().",
|
|
286
|
+
success: false,
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
const result = await this.mergeHandler();
|
|
292
|
+
this.send({
|
|
293
|
+
type: "merge_result",
|
|
294
|
+
id: msg.id,
|
|
295
|
+
result: result.result,
|
|
296
|
+
success: result.success,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
const errorText = err instanceof Error ? err.message : String(err);
|
|
301
|
+
this.send({
|
|
302
|
+
type: "merge_result",
|
|
303
|
+
id: msg.id,
|
|
304
|
+
result: `[ERROR] Merge failed: ${errorText}`,
|
|
305
|
+
success: false,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Wait for an inbound message from Python.
|
|
311
|
+
* @param type - Message type to wait for.
|
|
312
|
+
* @param requestId - Optional unique key for request-response pairs.
|
|
313
|
+
* Prevents collisions when multiple in-flight messages share the same type.
|
|
314
|
+
* Falls back to `type` when omitted (safe for singleton messages like "ready").
|
|
315
|
+
*/
|
|
316
|
+
waitForMessage(type, requestId) {
|
|
317
|
+
return new Promise((resolve, reject) => {
|
|
318
|
+
if (!this.isAlive) {
|
|
319
|
+
reject(new Error(`REPL subprocess is not running (waiting for "${type}")`));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const key = requestId || type;
|
|
323
|
+
const timeout = setTimeout(() => {
|
|
324
|
+
if (this.pending.has(key)) {
|
|
325
|
+
this.pending.delete(key);
|
|
326
|
+
reject(new Error(`Timeout waiting for "${type}" (key=${key}) from Python REPL`));
|
|
327
|
+
}
|
|
328
|
+
}, 300_000);
|
|
329
|
+
this.pending.set(key, {
|
|
330
|
+
resolve: (msg) => {
|
|
331
|
+
clearTimeout(timeout);
|
|
332
|
+
resolve(msg);
|
|
333
|
+
},
|
|
334
|
+
reject: (err) => {
|
|
335
|
+
clearTimeout(timeout);
|
|
336
|
+
reject(err);
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
cleanup() {
|
|
342
|
+
this.rl?.close();
|
|
343
|
+
this.rl = null;
|
|
344
|
+
this.proc = null;
|
|
345
|
+
// Reject all pending promises so callers unblock immediately
|
|
346
|
+
const abortError = new Error("REPL shut down");
|
|
347
|
+
for (const [, entry] of this.pending) {
|
|
348
|
+
entry.reject(abortError);
|
|
349
|
+
}
|
|
350
|
+
this.pending.clear();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=repl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repl.js","sourceRoot":"","sources":["../../src/core/repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAqB,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;GAEG;AACH,SAAS,YAAY,CAAC,GAAW;IAChC,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE;YAChD,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SACjC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnF,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,0CAA0C,OAAO,8CAA8C,CAAC,CAAC;QAClH,CAAC;IACF,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QACnB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACd,qCAAqC,GAAG,qEAAqE,CAC7G,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACX,CAAC;AACF,CAAC;AAID,cAAc,qBAAqB,CAAC;AAuDpC,+EAA+E;AAE/E,MAAM,OAAO,UAAU;IACd,IAAI,GAAwB,IAAI,CAAC;IACjC,EAAE,GAA8B,IAAI,CAAC;IACrC,eAAe,GAA2B,IAAI,CAAC;IAC/C,aAAa,GAAyB,IAAI,CAAC;IAC3C,YAAY,GAAwB,IAAI,CAAC;IAEjD;;;;OAIG;IACK,OAAO,GAA0F,IAAI,GAAG,EAAE,CAAC;IAEnH,4CAA4C;IAC5C,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC;IAC1D,CAAC;IAED,WAAW;QACV,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,MAAoB;QAC/B,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAEzB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QAE1F,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE;YAC3C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,GAAG,EAAE;gBACJ,iEAAiE;gBACjE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI;gBACtB,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,OAAO,EAAE,2BAA2B;gBACjD,gBAAgB,EAAE,GAAG;gBACrB,8DAA8D;gBAC9D,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACzE;SACD,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAO,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAE5D,IAAI,CAAC,IAAI,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;YACrD,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,gBAAgB,CACtB,OAAO,EACP,GAAG,EAAE;gBACJ,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACd,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,wEAAwE;IACxE,kBAAkB,CAAC,OAAwB;QAC1C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,qEAAqE;IACrE,gBAAgB,CAAC,OAAsB;QACtC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;IAC9B,CAAC;IAED,4EAA4E;IAC5E,eAAe,CAAC,OAAqB;QACpC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;IAC7B,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,UAAU,CAAC,IAAY;QAC5B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC;IAED,yCAAyC;IACzC,KAAK,CAAC,UAAU;QACf,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,OAAO,CAAC,IAAY;QACzB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAoB,CAAC;QACxE,OAAO;YACN,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,UAAU,EAAE,GAAG,CAAC,WAAW;SAC3B,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,QAAQ;QACP,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,CAAC;gBACJ,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACR,8BAA8B;YAC/B,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAClC,gDAAgD;gBAChD,IAAI,CAAC;oBACJ,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC;oBACR,kBAAkB;gBACnB,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,8DAA8D;gBAC9D,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBACjC,IAAI,CAAC;wBACJ,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;4BAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAClD,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;gBACX,CAAC,EAAE,GAAG,CAAC,CAAC;gBACR,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC/C,IAAI,CAAC;oBACJ,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC;oBACR,kBAAkB;gBACnB,CAAC;YACF,CAAC;QACF,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED,4EAA4E;IAEpE,IAAI,CAAC,GAA4B;QACxC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC;YACJ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACvD,CAAC;IACF,CAAC;IAEO,UAAU,CAAC,IAAY;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,IAAI,GAAmB,CAAC;QACxB,IAAI,CAAC;YACJ,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACR,OAAO;QACR,CAAC;QAED,wDAAwD;QACxD,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,IAAI,CAAC,qBAAqB,CAAC,GAAsB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;YACnF,CAAC,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACnC,IAAI,CAAC,0BAA0B,CAAC,GAA2B,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;YACxF,CAAC,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YAClC,IAAI,CAAC,yBAAyB,CAAC,GAA0B,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;YACvF,CAAC,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,gFAAgF;QAChF,uEAAuE;QACvE,MAAM,EAAE,GAAI,GAA0C,CAAC,EAAwB,CAAC;QAChF,MAAM,GAAG,GAAG,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,GAAoB;QACvD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,YAAY;gBAClB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,yCAAyC;aACjD,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;YAC5E,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnE,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,YAAY;gBAClB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,6BAA6B,SAAS,EAAE;aAChD,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,0BAA0B,CAAC,GAAyB;QACjE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,eAAe;gBACrB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,0EAA0E;gBAClF,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,EAAE;gBACjB,WAAW,EAAE,CAAC;aACd,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,eAAe;gBACrB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,aAAa,EAAE,MAAM,CAAC,YAAY;gBAClC,WAAW,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnE,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,eAAe;gBACrB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,0BAA0B,SAAS,EAAE;gBAC7C,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,EAAE;gBACjB,WAAW,EAAE,CAAC;aACd,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAC,GAAwB;QAC/D,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,cAAc;gBACpB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,gFAAgF;gBACxF,OAAO,EAAE,KAAK;aACd,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,cAAc;gBACpB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;aACvB,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnE,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,cAAc;gBACpB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,yBAAyB,SAAS,EAAE;gBAC5C,OAAO,EAAE,KAAK;aACd,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACK,cAAc,CAAC,IAAY,EAAE,SAAkB;QACtD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,IAAI,IAAI,CAAC,CAAC,CAAC;gBAC5E,OAAO;YACR,CAAC;YAED,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC;YAE9B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACzB,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,IAAI,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC;gBAClF,CAAC;YACF,CAAC,EAAE,OAAO,CAAC,CAAC;YAEZ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;gBACrB,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;oBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,OAAO,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;gBACD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE;oBACf,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,MAAM,CAAC,GAAG,CAAC,CAAC;gBACb,CAAC;aACD,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,OAAO;QACd,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,6DAA6D;QAC7D,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RLM Loop — implements Algorithm 1 from "Recursive Language Models" (arXiv:2512.24601).
|
|
3
|
+
* Extended for swarm-code with thread handler wiring.
|
|
4
|
+
*
|
|
5
|
+
* The loop works as follows:
|
|
6
|
+
* 1. Inject the full context into a persistent Python REPL as a variable.
|
|
7
|
+
* 2. Send the LLM metadata about the context plus the user's query.
|
|
8
|
+
* The LLM writes Python code that can inspect/slice/query `context`,
|
|
9
|
+
* call `llm_query()` recursively, call `thread()` to spawn agents,
|
|
10
|
+
* and call FINAL() when done.
|
|
11
|
+
* 3. Execute the code, capture stdout.
|
|
12
|
+
* 4. If FINAL is set, return it. Otherwise loop.
|
|
13
|
+
*/
|
|
14
|
+
import { type Api, type Model } from "@mariozechner/pi-ai";
|
|
15
|
+
import type { ActionDispatcher } from "./action-dispatcher.js";
|
|
16
|
+
import type { MergeHandler, Repl, ThreadHandler } from "./repl.js";
|
|
17
|
+
export interface RlmOptions {
|
|
18
|
+
context: string;
|
|
19
|
+
query: string;
|
|
20
|
+
model: Model<Api>;
|
|
21
|
+
repl?: Repl;
|
|
22
|
+
dispatcher?: ActionDispatcher;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
onProgress?: (info: RlmProgress) => void;
|
|
25
|
+
onSubQueryStart?: (info: SubQueryStartInfo) => void;
|
|
26
|
+
onSubQuery?: (info: SubQueryInfo) => void;
|
|
27
|
+
/** Custom system prompt (used for swarm mode) */
|
|
28
|
+
systemPrompt?: string;
|
|
29
|
+
/** Thread handler for swarm mode */
|
|
30
|
+
threadHandler?: ThreadHandler;
|
|
31
|
+
/** Merge handler for swarm mode */
|
|
32
|
+
mergeHandler?: MergeHandler;
|
|
33
|
+
}
|
|
34
|
+
export interface RlmProgress {
|
|
35
|
+
iteration: number;
|
|
36
|
+
maxIterations: number;
|
|
37
|
+
subQueries: number;
|
|
38
|
+
phase: "generating_code" | "executing" | "checking_final";
|
|
39
|
+
code?: string;
|
|
40
|
+
stdout?: string;
|
|
41
|
+
stderr?: string;
|
|
42
|
+
userMessage?: string;
|
|
43
|
+
rawResponse?: string;
|
|
44
|
+
systemPrompt?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface SubQueryStartInfo {
|
|
47
|
+
index: number;
|
|
48
|
+
contextLength: number;
|
|
49
|
+
instruction: string;
|
|
50
|
+
}
|
|
51
|
+
export interface SubQueryInfo {
|
|
52
|
+
index: number;
|
|
53
|
+
contextLength: number;
|
|
54
|
+
instruction: string;
|
|
55
|
+
resultLength: number;
|
|
56
|
+
resultPreview: string;
|
|
57
|
+
elapsedMs: number;
|
|
58
|
+
}
|
|
59
|
+
export interface RlmResult {
|
|
60
|
+
answer: string;
|
|
61
|
+
iterations: number;
|
|
62
|
+
totalSubQueries: number;
|
|
63
|
+
completed: boolean;
|
|
64
|
+
}
|
|
65
|
+
export declare function runRlmLoop(options: RlmOptions): Promise<RlmResult>;
|