@themoltnet/pi-extension 0.27.3 → 0.28.1
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 +5 -2
- package/dist/index.d.ts +37 -1
- package/dist/index.js +499 -23
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ agent's MoltNet identity fully available inside the sandbox.
|
|
|
6
6
|
## How it works
|
|
7
7
|
|
|
8
8
|
Every pi session boots a lightweight Alpine Linux VM from a cached snapshot.
|
|
9
|
-
All file system and shell tools (read/write/edit/bash)
|
|
9
|
+
All file system, search, and shell tools (read/write/edit/bash/ls/find/grep)
|
|
10
|
+
execute inside the VM.
|
|
10
11
|
MoltNet API tools (diary entries, pack ops, reflection) run on the host via
|
|
11
12
|
the SDK and communicate outbound over HTTP.
|
|
12
13
|
|
|
@@ -24,7 +25,8 @@ pi + extension $MOLTNET_GUEST_WORKSPACE
|
|
|
24
25
|
│ (via gitconfig ssh/allowed_signers
|
|
25
26
|
│ in VM) /home/agent/.pi/agent/auth.json (pi OAuth)
|
|
26
27
|
│
|
|
27
|
-
└─ read/write/edit/bash
|
|
28
|
+
└─ read/write/edit/bash/ls/find/grep
|
|
29
|
+
─▶ vm.exec() / vm.fs.*
|
|
28
30
|
(redirected to VM)
|
|
29
31
|
```
|
|
30
32
|
|
|
@@ -104,6 +106,7 @@ tools can use structured in-process calls rather than shell round-trips.
|
|
|
104
106
|
| Tool | Runs in | Mechanism |
|
|
105
107
|
| ----------------------------------- | ------- | -------------------------------------------------------------------------------- |
|
|
106
108
|
| `read`, `write`, `edit` | VM | Gondolin VFS — agent's FS view is `$MOLTNET_GUEST_WORKSPACE` |
|
|
109
|
+
| `ls`, `find`, `grep` | VM | Gondolin VFS — search/listing observes the sandboxed workspace |
|
|
107
110
|
| `bash` | VM | `vm.exec()` — shell runs in the isolated guest |
|
|
108
111
|
| `user_bash` (human `/bash` command) | VM | Same as agent bash |
|
|
109
112
|
| `moltnet_pack_get` | Host | TypeScript SDK (`@themoltnet/sdk`) authenticated via injected `moltnet.json` |
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,16 @@ declare interface BuildAgentSessionArgs {
|
|
|
40
40
|
piAuthDir: string;
|
|
41
41
|
/** Resolved pi model handle (provider + model id). */
|
|
42
42
|
modelHandle: Model<Api>;
|
|
43
|
+
/** Optional runtime-profile thinking/reasoning level applied at session start. */
|
|
44
|
+
thinkingLevel?: PiThinkingLevel | null;
|
|
45
|
+
/** Optional runtime-profile sampling temperature applied to provider requests. */
|
|
46
|
+
temperature?: number | null;
|
|
47
|
+
/** Optional runtime-profile nucleus sampling probability mass. */
|
|
48
|
+
topP?: number | null;
|
|
49
|
+
/** Optional runtime-profile top-k sampling cutoff. */
|
|
50
|
+
topK?: number | null;
|
|
51
|
+
/** Optional runtime-profile generated output token cap. */
|
|
52
|
+
maxOutputTokens?: number | null;
|
|
43
53
|
/** Pre-built customTools array. Caller composes Gondolin + MoltNet + submit tools. */
|
|
44
54
|
customTools: ToolDefinition[];
|
|
45
55
|
/** System-prompt fragments appended after pi's defaults. Parent passes the
|
|
@@ -157,11 +167,21 @@ export declare interface CreateSubagentToolArgs {
|
|
|
157
167
|
piAuthDir: string;
|
|
158
168
|
/** Resolved pi model handle — subagents share it. */
|
|
159
169
|
modelHandle: Model<Api>;
|
|
170
|
+
/** Runtime-profile thinking/reasoning level — subagents inherit it. */
|
|
171
|
+
thinkingLevel?: PiThinkingLevel | null;
|
|
172
|
+
/** Runtime-profile sampling temperature — subagents inherit it. */
|
|
173
|
+
temperature?: number | null;
|
|
174
|
+
/** Runtime-profile nucleus sampling probability mass — subagents inherit it. */
|
|
175
|
+
topP?: number | null;
|
|
176
|
+
/** Runtime-profile top-k sampling cutoff — subagents inherit it. */
|
|
177
|
+
topK?: number | null;
|
|
178
|
+
/** Runtime-profile generated output token cap — subagents inherit it. */
|
|
179
|
+
maxOutputTokens?: number | null;
|
|
160
180
|
/** Agent name for telemetry. */
|
|
161
181
|
agentName: string;
|
|
162
182
|
/**
|
|
163
183
|
* Custom tools every subagent inherits (Gondolin-routed
|
|
164
|
-
*
|
|
184
|
+
* built-ins + moltnet_* tools, etc). MUST NOT include
|
|
165
185
|
* the parent's submit-output tool, the parent's `subagent` tool,
|
|
166
186
|
* or any other parent-only artefact — the caller is responsible
|
|
167
187
|
* for filtering. The subagent appends its own submit tool.
|
|
@@ -256,6 +276,20 @@ export declare interface ExecutePiTaskOptions {
|
|
|
256
276
|
/** LLM selection. */
|
|
257
277
|
provider: string;
|
|
258
278
|
model: string;
|
|
279
|
+
/**
|
|
280
|
+
* Runtime-profile reasoning/thinking level. Null/undefined means use Pi's
|
|
281
|
+
* configured default; explicit `off` disables provider thinking where
|
|
282
|
+
* supported.
|
|
283
|
+
*/
|
|
284
|
+
thinkingLevel?: PiThinkingLevel | null;
|
|
285
|
+
/** Optional sampling temperature. Null/undefined means provider default. */
|
|
286
|
+
temperature?: number | null;
|
|
287
|
+
/** Optional nucleus-sampling probability mass. Null/undefined means provider default. */
|
|
288
|
+
topP?: number | null;
|
|
289
|
+
/** Optional top-k sampling cutoff. Null/undefined means provider default. */
|
|
290
|
+
topK?: number | null;
|
|
291
|
+
/** Optional cap on generated output tokens. Null/undefined means provider/model default. */
|
|
292
|
+
maxOutputTokens?: number | null;
|
|
259
293
|
/** Extra hosts to allow in the sandbox egress policy. */
|
|
260
294
|
extraAllowedHosts?: string[];
|
|
261
295
|
/** Sandbox overrides (env, VFS shadows, resources). */
|
|
@@ -544,6 +578,8 @@ export declare interface PiTaskExecutionPlan {
|
|
|
544
578
|
|
|
545
579
|
export declare type PiTaskExecutionPlanFactory = (claimedTask: ClaimedTask) => Promise<PiTaskExecutionPlan | null> | PiTaskExecutionPlan | null;
|
|
546
580
|
|
|
581
|
+
declare type PiThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
582
|
+
|
|
547
583
|
declare interface PiWorkspaceAttachmentPlan {
|
|
548
584
|
mountPath: string;
|
|
549
585
|
cwdPath: string;
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { execFileSync } from "node:child_process";
|
|
3
3
|
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
4
4
|
import path, { join, relative, sep } from "node:path";
|
|
5
|
-
import { DefaultResourceLoader, SessionManager, createAgentSession, createBashTool, createBashToolDefinition, createEditTool, createEditToolDefinition, createReadTool, createReadToolDefinition, createSyntheticSourceInfo, createWriteTool, createWriteToolDefinition, defineTool, parseFrontmatter } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { DEFAULT_MAX_BYTES, DefaultResourceLoader, SessionManager, createAgentSession, createBashTool, createBashToolDefinition, createEditTool, createEditToolDefinition, createFindTool, createFindToolDefinition, createGrepTool, createGrepToolDefinition, createLsTool, createLsToolDefinition, createReadTool, createReadToolDefinition, createSyntheticSourceInfo, createWriteTool, createWriteToolDefinition, defineTool, formatSize, parseFrontmatter, truncateHead, truncateLine } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import { Readable } from "node:stream";
|
|
8
8
|
import crypto, { createHash as createHash$1 } from "crypto";
|
|
@@ -1868,6 +1868,28 @@ var uploadRuntimeSession = (options) => (options.client ?? client).put({
|
|
|
1868
1868
|
}
|
|
1869
1869
|
});
|
|
1870
1870
|
/**
|
|
1871
|
+
* List recent team-scoped runtime slots for repair/sync.
|
|
1872
|
+
*/
|
|
1873
|
+
var listRuntimeSlots = (options) => (options.client ?? client).get({
|
|
1874
|
+
security: [
|
|
1875
|
+
{
|
|
1876
|
+
scheme: "bearer",
|
|
1877
|
+
type: "http"
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
name: "X-Moltnet-Session-Token",
|
|
1881
|
+
type: "apiKey"
|
|
1882
|
+
},
|
|
1883
|
+
{
|
|
1884
|
+
in: "cookie",
|
|
1885
|
+
name: "ory_kratos_session",
|
|
1886
|
+
type: "apiKey"
|
|
1887
|
+
}
|
|
1888
|
+
],
|
|
1889
|
+
url: "/runtime-slots",
|
|
1890
|
+
...options
|
|
1891
|
+
});
|
|
1892
|
+
/**
|
|
1871
1893
|
* Upsert a team-scoped runtime slot for audit and continuation affinity lookup.
|
|
1872
1894
|
*/
|
|
1873
1895
|
var beginRuntimeSlot = (options) => (options.client ?? client).post({
|
|
@@ -5171,6 +5193,15 @@ function createRuntimeSlotsNamespace(context) {
|
|
|
5171
5193
|
if (err instanceof MoltNetError && err.statusCode === 404) return null;
|
|
5172
5194
|
throw err;
|
|
5173
5195
|
}
|
|
5196
|
+
},
|
|
5197
|
+
async list(query, options) {
|
|
5198
|
+
const filteredQuery = Object.fromEntries(Object.entries(query).filter(([, value]) => value !== void 0));
|
|
5199
|
+
return unwrapResult(await listRuntimeSlots({
|
|
5200
|
+
auth,
|
|
5201
|
+
client,
|
|
5202
|
+
headers: requiredTeamHeaders(options),
|
|
5203
|
+
query: filteredQuery
|
|
5204
|
+
})).items;
|
|
5174
5205
|
}
|
|
5175
5206
|
};
|
|
5176
5207
|
}
|
|
@@ -9520,6 +9551,32 @@ var RuntimeProfileAllowedWorkspaceModes = _Array_(RuntimeProfileWorkspaceMode, {
|
|
|
9520
9551
|
maxItems: 3,
|
|
9521
9552
|
uniqueItems: true
|
|
9522
9553
|
});
|
|
9554
|
+
var RuntimeProfileThinkingLevelOptions = [
|
|
9555
|
+
Literal("off"),
|
|
9556
|
+
Literal("minimal"),
|
|
9557
|
+
Literal("low"),
|
|
9558
|
+
Literal("medium"),
|
|
9559
|
+
Literal("high"),
|
|
9560
|
+
Literal("xhigh")
|
|
9561
|
+
];
|
|
9562
|
+
Union([...RuntimeProfileThinkingLevelOptions]);
|
|
9563
|
+
var RuntimeProfileNullableThinkingLevel = Union([...RuntimeProfileThinkingLevelOptions, Null()]);
|
|
9564
|
+
var RuntimeProfileNullableTemperature = Union([Null(), Number$1({
|
|
9565
|
+
minimum: 0,
|
|
9566
|
+
maximum: 2
|
|
9567
|
+
})]);
|
|
9568
|
+
var RuntimeProfileNullableTopP = Union([Null(), Number$1({
|
|
9569
|
+
minimum: 0,
|
|
9570
|
+
maximum: 1
|
|
9571
|
+
})]);
|
|
9572
|
+
var RuntimeProfileNullableTopK = Union([Integer({
|
|
9573
|
+
minimum: 1,
|
|
9574
|
+
maximum: 1e4
|
|
9575
|
+
}), Null()]);
|
|
9576
|
+
var RuntimeProfileNullableMaxOutputTokens = Union([Integer({
|
|
9577
|
+
minimum: 1,
|
|
9578
|
+
maximum: 1e6
|
|
9579
|
+
}), Null()]);
|
|
9523
9580
|
var SandboxResumeCommandWhenSchema = _Object_({ workspaceMode: Optional(_Array_(Union([
|
|
9524
9581
|
Literal("shared_mount"),
|
|
9525
9582
|
Literal("dedicated_worktree"),
|
|
@@ -9644,6 +9701,11 @@ _Object_({
|
|
|
9644
9701
|
minLength: 1,
|
|
9645
9702
|
maxLength: 200
|
|
9646
9703
|
}),
|
|
9704
|
+
thinkingLevel: RuntimeProfileNullableThinkingLevel,
|
|
9705
|
+
temperature: RuntimeProfileNullableTemperature,
|
|
9706
|
+
topP: RuntimeProfileNullableTopP,
|
|
9707
|
+
topK: RuntimeProfileNullableTopK,
|
|
9708
|
+
maxOutputTokens: RuntimeProfileNullableMaxOutputTokens,
|
|
9647
9709
|
runtimeKind: Literal("gondolin_pi"),
|
|
9648
9710
|
sandbox: RuntimeProfileSandbox,
|
|
9649
9711
|
sessionStorageMode: Literal("local"),
|
|
@@ -9755,7 +9817,7 @@ var RuntimeWorkspace = _Object_({
|
|
|
9755
9817
|
createdAtMs: Integer({ minimum: 0 }),
|
|
9756
9818
|
lastUsedAtMs: Integer({ minimum: 0 })
|
|
9757
9819
|
}, { $id: "RuntimeWorkspace" });
|
|
9758
|
-
_Object_({
|
|
9820
|
+
_Object_({ items: _Array_(_Object_({
|
|
9759
9821
|
slot: _Object_({
|
|
9760
9822
|
id: String$1({ format: "uuid" }),
|
|
9761
9823
|
teamId: String$1({ format: "uuid" }),
|
|
@@ -9788,7 +9850,7 @@ _Object_({
|
|
|
9788
9850
|
expiresAtMs: Integer({ minimum: 0 })
|
|
9789
9851
|
}, { $id: "RuntimeSlot" }),
|
|
9790
9852
|
workspace: Union([RuntimeWorkspace, Null()])
|
|
9791
|
-
}, { $id: "ResolvedRuntimeSlot" });
|
|
9853
|
+
}, { $id: "ResolvedRuntimeSlot" })) }, { $id: "RuntimeSlotListResponse" });
|
|
9792
9854
|
_Object_({
|
|
9793
9855
|
agentName: String$1({
|
|
9794
9856
|
minLength: 1,
|
|
@@ -9849,6 +9911,21 @@ _Object_({
|
|
|
9849
9911
|
$id: "FindLatestRuntimeSlotForAttemptQuery",
|
|
9850
9912
|
additionalProperties: false
|
|
9851
9913
|
});
|
|
9914
|
+
_Object_({
|
|
9915
|
+
agentName: Optional(String$1({
|
|
9916
|
+
minLength: 1,
|
|
9917
|
+
maxLength: 100
|
|
9918
|
+
})),
|
|
9919
|
+
runtimeProfileId: Optional(String$1({ format: "uuid" })),
|
|
9920
|
+
state: Optional(RuntimeSlotState),
|
|
9921
|
+
limit: Optional(Integer({
|
|
9922
|
+
minimum: 1,
|
|
9923
|
+
maximum: 200
|
|
9924
|
+
}))
|
|
9925
|
+
}, {
|
|
9926
|
+
$id: "ListRuntimeSlotsQuery",
|
|
9927
|
+
additionalProperties: false
|
|
9928
|
+
});
|
|
9852
9929
|
//#endregion
|
|
9853
9930
|
//#region ../tasks/src/success-criteria.ts
|
|
9854
9931
|
/**
|
|
@@ -18482,11 +18559,13 @@ function rewriteMoltnetJsonPaths(moltnetJson, vmAgentDir, vmSshDir, githubAppPem
|
|
|
18482
18559
|
//#region src/tool-operations.ts
|
|
18483
18560
|
/**
|
|
18484
18561
|
* Gondolin tool operations: redirect pi's built-in tool operations
|
|
18485
|
-
* (read, write, edit, bash) to execute inside the VM.
|
|
18562
|
+
* (read, write, edit, bash, ls, find, grep) to execute inside the VM.
|
|
18486
18563
|
*
|
|
18487
18564
|
* Follows the same pattern as upstream pi-gondolin.ts — pi's tool factories
|
|
18488
18565
|
* accept an `operations` object that provides the underlying I/O.
|
|
18489
18566
|
*/
|
|
18567
|
+
var DEFAULT_GREP_LIMIT = 100;
|
|
18568
|
+
var GREP_MAX_FILE_SIZE = "2M";
|
|
18490
18569
|
function shQuote(s) {
|
|
18491
18570
|
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
18492
18571
|
}
|
|
@@ -18496,6 +18575,18 @@ function normalizeGuestPath(p) {
|
|
|
18496
18575
|
function isSameOrInsidePosixPath(candidate, root) {
|
|
18497
18576
|
return candidate === root || candidate.startsWith(`${root}/`);
|
|
18498
18577
|
}
|
|
18578
|
+
function resolveLocalPath(localCwd, inputPath) {
|
|
18579
|
+
return path.isAbsolute(inputPath) ? inputPath : path.resolve(localCwd, inputPath);
|
|
18580
|
+
}
|
|
18581
|
+
function toHostToolPath(localCwd, guestWorkspace, guestPath) {
|
|
18582
|
+
const normalizedGuestWorkspace = normalizeGuestPath(guestWorkspace);
|
|
18583
|
+
const normalizedGuestPath = normalizeGuestPath(guestPath);
|
|
18584
|
+
if (isSameOrInsidePosixPath(normalizedGuestPath, normalizedGuestWorkspace)) {
|
|
18585
|
+
const rel = path.posix.relative(normalizedGuestWorkspace, normalizedGuestPath);
|
|
18586
|
+
return rel ? path.join(localCwd, ...rel.split("/")) : localCwd;
|
|
18587
|
+
}
|
|
18588
|
+
return normalizedGuestPath;
|
|
18589
|
+
}
|
|
18499
18590
|
/**
|
|
18500
18591
|
* Map a host-side absolute path to a guest-side workspace path.
|
|
18501
18592
|
* Throws if the path escapes the workspace.
|
|
@@ -18515,17 +18606,10 @@ function toGuestPath(localCwd, localPath, guestWorkspace) {
|
|
|
18515
18606
|
function createGondolinReadOps(vm, localCwd, guestWorkspace) {
|
|
18516
18607
|
return {
|
|
18517
18608
|
readFile: async (p) => {
|
|
18518
|
-
const
|
|
18519
|
-
|
|
18520
|
-
return r.stdoutBuffer;
|
|
18521
|
-
},
|
|
18522
|
-
access: async (p) => {
|
|
18523
|
-
if (!(await vm.exec([
|
|
18524
|
-
"/bin/sh",
|
|
18525
|
-
"-lc",
|
|
18526
|
-
`test -r ${shQuote(toGuestPath(localCwd, p, guestWorkspace))}`
|
|
18527
|
-
])).ok) throw new Error(`not readable: ${p}`);
|
|
18609
|
+
const content = await vm.fs.readFile(toGuestPath(localCwd, p, guestWorkspace));
|
|
18610
|
+
return typeof content === "string" ? Buffer.from(content, "utf8") : Buffer.from(content);
|
|
18528
18611
|
},
|
|
18612
|
+
access: async (p) => vm.fs.access(toGuestPath(localCwd, p, guestWorkspace)),
|
|
18529
18613
|
detectImageMimeType: async (p) => {
|
|
18530
18614
|
try {
|
|
18531
18615
|
const r = await vm.exec([
|
|
@@ -18583,6 +18667,253 @@ function createGondolinEditOps(vm, localCwd, guestWorkspace) {
|
|
|
18583
18667
|
writeFile: w.writeFile
|
|
18584
18668
|
};
|
|
18585
18669
|
}
|
|
18670
|
+
function createGondolinLsOps(vm, localCwd, guestWorkspace) {
|
|
18671
|
+
return {
|
|
18672
|
+
exists: async (p) => {
|
|
18673
|
+
try {
|
|
18674
|
+
await vm.fs.access(toGuestPath(localCwd, p, guestWorkspace));
|
|
18675
|
+
return true;
|
|
18676
|
+
} catch {
|
|
18677
|
+
return false;
|
|
18678
|
+
}
|
|
18679
|
+
},
|
|
18680
|
+
stat: async (p) => vm.fs.stat(toGuestPath(localCwd, p, guestWorkspace)),
|
|
18681
|
+
readdir: async (p) => vm.fs.listDir(toGuestPath(localCwd, p, guestWorkspace))
|
|
18682
|
+
};
|
|
18683
|
+
}
|
|
18684
|
+
async function walkGuestFiles(vm, root, visit, signal) {
|
|
18685
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
18686
|
+
if (!(await vm.fs.stat(root, { signal })).isDirectory()) return visit(root, path.posix.basename(root));
|
|
18687
|
+
const walkDirectory = async (dir, relativeDir) => {
|
|
18688
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
18689
|
+
const entries = await vm.fs.listDir(dir, { signal });
|
|
18690
|
+
for (const entry of entries) {
|
|
18691
|
+
if (entry === ".git" || entry === "node_modules") continue;
|
|
18692
|
+
const guestPath = path.posix.join(dir, entry);
|
|
18693
|
+
const relativePath = relativeDir ? path.posix.join(relativeDir, entry) : entry;
|
|
18694
|
+
let entryStat;
|
|
18695
|
+
try {
|
|
18696
|
+
entryStat = await vm.fs.stat(guestPath, { signal });
|
|
18697
|
+
} catch {
|
|
18698
|
+
continue;
|
|
18699
|
+
}
|
|
18700
|
+
if (entryStat.isDirectory()) {
|
|
18701
|
+
if (!await walkDirectory(guestPath, relativePath)) return false;
|
|
18702
|
+
} else if (!await visit(guestPath, relativePath)) return false;
|
|
18703
|
+
}
|
|
18704
|
+
return true;
|
|
18705
|
+
};
|
|
18706
|
+
return walkDirectory(root, "");
|
|
18707
|
+
}
|
|
18708
|
+
function matchesGlob(relativePath, pattern) {
|
|
18709
|
+
return path.posix.matchesGlob(relativePath, pattern);
|
|
18710
|
+
}
|
|
18711
|
+
function matchesToolGlob(relativePath, pattern) {
|
|
18712
|
+
const normalizedPattern = normalizeGuestPath(pattern);
|
|
18713
|
+
if (normalizedPattern.includes("/")) return matchesGlob(relativePath, normalizedPattern) || matchesGlob(relativePath, `**/${normalizedPattern}`);
|
|
18714
|
+
return matchesGlob(path.posix.basename(relativePath), normalizedPattern);
|
|
18715
|
+
}
|
|
18716
|
+
function createGondolinFindOps(vm, localCwd, guestWorkspace) {
|
|
18717
|
+
return {
|
|
18718
|
+
exists: async (p) => {
|
|
18719
|
+
try {
|
|
18720
|
+
await vm.fs.access(toGuestPath(localCwd, p, guestWorkspace));
|
|
18721
|
+
return true;
|
|
18722
|
+
} catch {
|
|
18723
|
+
return false;
|
|
18724
|
+
}
|
|
18725
|
+
},
|
|
18726
|
+
glob: async (pattern, cwd, options) => {
|
|
18727
|
+
const root = toGuestPath(localCwd, cwd, guestWorkspace);
|
|
18728
|
+
const results = [];
|
|
18729
|
+
await walkGuestFiles(vm, root, (guestPath, relativePath) => {
|
|
18730
|
+
if (results.length >= options.limit) return Promise.resolve(false);
|
|
18731
|
+
if (options.ignore.some((ignore) => matchesToolGlob(relativePath, ignore))) return Promise.resolve(true);
|
|
18732
|
+
if (matchesToolGlob(relativePath, pattern)) results.push(toHostToolPath(localCwd, guestWorkspace, guestPath));
|
|
18733
|
+
return Promise.resolve(results.length < options.limit);
|
|
18734
|
+
});
|
|
18735
|
+
return results;
|
|
18736
|
+
}
|
|
18737
|
+
};
|
|
18738
|
+
}
|
|
18739
|
+
function appendGrepBlock(params) {
|
|
18740
|
+
let linesTruncated = false;
|
|
18741
|
+
const start = params.contextLines > 0 ? Math.max(0, params.lineIndex - params.contextLines) : params.lineIndex;
|
|
18742
|
+
const end = params.contextLines > 0 ? Math.min(params.lines.length - 1, params.lineIndex + params.contextLines) : params.lineIndex;
|
|
18743
|
+
for (let index = start; index <= end; index++) {
|
|
18744
|
+
const { text, wasTruncated } = truncateLine((params.lines[index] ?? "").replace(/\r/g, ""));
|
|
18745
|
+
if (wasTruncated) linesTruncated = true;
|
|
18746
|
+
const separator = index === params.lineIndex ? ":" : "-";
|
|
18747
|
+
params.outputLines.push(`${params.relativePath}${separator}${index + 1}${separator} ${text}`);
|
|
18748
|
+
}
|
|
18749
|
+
return linesTruncated;
|
|
18750
|
+
}
|
|
18751
|
+
function parseRgJsonLines(params) {
|
|
18752
|
+
const parts = `${params.carry}${params.chunk}`.split("\n");
|
|
18753
|
+
const carry = parts.pop() ?? "";
|
|
18754
|
+
let limitReached = false;
|
|
18755
|
+
for (const line of parts) {
|
|
18756
|
+
if (!line.trim() || params.matches.length >= params.effectiveLimit) continue;
|
|
18757
|
+
let event;
|
|
18758
|
+
try {
|
|
18759
|
+
event = JSON.parse(line);
|
|
18760
|
+
} catch {
|
|
18761
|
+
continue;
|
|
18762
|
+
}
|
|
18763
|
+
const candidate = event;
|
|
18764
|
+
if (candidate.type !== "match") continue;
|
|
18765
|
+
const guestPath = candidate.data?.path?.text;
|
|
18766
|
+
const lineNumber = candidate.data?.line_number;
|
|
18767
|
+
if (!guestPath || typeof lineNumber !== "number") continue;
|
|
18768
|
+
params.matches.push({
|
|
18769
|
+
guestPath,
|
|
18770
|
+
lineNumber,
|
|
18771
|
+
lineText: candidate.data?.lines?.text
|
|
18772
|
+
});
|
|
18773
|
+
if (params.matches.length >= params.effectiveLimit) {
|
|
18774
|
+
limitReached = true;
|
|
18775
|
+
break;
|
|
18776
|
+
}
|
|
18777
|
+
}
|
|
18778
|
+
return {
|
|
18779
|
+
carry,
|
|
18780
|
+
limitReached
|
|
18781
|
+
};
|
|
18782
|
+
}
|
|
18783
|
+
async function readGuestLines(vm, guestPath, signal) {
|
|
18784
|
+
try {
|
|
18785
|
+
return (await vm.fs.readFile(guestPath, {
|
|
18786
|
+
encoding: "utf8",
|
|
18787
|
+
signal
|
|
18788
|
+
})).replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
|
|
18789
|
+
} catch {
|
|
18790
|
+
return [];
|
|
18791
|
+
}
|
|
18792
|
+
}
|
|
18793
|
+
async function executeGondolinGrep(vm, localCwd, guestWorkspace, params, signal) {
|
|
18794
|
+
const root = toGuestPath(localCwd, resolveLocalPath(localCwd, params.path ?? "."), guestWorkspace);
|
|
18795
|
+
let rootStat;
|
|
18796
|
+
try {
|
|
18797
|
+
rootStat = await vm.fs.stat(root, { signal });
|
|
18798
|
+
} catch {
|
|
18799
|
+
throw new Error(`Path not found: ${resolveLocalPath(localCwd, params.path ?? ".")}`);
|
|
18800
|
+
}
|
|
18801
|
+
const rootIsDirectory = rootStat.isDirectory();
|
|
18802
|
+
const contextLines = params.context && params.context > 0 ? params.context : 0;
|
|
18803
|
+
const effectiveLimit = Math.max(1, params.limit ?? DEFAULT_GREP_LIMIT);
|
|
18804
|
+
const args = [
|
|
18805
|
+
"--json",
|
|
18806
|
+
"--line-number",
|
|
18807
|
+
"--color=never",
|
|
18808
|
+
"--hidden",
|
|
18809
|
+
"--max-filesize",
|
|
18810
|
+
GREP_MAX_FILE_SIZE
|
|
18811
|
+
];
|
|
18812
|
+
if (params.ignoreCase) args.push("--ignore-case");
|
|
18813
|
+
if (params.literal) args.push("--fixed-strings");
|
|
18814
|
+
if (params.glob) args.push("--glob", params.glob);
|
|
18815
|
+
args.push("--", params.pattern, root);
|
|
18816
|
+
const outputLines = [];
|
|
18817
|
+
const details = {};
|
|
18818
|
+
const matches = [];
|
|
18819
|
+
let matchLimitReached = false;
|
|
18820
|
+
let linesTruncated = false;
|
|
18821
|
+
let stderr = "";
|
|
18822
|
+
let carry = "";
|
|
18823
|
+
const ac = new AbortController();
|
|
18824
|
+
const onAbort = () => ac.abort();
|
|
18825
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
18826
|
+
try {
|
|
18827
|
+
const proc = vm.exec(["/bin/rg", ...args], {
|
|
18828
|
+
signal: ac.signal,
|
|
18829
|
+
stdout: "pipe",
|
|
18830
|
+
stderr: "pipe"
|
|
18831
|
+
});
|
|
18832
|
+
for await (const chunk of proc.output()) {
|
|
18833
|
+
const text = typeof chunk.data === "string" ? chunk.data : Buffer.from(chunk.data).toString("utf8");
|
|
18834
|
+
if (chunk.stream === "stderr") {
|
|
18835
|
+
stderr += text;
|
|
18836
|
+
continue;
|
|
18837
|
+
}
|
|
18838
|
+
const parsed = parseRgJsonLines({
|
|
18839
|
+
chunk: text,
|
|
18840
|
+
carry,
|
|
18841
|
+
matches,
|
|
18842
|
+
effectiveLimit
|
|
18843
|
+
});
|
|
18844
|
+
carry = parsed.carry;
|
|
18845
|
+
if (parsed.limitReached) {
|
|
18846
|
+
matchLimitReached = true;
|
|
18847
|
+
ac.abort();
|
|
18848
|
+
break;
|
|
18849
|
+
}
|
|
18850
|
+
}
|
|
18851
|
+
const r = await proc;
|
|
18852
|
+
if (!signal?.aborted && !matchLimitReached && r.exitCode !== 0 && r.exitCode !== 1) throw new Error(stderr.trim() || `ripgrep exited with code ${r.exitCode}`);
|
|
18853
|
+
} catch (err) {
|
|
18854
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
18855
|
+
if (matchLimitReached) {} else throw err;
|
|
18856
|
+
} finally {
|
|
18857
|
+
signal?.removeEventListener("abort", onAbort);
|
|
18858
|
+
}
|
|
18859
|
+
if (matches.length === 0) return {
|
|
18860
|
+
content: [{
|
|
18861
|
+
type: "text",
|
|
18862
|
+
text: "No matches found"
|
|
18863
|
+
}],
|
|
18864
|
+
details: void 0
|
|
18865
|
+
};
|
|
18866
|
+
const fileCache = /* @__PURE__ */ new Map();
|
|
18867
|
+
for (const match of matches) {
|
|
18868
|
+
if (signal?.aborted) throw new Error("Operation aborted");
|
|
18869
|
+
const displayPath = rootIsDirectory ? path.posix.relative(root, match.guestPath) : path.posix.basename(match.guestPath);
|
|
18870
|
+
if (contextLines === 0 && match.lineText !== void 0) {
|
|
18871
|
+
const { text, wasTruncated } = truncateLine(match.lineText.replace(/\r\n/g, "\n").replace(/\r/g, "").replace(/\n$/, ""));
|
|
18872
|
+
if (wasTruncated) linesTruncated = true;
|
|
18873
|
+
outputLines.push(`${displayPath}:${match.lineNumber}: ${text}`);
|
|
18874
|
+
continue;
|
|
18875
|
+
}
|
|
18876
|
+
let lines = fileCache.get(match.guestPath);
|
|
18877
|
+
if (!lines) {
|
|
18878
|
+
lines = await readGuestLines(vm, match.guestPath, signal);
|
|
18879
|
+
fileCache.set(match.guestPath, lines);
|
|
18880
|
+
}
|
|
18881
|
+
if (lines.length === 0) {
|
|
18882
|
+
outputLines.push(`${displayPath}:${match.lineNumber}: (unable to read file)`);
|
|
18883
|
+
continue;
|
|
18884
|
+
}
|
|
18885
|
+
if (appendGrepBlock({
|
|
18886
|
+
outputLines,
|
|
18887
|
+
lines,
|
|
18888
|
+
relativePath: displayPath,
|
|
18889
|
+
lineIndex: match.lineNumber - 1,
|
|
18890
|
+
contextLines
|
|
18891
|
+
})) linesTruncated = true;
|
|
18892
|
+
}
|
|
18893
|
+
const truncation = truncateHead(outputLines.join("\n"), { maxLines: Number.MAX_SAFE_INTEGER });
|
|
18894
|
+
const notices = [];
|
|
18895
|
+
let output = truncation.content;
|
|
18896
|
+
if (matchLimitReached) {
|
|
18897
|
+
details.matchLimitReached = effectiveLimit;
|
|
18898
|
+
notices.push(`${effectiveLimit} matches limit reached`);
|
|
18899
|
+
}
|
|
18900
|
+
if (linesTruncated) {
|
|
18901
|
+
details.linesTruncated = true;
|
|
18902
|
+
notices.push("long lines truncated");
|
|
18903
|
+
}
|
|
18904
|
+
if (truncation.truncated) {
|
|
18905
|
+
details.truncation = truncation;
|
|
18906
|
+
notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
|
|
18907
|
+
}
|
|
18908
|
+
if (notices.length > 0) output += `\n\n[${notices.join(". ")}]`;
|
|
18909
|
+
return {
|
|
18910
|
+
content: [{
|
|
18911
|
+
type: "text",
|
|
18912
|
+
text: output
|
|
18913
|
+
}],
|
|
18914
|
+
details: Object.keys(details).length > 0 ? details : void 0
|
|
18915
|
+
};
|
|
18916
|
+
}
|
|
18586
18917
|
function createGondolinBashOps(vm, localCwd, guestWorkspace) {
|
|
18587
18918
|
return { exec: async (command, cwd, { onData, signal, timeout, env }) => {
|
|
18588
18919
|
const guestCwd = toGuestPath(localCwd, cwd, guestWorkspace);
|
|
@@ -18755,6 +19086,89 @@ function extractUsage(message) {
|
|
|
18755
19086
|
};
|
|
18756
19087
|
}
|
|
18757
19088
|
//#endregion
|
|
19089
|
+
//#region src/runtime/model-options-extension.ts
|
|
19090
|
+
function hasPiModelOptions(options) {
|
|
19091
|
+
return options.temperature !== void 0 && options.temperature !== null || options.topP !== void 0 && options.topP !== null || options.topK !== void 0 && options.topK !== null || options.maxOutputTokens !== void 0 && options.maxOutputTokens !== null;
|
|
19092
|
+
}
|
|
19093
|
+
function createPiModelOptionsExtension(options) {
|
|
19094
|
+
return function piModelOptionsExtension(pi) {
|
|
19095
|
+
pi.on("before_provider_request", (event) => {
|
|
19096
|
+
return applyPiModelOptions(event.payload, options);
|
|
19097
|
+
});
|
|
19098
|
+
};
|
|
19099
|
+
}
|
|
19100
|
+
function applyPiModelOptions(payload, options) {
|
|
19101
|
+
if (!isRecord(payload)) return void 0;
|
|
19102
|
+
if (!hasPiModelOptions(options)) return void 0;
|
|
19103
|
+
if (isGooglePayload(payload)) {
|
|
19104
|
+
const config = isRecord(payload.config) ? payload.config : {};
|
|
19105
|
+
return {
|
|
19106
|
+
...payload,
|
|
19107
|
+
config: applyConfigOptions(config, options)
|
|
19108
|
+
};
|
|
19109
|
+
}
|
|
19110
|
+
if (isBedrockPayload(payload)) {
|
|
19111
|
+
const inferenceConfig = isRecord(payload.inferenceConfig) ? payload.inferenceConfig : {};
|
|
19112
|
+
return {
|
|
19113
|
+
...payload,
|
|
19114
|
+
inferenceConfig: applyBedrockOptions(inferenceConfig, options)
|
|
19115
|
+
};
|
|
19116
|
+
}
|
|
19117
|
+
return applyTopLevelOptions(payload, options);
|
|
19118
|
+
}
|
|
19119
|
+
function applyConfigOptions(config, options) {
|
|
19120
|
+
return {
|
|
19121
|
+
...config,
|
|
19122
|
+
...options.temperature !== void 0 && options.temperature !== null ? { temperature: options.temperature } : {},
|
|
19123
|
+
...options.topP !== void 0 && options.topP !== null ? { topP: options.topP } : {},
|
|
19124
|
+
...options.topK !== void 0 && options.topK !== null ? { topK: options.topK } : {},
|
|
19125
|
+
...options.maxOutputTokens !== void 0 && options.maxOutputTokens !== null ? { maxOutputTokens: options.maxOutputTokens } : {}
|
|
19126
|
+
};
|
|
19127
|
+
}
|
|
19128
|
+
function applyBedrockOptions(inferenceConfig, options) {
|
|
19129
|
+
return {
|
|
19130
|
+
...inferenceConfig,
|
|
19131
|
+
...options.temperature !== void 0 && options.temperature !== null ? { temperature: options.temperature } : {},
|
|
19132
|
+
...options.topP !== void 0 && options.topP !== null ? { topP: options.topP } : {},
|
|
19133
|
+
...options.maxOutputTokens !== void 0 && options.maxOutputTokens !== null ? { maxTokens: options.maxOutputTokens } : {}
|
|
19134
|
+
};
|
|
19135
|
+
}
|
|
19136
|
+
function applyTopLevelOptions(payload, options) {
|
|
19137
|
+
const reasoningEnabled = hasActiveThinking(payload.thinking) || "reasoning" in payload || "reasoning_effort" in payload;
|
|
19138
|
+
const next = { ...payload };
|
|
19139
|
+
if (options.temperature !== void 0 && options.temperature !== null && !reasoningEnabled) next.temperature = options.temperature;
|
|
19140
|
+
if (options.topP !== void 0 && options.topP !== null && !reasoningEnabled) next.top_p = options.topP;
|
|
19141
|
+
if (options.topK !== void 0 && options.topK !== null && !reasoningEnabled && isAnthropicPayload(next)) next.top_k = options.topK;
|
|
19142
|
+
if (options.maxOutputTokens !== void 0 && options.maxOutputTokens !== null) {
|
|
19143
|
+
const maxOutputTokens = options.maxOutputTokens;
|
|
19144
|
+
if ("max_output_tokens" in next || isResponsesPayload(next)) next.max_output_tokens = maxOutputTokens;
|
|
19145
|
+
else if ("max_completion_tokens" in next) next.max_completion_tokens = maxOutputTokens;
|
|
19146
|
+
else if ("maxTokens" in next) next.maxTokens = maxOutputTokens;
|
|
19147
|
+
else next.max_tokens = maxOutputTokens;
|
|
19148
|
+
}
|
|
19149
|
+
return next;
|
|
19150
|
+
}
|
|
19151
|
+
function isGooglePayload(payload) {
|
|
19152
|
+
return "contents" in payload && ("config" in payload || "model" in payload);
|
|
19153
|
+
}
|
|
19154
|
+
function isBedrockPayload(payload) {
|
|
19155
|
+
return "inferenceConfig" in payload || "additionalModelRequestFields" in payload;
|
|
19156
|
+
}
|
|
19157
|
+
function isResponsesPayload(payload) {
|
|
19158
|
+
return "input" in payload && !("messages" in payload);
|
|
19159
|
+
}
|
|
19160
|
+
function isAnthropicPayload(payload) {
|
|
19161
|
+
return "anthropic_version" in payload;
|
|
19162
|
+
}
|
|
19163
|
+
function hasActiveThinking(value) {
|
|
19164
|
+
if (!isRecord(value)) return false;
|
|
19165
|
+
const type = value.type;
|
|
19166
|
+
return type !== "disabled" && type !== "off" && type !== false;
|
|
19167
|
+
}
|
|
19168
|
+
function isRecord(value) {
|
|
19169
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19170
|
+
}
|
|
19171
|
+
//#endregion
|
|
18758
19172
|
//#region src/runtime/agent-session-factory.ts
|
|
18759
19173
|
var NO_SKILLS = () => ({
|
|
18760
19174
|
skills: [],
|
|
@@ -18772,10 +19186,17 @@ async function buildAgentSession(args) {
|
|
|
18772
19186
|
agentName: args.agentName,
|
|
18773
19187
|
spanAttributes: args.otelSpanAttrs
|
|
18774
19188
|
});
|
|
19189
|
+
const modelOptions = {
|
|
19190
|
+
temperature: args.temperature,
|
|
19191
|
+
topP: args.topP,
|
|
19192
|
+
topK: args.topK,
|
|
19193
|
+
maxOutputTokens: args.maxOutputTokens
|
|
19194
|
+
};
|
|
19195
|
+
const extensionFactories = hasPiModelOptions(modelOptions) ? [piOtelExtension, createPiModelOptionsExtension(modelOptions)] : [piOtelExtension];
|
|
18775
19196
|
const resourceLoader = new DefaultResourceLoader({
|
|
18776
19197
|
cwd: args.cwdPath,
|
|
18777
19198
|
agentDir: args.piAuthDir,
|
|
18778
|
-
extensionFactories
|
|
19199
|
+
extensionFactories,
|
|
18779
19200
|
appendSystemPrompt: args.appendSystemPrompt,
|
|
18780
19201
|
skillsOverride: args.skillsOverride ?? NO_SKILLS
|
|
18781
19202
|
});
|
|
@@ -18789,6 +19210,7 @@ async function buildAgentSession(args) {
|
|
|
18789
19210
|
agentDir: args.piAuthDir,
|
|
18790
19211
|
cwd: args.cwdPath,
|
|
18791
19212
|
model: args.modelHandle,
|
|
19213
|
+
thinkingLevel: args.thinkingLevel ?? void 0,
|
|
18792
19214
|
customTools: args.customTools,
|
|
18793
19215
|
sessionManager,
|
|
18794
19216
|
resourceLoader
|
|
@@ -24052,6 +24474,11 @@ function createSubagentTool(args) {
|
|
|
24052
24474
|
cwdPath: args.cwdPath ?? args.mountPath,
|
|
24053
24475
|
piAuthDir: args.piAuthDir,
|
|
24054
24476
|
modelHandle: args.modelHandle,
|
|
24477
|
+
thinkingLevel: args.thinkingLevel,
|
|
24478
|
+
temperature: args.temperature,
|
|
24479
|
+
topP: args.topP,
|
|
24480
|
+
topK: args.topK,
|
|
24481
|
+
maxOutputTokens: args.maxOutputTokens,
|
|
24055
24482
|
agentName: args.agentName,
|
|
24056
24483
|
customTools: [...args.inheritedCustomTools, submitTool],
|
|
24057
24484
|
appendSystemPrompt: [args.parentRuntimeInstructor, subagentInstructor],
|
|
@@ -24119,7 +24546,7 @@ function subagentToolDescription() {
|
|
|
24119
24546
|
"",
|
|
24120
24547
|
"The subagent starts with no conversation history and only the `task` ",
|
|
24121
24548
|
"string you provide as its instructions. It runs in the same VM with ",
|
|
24122
|
-
"the same tools you have (Gondolin-routed
|
|
24549
|
+
"the same tools you have (Gondolin-routed built-ins, ",
|
|
24123
24550
|
"moltnet_* tools), and is expected to call ",
|
|
24124
24551
|
`\`${SUBAGENT_SUBMIT_TOOL_NAME}\` with a payload matching the named `,
|
|
24125
24552
|
"contract before its session ends.",
|
|
@@ -24611,7 +25038,7 @@ function shouldSkipSeedEntry(sourceEntry, entryName, resolvedTargetDir) {
|
|
|
24611
25038
|
*
|
|
24612
25039
|
* This is the pi-specific task executor. It owns:
|
|
24613
25040
|
* - VM lifecycle (ensureSnapshot + resumeVm + close)
|
|
24614
|
-
* - Gondolin-redirected tool wiring (read/write/edit/bash → VM)
|
|
25041
|
+
* - Gondolin-redirected tool wiring (read/write/edit/bash/ls/find/grep → VM)
|
|
24615
25042
|
* - MoltNet custom tools (diary entries, pack render/judge, etc.)
|
|
24616
25043
|
* - pi createAgentSession + event → TaskReporter bridge
|
|
24617
25044
|
*
|
|
@@ -24622,6 +25049,25 @@ function shouldSkipSeedEntry(sourceEntry, entryName, resolvedTargetDir) {
|
|
|
24622
25049
|
* `AgentRuntime`.
|
|
24623
25050
|
*/
|
|
24624
25051
|
var noopTurnEventHandler = () => {};
|
|
25052
|
+
function createGondolinToolDefinitions(config) {
|
|
25053
|
+
const { vm, mountPath, guestWorkspace } = config;
|
|
25054
|
+
const grepTool = createGrepToolDefinition(mountPath);
|
|
25055
|
+
return [
|
|
25056
|
+
createReadToolDefinition(mountPath, { operations: createGondolinReadOps(vm, mountPath, guestWorkspace) }),
|
|
25057
|
+
createWriteToolDefinition(mountPath, { operations: createGondolinWriteOps(vm, mountPath, guestWorkspace) }),
|
|
25058
|
+
createEditToolDefinition(mountPath, { operations: createGondolinEditOps(vm, mountPath, guestWorkspace) }),
|
|
25059
|
+
createBashToolDefinition(mountPath, { operations: createGondolinBashOps(vm, mountPath, guestWorkspace) }),
|
|
25060
|
+
createLsToolDefinition(mountPath, { operations: createGondolinLsOps(vm, mountPath, guestWorkspace) }),
|
|
25061
|
+
createFindToolDefinition(mountPath, { operations: createGondolinFindOps(vm, mountPath, guestWorkspace) }),
|
|
25062
|
+
{
|
|
25063
|
+
...grepTool,
|
|
25064
|
+
async execute(...args) {
|
|
25065
|
+
const [_id, params, signal] = args;
|
|
25066
|
+
return executeGondolinGrep(vm, mountPath, guestWorkspace, params, signal);
|
|
25067
|
+
}
|
|
25068
|
+
}
|
|
25069
|
+
];
|
|
25070
|
+
}
|
|
24625
25071
|
/**
|
|
24626
25072
|
* Factory that builds a pi-specific `executeTask` function suitable for
|
|
24627
25073
|
* injection into `AgentRuntime`. The returned function caches the resolved
|
|
@@ -24885,12 +25331,11 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
24885
25331
|
slugs: injectedContext.injected.map((r) => r.slug)
|
|
24886
25332
|
});
|
|
24887
25333
|
if (injectedContext.userInlineSuffix) taskPrompt = `${taskPrompt}\n\n---\n\n${injectedContext.userInlineSuffix}`;
|
|
24888
|
-
const gondolinCustomTools =
|
|
24889
|
-
|
|
24890
|
-
|
|
24891
|
-
|
|
24892
|
-
|
|
24893
|
-
];
|
|
25334
|
+
const gondolinCustomTools = createGondolinToolDefinitions({
|
|
25335
|
+
vm: managed.vm,
|
|
25336
|
+
mountPath,
|
|
25337
|
+
guestWorkspace: managed.guestWorkspace
|
|
25338
|
+
});
|
|
24894
25339
|
const { handle: submitToolHandle, tools: submitToolDefs } = resolveSubmitTools(task.taskType, {
|
|
24895
25340
|
model: opts.model,
|
|
24896
25341
|
input: task.input
|
|
@@ -24936,6 +25381,11 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
24936
25381
|
cwdPath,
|
|
24937
25382
|
piAuthDir,
|
|
24938
25383
|
modelHandle,
|
|
25384
|
+
thinkingLevel: opts.thinkingLevel,
|
|
25385
|
+
temperature: opts.temperature,
|
|
25386
|
+
topP: opts.topP,
|
|
25387
|
+
topK: opts.topK,
|
|
25388
|
+
maxOutputTokens: opts.maxOutputTokens,
|
|
24939
25389
|
agentName: opts.agentName,
|
|
24940
25390
|
inheritedCustomTools: [...gondolinCustomTools, ...moltnetTools],
|
|
24941
25391
|
parentRuntimeInstructor: runtimeInstructor,
|
|
@@ -24952,6 +25402,11 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
24952
25402
|
cwdPath,
|
|
24953
25403
|
piAuthDir,
|
|
24954
25404
|
modelHandle,
|
|
25405
|
+
thinkingLevel: opts.thinkingLevel,
|
|
25406
|
+
temperature: opts.temperature,
|
|
25407
|
+
topP: opts.topP,
|
|
25408
|
+
topK: opts.topK,
|
|
25409
|
+
maxOutputTokens: opts.maxOutputTokens,
|
|
24955
25410
|
agentName: opts.agentName,
|
|
24956
25411
|
customTools: [
|
|
24957
25412
|
...gondolinCustomTools,
|
|
@@ -25408,6 +25863,9 @@ function moltnetExtension(pi) {
|
|
|
25408
25863
|
const localWrite = createWriteTool(localCwd);
|
|
25409
25864
|
const localEdit = createEditTool(localCwd);
|
|
25410
25865
|
const localBash = createBashTool(localCwd);
|
|
25866
|
+
const localLs = createLsTool(localCwd);
|
|
25867
|
+
const localFind = createFindTool(localCwd);
|
|
25868
|
+
const localGrep = createGrepTool(localCwd);
|
|
25411
25869
|
const initialGuestWorkspace = path.resolve(localCwd);
|
|
25412
25870
|
let vm = null;
|
|
25413
25871
|
let guestWorkspace = initialGuestWorkspace;
|
|
@@ -25518,6 +25976,24 @@ function moltnetExtension(pi) {
|
|
|
25518
25976
|
return createBashTool(localCwd, { operations: createGondolinBashOps(await ensureVm(ctx), localCwd, guestWorkspace) }).execute(id, params, signal, onUpdate);
|
|
25519
25977
|
}
|
|
25520
25978
|
});
|
|
25979
|
+
pi.registerTool({
|
|
25980
|
+
...localLs,
|
|
25981
|
+
async execute(id, params, signal, onUpdate, ctx) {
|
|
25982
|
+
return createLsTool(localCwd, { operations: createGondolinLsOps(await ensureVm(ctx), localCwd, guestWorkspace) }).execute(id, params, signal, onUpdate);
|
|
25983
|
+
}
|
|
25984
|
+
});
|
|
25985
|
+
pi.registerTool({
|
|
25986
|
+
...localFind,
|
|
25987
|
+
async execute(id, params, signal, onUpdate, ctx) {
|
|
25988
|
+
return createFindTool(localCwd, { operations: createGondolinFindOps(await ensureVm(ctx), localCwd, guestWorkspace) }).execute(id, params, signal, onUpdate);
|
|
25989
|
+
}
|
|
25990
|
+
});
|
|
25991
|
+
pi.registerTool({
|
|
25992
|
+
...localGrep,
|
|
25993
|
+
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
25994
|
+
return executeGondolinGrep(await ensureVm(ctx), localCwd, guestWorkspace, params, signal);
|
|
25995
|
+
}
|
|
25996
|
+
});
|
|
25521
25997
|
pi.on("user_bash", (_event, _ctx) => {
|
|
25522
25998
|
if (!vm) return;
|
|
25523
25999
|
return { operations: createGondolinBashOps(vm, localCwd, guestWorkspace) };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/pi-extension",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MoltNet pi extension — sandboxed tool execution in Gondolin VMs with MoltNet identity and persistent memory",
|
|
6
6
|
"keywords": [
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@earendil-works/gondolin": "^0.9.1",
|
|
37
37
|
"@opentelemetry/api": "^1.9.0",
|
|
38
38
|
"typebox": "^1.2.8",
|
|
39
|
-
"@themoltnet/
|
|
40
|
-
"@themoltnet/
|
|
39
|
+
"@themoltnet/agent-runtime": "0.31.1",
|
|
40
|
+
"@themoltnet/sdk": "0.114.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@earendil-works/pi-coding-agent": ">=0.74.0",
|
|
@@ -61,8 +61,7 @@
|
|
|
61
61
|
"vite": "^8.0.0",
|
|
62
62
|
"vite-plugin-dts": "^4.5.4",
|
|
63
63
|
"vitest": "^3.0.0",
|
|
64
|
-
"@moltnet/crypto-service": "0.1.0"
|
|
65
|
-
"@moltnet/tasks": "0.1.0"
|
|
64
|
+
"@moltnet/crypto-service": "0.1.0"
|
|
66
65
|
},
|
|
67
66
|
"engines": {
|
|
68
67
|
"node": ">=22"
|