@themoltnet/pi-extension 0.20.0 → 0.20.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/dist/index.js +171 -103
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1130,84 +1130,6 @@ var searchDiary = (options) => (options?.client ?? client).post({
|
|
|
1130
1130
|
}
|
|
1131
1131
|
});
|
|
1132
1132
|
/**
|
|
1133
|
-
* Get a digest of recent diary entries.
|
|
1134
|
-
*/
|
|
1135
|
-
var reflectDiary = (options) => (options.client ?? client).get({
|
|
1136
|
-
security: [
|
|
1137
|
-
{
|
|
1138
|
-
scheme: "bearer",
|
|
1139
|
-
type: "http"
|
|
1140
|
-
},
|
|
1141
|
-
{
|
|
1142
|
-
name: "X-Moltnet-Session-Token",
|
|
1143
|
-
type: "apiKey"
|
|
1144
|
-
},
|
|
1145
|
-
{
|
|
1146
|
-
in: "cookie",
|
|
1147
|
-
name: "ory_kratos_session",
|
|
1148
|
-
type: "apiKey"
|
|
1149
|
-
}
|
|
1150
|
-
],
|
|
1151
|
-
url: "/diaries/reflect",
|
|
1152
|
-
...options
|
|
1153
|
-
});
|
|
1154
|
-
/**
|
|
1155
|
-
* [DEPRECATED] Server-side consolidation is obsolete. Compose consolidation suggestions client-side using diary search + clustering. Cluster semantically similar entries and return consolidation suggestions.
|
|
1156
|
-
*
|
|
1157
|
-
* @deprecated
|
|
1158
|
-
*/
|
|
1159
|
-
var consolidateDiary = (options) => (options.client ?? client).post({
|
|
1160
|
-
security: [
|
|
1161
|
-
{
|
|
1162
|
-
scheme: "bearer",
|
|
1163
|
-
type: "http"
|
|
1164
|
-
},
|
|
1165
|
-
{
|
|
1166
|
-
name: "X-Moltnet-Session-Token",
|
|
1167
|
-
type: "apiKey"
|
|
1168
|
-
},
|
|
1169
|
-
{
|
|
1170
|
-
in: "cookie",
|
|
1171
|
-
name: "ory_kratos_session",
|
|
1172
|
-
type: "apiKey"
|
|
1173
|
-
}
|
|
1174
|
-
],
|
|
1175
|
-
url: "/diaries/{id}/consolidate",
|
|
1176
|
-
...options,
|
|
1177
|
-
headers: {
|
|
1178
|
-
"Content-Type": "application/json",
|
|
1179
|
-
...options.headers
|
|
1180
|
-
}
|
|
1181
|
-
});
|
|
1182
|
-
/**
|
|
1183
|
-
* [DEPRECATED] Server-side compilation is obsolete. Use POST /diaries/:id/packs to create custom packs from agent-side entry selection. Compile a token-budget-fitted context pack from diary entries.
|
|
1184
|
-
*
|
|
1185
|
-
* @deprecated
|
|
1186
|
-
*/
|
|
1187
|
-
var compileDiary = (options) => (options.client ?? client).post({
|
|
1188
|
-
security: [
|
|
1189
|
-
{
|
|
1190
|
-
scheme: "bearer",
|
|
1191
|
-
type: "http"
|
|
1192
|
-
},
|
|
1193
|
-
{
|
|
1194
|
-
name: "X-Moltnet-Session-Token",
|
|
1195
|
-
type: "apiKey"
|
|
1196
|
-
},
|
|
1197
|
-
{
|
|
1198
|
-
in: "cookie",
|
|
1199
|
-
name: "ory_kratos_session",
|
|
1200
|
-
type: "apiKey"
|
|
1201
|
-
}
|
|
1202
|
-
],
|
|
1203
|
-
url: "/diaries/{id}/compile",
|
|
1204
|
-
...options,
|
|
1205
|
-
headers: {
|
|
1206
|
-
"Content-Type": "application/json",
|
|
1207
|
-
...options.headers
|
|
1208
|
-
}
|
|
1209
|
-
});
|
|
1210
|
-
/**
|
|
1211
1133
|
* Export the provenance graph for a persisted context pack by ID.
|
|
1212
1134
|
*/
|
|
1213
1135
|
var getContextPackProvenanceById = (options) => (options.client ?? client).get({
|
|
@@ -2683,22 +2605,6 @@ function createDiariesNamespace(context) {
|
|
|
2683
2605
|
path: { id }
|
|
2684
2606
|
}));
|
|
2685
2607
|
},
|
|
2686
|
-
async consolidate(id, body) {
|
|
2687
|
-
return unwrapResult(await consolidateDiary({
|
|
2688
|
-
client,
|
|
2689
|
-
auth,
|
|
2690
|
-
path: { id },
|
|
2691
|
-
body
|
|
2692
|
-
}));
|
|
2693
|
-
},
|
|
2694
|
-
async compile(id, body) {
|
|
2695
|
-
return unwrapResult(await compileDiary({
|
|
2696
|
-
client,
|
|
2697
|
-
auth,
|
|
2698
|
-
path: { id },
|
|
2699
|
-
body
|
|
2700
|
-
}));
|
|
2701
|
-
},
|
|
2702
2608
|
async tags(diaryId, query) {
|
|
2703
2609
|
return unwrapResult(await listDiaryTags({
|
|
2704
2610
|
client,
|
|
@@ -4546,13 +4452,6 @@ function createEntriesNamespace(context) {
|
|
|
4546
4452
|
body
|
|
4547
4453
|
}));
|
|
4548
4454
|
},
|
|
4549
|
-
async reflect(query) {
|
|
4550
|
-
return unwrapResult(await reflectDiary({
|
|
4551
|
-
client,
|
|
4552
|
-
auth,
|
|
4553
|
-
query
|
|
4554
|
-
}));
|
|
4555
|
-
},
|
|
4556
4455
|
async verify(entryId) {
|
|
4557
4456
|
return unwrapResult(await verifyDiaryEntryById({
|
|
4558
4457
|
client,
|
|
@@ -8032,7 +7931,7 @@ function createMoltNetTools(config) {
|
|
|
8032
7931
|
defineTool({
|
|
8033
7932
|
name: "moltnet_host_exec",
|
|
8034
7933
|
label: "Run command on host (escape hatch — requires user approval)",
|
|
8035
|
-
description: "Runs a command on the HOST machine, outside the sandbox VM. The user will be prompted to approve each invocation via a UI dialog — do NOT call this tool speculatively.
|
|
7934
|
+
description: "Runs a command on the HOST machine, outside the sandbox VM. The user will be prompted to approve each invocation via a UI dialog, and in headless task runs there is no one to approve — so do NOT call this tool speculatively. Routine git and gh work — pushing branches, opening pull requests, etc. — runs INSIDE the VM via the normal `bash` tool, where your credentials are already injected; use that, not this escape hatch. Reserve this tool for the rare case that genuinely cannot run in the guest (e.g. reaching a host-only resource the VM has no path to).\n\nAllowed executables: git, gh, moltnet. Runs with a minimal env (PATH, HOME, GIT_CONFIG_GLOBAL, …); pass any additional vars via the `env` parameter (e.g. GH_TOKEN). Every invocation is logged as an auditable host execution.",
|
|
8036
7935
|
parameters: Type.Object({
|
|
8037
7936
|
executable: Type.String({ description: "Executable to run (git | gh | moltnet)" }),
|
|
8038
7937
|
args: Type.Array(Type.String(), { description: "Arguments to pass to the executable" }),
|
|
@@ -9477,6 +9376,59 @@ var CuratePackOutput = Type$1.Object({
|
|
|
9477
9376
|
additionalProperties: false
|
|
9478
9377
|
});
|
|
9479
9378
|
//#endregion
|
|
9379
|
+
//#region ../tasks/src/task-types/freeform.ts
|
|
9380
|
+
var FREEFORM_TYPE = "freeform";
|
|
9381
|
+
var FreeformTaskTypeProposal = Type$1.Object({
|
|
9382
|
+
name: Type$1.String({ minLength: 1 }),
|
|
9383
|
+
rationale: Type$1.String({ minLength: 1 }),
|
|
9384
|
+
inputShape: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.Unknown())),
|
|
9385
|
+
outputShape: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.Unknown()))
|
|
9386
|
+
}, {
|
|
9387
|
+
$id: "FreeformTaskTypeProposal",
|
|
9388
|
+
additionalProperties: false
|
|
9389
|
+
});
|
|
9390
|
+
var FreeformInput = Type$1.Object({
|
|
9391
|
+
title: Type$1.Optional(Type$1.String({ minLength: 1 })),
|
|
9392
|
+
brief: Type$1.String({ minLength: 1 }),
|
|
9393
|
+
expectedOutput: Type$1.Optional(Type$1.String({ minLength: 1 })),
|
|
9394
|
+
constraints: Type$1.Optional(Type$1.Array(Type$1.String({ minLength: 1 }), { maxItems: 20 })),
|
|
9395
|
+
suggestedTaskType: Type$1.Optional(Type$1.String({ minLength: 1 })),
|
|
9396
|
+
successCriteria: Type$1.Optional(SuccessCriteria),
|
|
9397
|
+
context: Type$1.Optional(TaskContext)
|
|
9398
|
+
}, {
|
|
9399
|
+
$id: "FreeformInput",
|
|
9400
|
+
additionalProperties: false
|
|
9401
|
+
});
|
|
9402
|
+
var FreeformArtifact = Type$1.Object({
|
|
9403
|
+
kind: Type$1.String({ minLength: 1 }),
|
|
9404
|
+
title: Type$1.String({ minLength: 1 }),
|
|
9405
|
+
description: Type$1.Optional(Type$1.String({ minLength: 1 })),
|
|
9406
|
+
url: Type$1.Optional(Type$1.String({ minLength: 1 })),
|
|
9407
|
+
path: Type$1.Optional(Type$1.String({ minLength: 1 }))
|
|
9408
|
+
}, {
|
|
9409
|
+
$id: "FreeformArtifact",
|
|
9410
|
+
additionalProperties: false
|
|
9411
|
+
});
|
|
9412
|
+
var FreeformFollowUpTask = Type$1.Object({
|
|
9413
|
+
title: Type$1.String({ minLength: 1 }),
|
|
9414
|
+
brief: Type$1.String({ minLength: 1 }),
|
|
9415
|
+
suggestedTaskType: Type$1.Optional(Type$1.String({ minLength: 1 }))
|
|
9416
|
+
}, {
|
|
9417
|
+
$id: "FreeformFollowUpTask",
|
|
9418
|
+
additionalProperties: false
|
|
9419
|
+
});
|
|
9420
|
+
var FreeformOutput = Type$1.Object({
|
|
9421
|
+
summary: Type$1.String({ minLength: 1 }),
|
|
9422
|
+
artifacts: Type$1.Optional(Type$1.Array(FreeformArtifact, { maxItems: 20 })),
|
|
9423
|
+
proposedTaskType: Type$1.Optional(FreeformTaskTypeProposal),
|
|
9424
|
+
followUpTasks: Type$1.Optional(Type$1.Array(FreeformFollowUpTask, { maxItems: 20 })),
|
|
9425
|
+
diaryEntryIds: Type$1.Optional(Type$1.Array(Type$1.String({ format: "uuid" }))),
|
|
9426
|
+
verification: Type$1.Optional(VerificationRecord)
|
|
9427
|
+
}, {
|
|
9428
|
+
$id: "FreeformOutput",
|
|
9429
|
+
additionalProperties: false
|
|
9430
|
+
});
|
|
9431
|
+
//#endregion
|
|
9480
9432
|
//#region ../tasks/src/task-types/fulfill-brief.ts
|
|
9481
9433
|
/**
|
|
9482
9434
|
* `fulfill_brief` — produce a signed change against a coding brief.
|
|
@@ -10035,6 +9987,16 @@ function requireVerificationWhenCriteriaPresent(output, input) {
|
|
|
10035
9987
|
* / claiming a task.
|
|
10036
9988
|
*/
|
|
10037
9989
|
var BUILT_IN_TASK_TYPES = {
|
|
9990
|
+
[FREEFORM_TYPE]: {
|
|
9991
|
+
name: FREEFORM_TYPE,
|
|
9992
|
+
inputSchema: FreeformInput,
|
|
9993
|
+
outputSchema: FreeformOutput,
|
|
9994
|
+
outputKind: "artifact",
|
|
9995
|
+
workspaceScope: "attempt",
|
|
9996
|
+
sessionScope: "none",
|
|
9997
|
+
requiresReferences: false,
|
|
9998
|
+
validateOutput: requireVerificationWhenCriteriaPresent
|
|
9999
|
+
},
|
|
10038
10000
|
[FULFILL_BRIEF_TYPE]: {
|
|
10039
10001
|
name: FULFILL_BRIEF_TYPE,
|
|
10040
10002
|
inputSchema: FulfillBriefInput,
|
|
@@ -10967,6 +10929,97 @@ function buildCuratePackUserPrompt(input, ctx) {
|
|
|
10967
10929
|
]);
|
|
10968
10930
|
}
|
|
10969
10931
|
//#endregion
|
|
10932
|
+
//#region ../agent-runtime/src/prompts/freeform.ts
|
|
10933
|
+
function buildFreeformUserPrompt(input, ctx) {
|
|
10934
|
+
const header = [
|
|
10935
|
+
"# Freeform Task Agent",
|
|
10936
|
+
"",
|
|
10937
|
+
"You are handling an exploratory MoltNet task that does not yet have a",
|
|
10938
|
+
"more specific execution contract. Treat the brief as the source of truth,",
|
|
10939
|
+
"use judgment, and keep the result useful enough for a human or another",
|
|
10940
|
+
"agent to continue from it.",
|
|
10941
|
+
"",
|
|
10942
|
+
`Task id: \`${ctx.taskId}\``
|
|
10943
|
+
].join("\n");
|
|
10944
|
+
const expectedOutput = input.expectedOutput ?? "";
|
|
10945
|
+
const constraints = input.constraints?.length ? input.constraints.map((constraint) => `- ${constraint}`).join("\n") : "";
|
|
10946
|
+
const suggestedTaskType = input.suggestedTaskType ? [`The proposer suggested task type \`${input.suggestedTaskType}\`.`, "Use it as a hint, not as a contract."].join("\n") : "";
|
|
10947
|
+
const workflow = [
|
|
10948
|
+
"1. Clarify the real objective from the brief before acting.",
|
|
10949
|
+
"2. Gather enough context to avoid guessing.",
|
|
10950
|
+
"3. Complete the requested work when it is safe and bounded.",
|
|
10951
|
+
"4. If the request reveals a recurring task shape, include a",
|
|
10952
|
+
" `proposedTaskType` in the final output with a concise rationale.",
|
|
10953
|
+
"5. If the work should be split or continued, include `followUpTasks`."
|
|
10954
|
+
].join("\n");
|
|
10955
|
+
return assembleTaskPrompt("freeform", [
|
|
10956
|
+
{
|
|
10957
|
+
id: "freeform.header",
|
|
10958
|
+
source: "header",
|
|
10959
|
+
body: header
|
|
10960
|
+
},
|
|
10961
|
+
{
|
|
10962
|
+
id: "freeform.title",
|
|
10963
|
+
source: "task_input",
|
|
10964
|
+
header: "Title",
|
|
10965
|
+
body: input.title ?? ""
|
|
10966
|
+
},
|
|
10967
|
+
{
|
|
10968
|
+
id: "freeform.brief",
|
|
10969
|
+
source: "task_input",
|
|
10970
|
+
header: "Brief",
|
|
10971
|
+
body: input.brief
|
|
10972
|
+
},
|
|
10973
|
+
{
|
|
10974
|
+
id: "freeform.expected_output",
|
|
10975
|
+
source: "task_input",
|
|
10976
|
+
header: "Expected Output",
|
|
10977
|
+
body: expectedOutput
|
|
10978
|
+
},
|
|
10979
|
+
{
|
|
10980
|
+
id: "freeform.constraints",
|
|
10981
|
+
source: "task_input",
|
|
10982
|
+
header: "Constraints",
|
|
10983
|
+
body: constraints
|
|
10984
|
+
},
|
|
10985
|
+
{
|
|
10986
|
+
id: "freeform.suggested_task_type",
|
|
10987
|
+
source: "task_input",
|
|
10988
|
+
header: "Suggested Task Type",
|
|
10989
|
+
body: suggestedTaskType
|
|
10990
|
+
},
|
|
10991
|
+
{
|
|
10992
|
+
id: "freeform.workflow",
|
|
10993
|
+
source: "static",
|
|
10994
|
+
header: "Workflow",
|
|
10995
|
+
body: workflow
|
|
10996
|
+
},
|
|
10997
|
+
{
|
|
10998
|
+
id: "freeform.verification",
|
|
10999
|
+
source: "verification",
|
|
11000
|
+
body: buildSelfVerificationBlock(ctx.taskId)
|
|
11001
|
+
},
|
|
11002
|
+
{
|
|
11003
|
+
id: "freeform.final_output",
|
|
11004
|
+
source: "final_output",
|
|
11005
|
+
body: buildFinalOutputBlock({
|
|
11006
|
+
taskType: "freeform",
|
|
11007
|
+
outputSchemaName: "FreeformOutput",
|
|
11008
|
+
shapeSketch: [
|
|
11009
|
+
"{",
|
|
11010
|
+
" \"summary\": \"<2-5 sentence result>\",",
|
|
11011
|
+
" \"artifacts\": [{ \"kind\": \"...\", \"title\": \"...\", \"description\": \"...\", \"url\": \"...\", \"path\": \"...\" }],",
|
|
11012
|
+
" \"proposedTaskType\": { \"name\": \"...\", \"rationale\": \"...\", \"inputShape\": {}, \"outputShape\": {} },",
|
|
11013
|
+
" \"followUpTasks\": [{ \"title\": \"...\", \"brief\": \"...\", \"suggestedTaskType\": \"...\" }],",
|
|
11014
|
+
" \"diaryEntryIds\": [\"...\"],",
|
|
11015
|
+
" \"verification\": <required iff input.successCriteria; see Self-verification>",
|
|
11016
|
+
"}"
|
|
11017
|
+
].join("\n")
|
|
11018
|
+
})
|
|
11019
|
+
}
|
|
11020
|
+
]);
|
|
11021
|
+
}
|
|
11022
|
+
//#endregion
|
|
10970
11023
|
//#region ../agent-runtime/src/prompts/fulfill-brief.ts
|
|
10971
11024
|
/**
|
|
10972
11025
|
* Build the first user-message prompt for a `fulfill_brief` task.
|
|
@@ -11016,7 +11069,11 @@ function buildFulfillBriefUserPrompt(input, ctx) {
|
|
|
11016
11069
|
"5. For every commit, create a signed diary entry first via",
|
|
11017
11070
|
" `moltnet_create_entry` and embed its id in the commit trailer",
|
|
11018
11071
|
" `MoltNet-Diary: <id>` (per the runtime instructor).",
|
|
11019
|
-
"6. Push the branch and open a PR
|
|
11072
|
+
"6. Push the branch and open a PR — run `git push` and `gh pr create`",
|
|
11073
|
+
" IN the VM with your normal `bash` tool (use the",
|
|
11074
|
+
" `GH_TOKEN=$(moltnet github token …) gh …` form from the runtime",
|
|
11075
|
+
" instructor). Do NOT use `moltnet_host_exec` for this; it needs human",
|
|
11076
|
+
" approval that is unavailable in a headless run."
|
|
11020
11077
|
].join("\n");
|
|
11021
11078
|
return assembleTaskPrompt("fulfill_brief", [
|
|
11022
11079
|
{
|
|
@@ -11716,6 +11773,12 @@ function buildRunEvalUserPrompt(input, ctx) {
|
|
|
11716
11773
|
*/
|
|
11717
11774
|
function buildTaskUserPrompt(task, ctx) {
|
|
11718
11775
|
switch (task.taskType) {
|
|
11776
|
+
case FREEFORM_TYPE:
|
|
11777
|
+
if (!Value.Check(FreeformInput, task.input)) {
|
|
11778
|
+
const errors = [...Value.Errors(FreeformInput, task.input)];
|
|
11779
|
+
throw new Error(`freeform input failed validation: ${JSON.stringify(errors.slice(0, 3))}`);
|
|
11780
|
+
}
|
|
11781
|
+
return buildFreeformUserPrompt(task.input, { taskId: ctx.taskId });
|
|
11719
11782
|
case FULFILL_BRIEF_TYPE:
|
|
11720
11783
|
if (!Value.Check(FulfillBriefInput, task.input)) {
|
|
11721
11784
|
const errors = [...Value.Errors(FulfillBriefInput, task.input)];
|
|
@@ -15453,6 +15516,11 @@ function buildRuntimeInstructor(ctx) {
|
|
|
15453
15516
|
"",
|
|
15454
15517
|
"- `git push` uses the gitconfig-configured credential helper and is not",
|
|
15455
15518
|
" a `gh` call — it does not need `GH_TOKEN`.",
|
|
15519
|
+
"- Run `git` and `gh` in the VM with your normal `bash` tool — your",
|
|
15520
|
+
" credentials are injected here, so they work in the guest. The",
|
|
15521
|
+
" `moltnet_host_exec` tool is a last-resort host escape-hatch that",
|
|
15522
|
+
" requires human approval and is unavailable in headless task runs;",
|
|
15523
|
+
" never use it for routine git/gh.",
|
|
15456
15524
|
"",
|
|
15457
15525
|
"## Diary discipline",
|
|
15458
15526
|
"",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/pi-extension",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.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
|
"license": "MIT",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@earendil-works/gondolin": "^0.9.1",
|
|
32
32
|
"@opentelemetry/api": "^1.9.0",
|
|
33
33
|
"@sinclair/typebox": "^0.34.0",
|
|
34
|
-
"@themoltnet/
|
|
35
|
-
"@themoltnet/
|
|
34
|
+
"@themoltnet/agent-runtime": "0.19.1",
|
|
35
|
+
"@themoltnet/sdk": "0.106.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@earendil-works/pi-coding-agent": ">=0.74.0",
|