@themoltnet/pi-extension 0.26.5 → 0.27.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.
Files changed (2) hide show
  1. package/dist/index.js +241 -35
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync,
4
4
  import path, { join, relative, sep } from "node:path";
5
5
  import { DefaultResourceLoader, SessionManager, createAgentSession, createBashTool, createBashToolDefinition, createEditTool, createEditToolDefinition, createReadTool, createReadToolDefinition, createSyntheticSourceInfo, createWriteTool, createWriteToolDefinition, defineTool, parseFrontmatter } from "@earendil-works/pi-coding-agent";
6
6
  import { createHash } from "node:crypto";
7
+ import { Readable } from "node:stream";
7
8
  import crypto, { createHash as createHash$1 } from "crypto";
8
9
  import { readFile } from "node:fs/promises";
9
10
  import { homedir } from "node:os";
@@ -1818,6 +1819,55 @@ var updateRuntimeProfile = (options) => (options.client ?? client).patch({
1818
1819
  }
1819
1820
  });
1820
1821
  /**
1822
+ * Get metadata for the durable team-scoped runtime session for a task attempt.
1823
+ */
1824
+ var getRuntimeSession = (options) => (options.client ?? client).get({
1825
+ security: [
1826
+ {
1827
+ scheme: "bearer",
1828
+ type: "http"
1829
+ },
1830
+ {
1831
+ name: "X-Moltnet-Session-Token",
1832
+ type: "apiKey"
1833
+ },
1834
+ {
1835
+ in: "cookie",
1836
+ name: "ory_kratos_session",
1837
+ type: "apiKey"
1838
+ }
1839
+ ],
1840
+ url: "/runtime-sessions/{taskId}/{attemptN}",
1841
+ ...options
1842
+ });
1843
+ /**
1844
+ * Stream or replace the durable team-scoped runtime session content for a task attempt.
1845
+ */
1846
+ var uploadRuntimeSession = (options) => (options.client ?? client).put({
1847
+ bodySerializer: null,
1848
+ security: [
1849
+ {
1850
+ scheme: "bearer",
1851
+ type: "http"
1852
+ },
1853
+ {
1854
+ name: "X-Moltnet-Session-Token",
1855
+ type: "apiKey"
1856
+ },
1857
+ {
1858
+ in: "cookie",
1859
+ name: "ory_kratos_session",
1860
+ type: "apiKey"
1861
+ }
1862
+ ],
1863
+ url: "/runtime-sessions/{taskId}/{attemptN}/content",
1864
+ ...options,
1865
+ headers: {
1866
+ "Content-Type": "application/octet-stream",
1867
+ ...options.headers
1868
+ }
1869
+ });
1870
+ /**
1821
1871
  * Upsert a team-scoped runtime slot for audit and continuation affinity lookup.
1822
1872
  */
1823
1873
  var beginRuntimeSlot = (options) => (options.client ?? client).post({
@@ -2831,46 +2881,66 @@ function createCryptoNamespace(context, signingRequests) {
2831
2881
  };
2832
2882
  }
2833
2883
  //#endregion
2884
+ //#region ../sdk/src/namespaces/team-headers.ts
2885
+ /**
2886
+ * Build the team header from an optional option, or `undefined` when no team
2887
+ * context was supplied. Used by diaries and runtime-profiles, whose endpoints
2888
+ * accept the header optionally.
2889
+ */
2890
+ function teamHeaders(options) {
2891
+ return options?.teamId ? { "x-moltnet-team-id": options.teamId } : void 0;
2892
+ }
2893
+ /**
2894
+ * Build the team header from a required option. Used by tasks and
2895
+ * runtime-slots, whose endpoints mandate the header.
2896
+ */
2897
+ function requiredTeamHeaders(options) {
2898
+ return { "x-moltnet-team-id": options.teamId };
2899
+ }
2900
+ //#endregion
2834
2901
  //#region ../sdk/src/namespaces/diaries.ts
2835
2902
  function createDiariesNamespace(context) {
2836
2903
  const { client, auth } = context;
2837
2904
  return {
2838
- async list(query, headers) {
2905
+ async list(query, options) {
2839
2906
  return unwrapResult(await listDiaries({
2840
2907
  client,
2841
2908
  auth,
2842
2909
  query,
2843
- headers
2910
+ headers: teamHeaders(options)
2844
2911
  }));
2845
2912
  },
2846
- async create(body, headers) {
2913
+ async create(body, options) {
2847
2914
  return unwrapResult(await createDiary({
2848
2915
  client,
2849
2916
  auth,
2850
2917
  body,
2851
- headers
2918
+ headers: requiredTeamHeaders(options)
2852
2919
  }));
2853
2920
  },
2854
- async get(id) {
2921
+ async get(id, options) {
2855
2922
  return unwrapResult(await getDiary({
2856
2923
  client,
2857
2924
  auth,
2858
- path: { id }
2925
+ path: { id },
2926
+ headers: teamHeaders(options)
2859
2927
  }));
2860
2928
  },
2861
- async update(id, body) {
2929
+ async update(id, body, options) {
2862
2930
  return unwrapResult(await updateDiary({
2863
2931
  client,
2864
2932
  auth,
2865
2933
  path: { id },
2866
- body
2934
+ body,
2935
+ headers: teamHeaders(options)
2867
2936
  }));
2868
2937
  },
2869
- async delete(id) {
2938
+ async delete(id, options) {
2870
2939
  return unwrapResult(await deleteDiary({
2871
2940
  client,
2872
2941
  auth,
2873
- path: { id }
2942
+ path: { id },
2943
+ headers: teamHeaders(options)
2874
2944
  }));
2875
2945
  },
2876
2946
  async tags(diaryId, query) {
@@ -4981,14 +5051,14 @@ function createRuntimeProfilesNamespace(context) {
4981
5051
  return unwrapResult(await listRuntimeProfiles({
4982
5052
  client,
4983
5053
  auth,
4984
- headers: teamHeaders$1(options)
5054
+ headers: teamHeaders(options)
4985
5055
  }));
4986
5056
  },
4987
5057
  async create(body, options) {
4988
5058
  return unwrapResult(await createRuntimeProfile({
4989
5059
  client,
4990
5060
  auth,
4991
- headers: teamHeaders$1(options),
5061
+ headers: teamHeaders(options),
4992
5062
  body
4993
5063
  }));
4994
5064
  },
@@ -5017,8 +5087,56 @@ function createRuntimeProfilesNamespace(context) {
5017
5087
  }
5018
5088
  };
5019
5089
  }
5020
- function teamHeaders$1(options) {
5021
- return options?.teamId ? { "x-moltnet-team-id": options.teamId } : void 0;
5090
+ //#endregion
5091
+ //#region ../sdk/src/namespaces/runtime-sessions.ts
5092
+ function createRuntimeSessionsNamespace(context) {
5093
+ const { client, auth } = context;
5094
+ return {
5095
+ async getForAttempt(path, options) {
5096
+ try {
5097
+ return unwrapResult(await getRuntimeSession({
5098
+ client,
5099
+ auth,
5100
+ headers: requiredTeamHeaders(options),
5101
+ path
5102
+ }));
5103
+ } catch (err) {
5104
+ if (err instanceof MoltNetError && err.statusCode === 404) return null;
5105
+ throw err;
5106
+ }
5107
+ },
5108
+ async upload(path, body, query, options) {
5109
+ return unwrapResult(await uploadRuntimeSession({
5110
+ auth,
5111
+ body,
5112
+ client,
5113
+ duplex: "half",
5114
+ headers: {
5115
+ ...requiredTeamHeaders(options),
5116
+ "content-type": "application/octet-stream"
5117
+ },
5118
+ path,
5119
+ query
5120
+ }));
5121
+ },
5122
+ async download(path, options) {
5123
+ const stream = unwrapResult(await client.request({
5124
+ auth,
5125
+ headers: requiredTeamHeaders(options),
5126
+ method: "GET",
5127
+ parseAs: "stream",
5128
+ path,
5129
+ security: [{
5130
+ scheme: "bearer",
5131
+ type: "http"
5132
+ }],
5133
+ url: "/runtime-sessions/{taskId}/{attemptN}/content"
5134
+ }));
5135
+ if (stream instanceof Readable) return stream;
5136
+ if (stream instanceof ReadableStream) return Readable.fromWeb(stream);
5137
+ throw new MoltNetError("Unexpected runtime session download response stream", { code: "INVALID_RESPONSE" });
5138
+ }
5139
+ };
5022
5140
  }
5023
5141
  //#endregion
5024
5142
  //#region ../sdk/src/namespaces/runtime-slots.ts
@@ -5029,7 +5147,7 @@ function createRuntimeSlotsNamespace(context) {
5029
5147
  return unwrapResult(await beginRuntimeSlot({
5030
5148
  client,
5031
5149
  auth,
5032
- headers: teamHeaders(options),
5150
+ headers: requiredTeamHeaders(options),
5033
5151
  body
5034
5152
  }));
5035
5153
  },
@@ -5037,7 +5155,7 @@ function createRuntimeSlotsNamespace(context) {
5037
5155
  return unwrapResult(await finishRuntimeSlot({
5038
5156
  client,
5039
5157
  auth,
5040
- headers: teamHeaders(options),
5158
+ headers: requiredTeamHeaders(options),
5041
5159
  body
5042
5160
  }));
5043
5161
  },
@@ -5046,7 +5164,7 @@ function createRuntimeSlotsNamespace(context) {
5046
5164
  return unwrapResult(await findLatestRuntimeSlotForAttempt({
5047
5165
  client,
5048
5166
  auth,
5049
- headers: teamHeaders(options),
5167
+ headers: requiredTeamHeaders(options),
5050
5168
  query
5051
5169
  }));
5052
5170
  } catch (err) {
@@ -5056,9 +5174,6 @@ function createRuntimeSlotsNamespace(context) {
5056
5174
  }
5057
5175
  };
5058
5176
  }
5059
- function teamHeaders(options) {
5060
- return { "x-moltnet-team-id": options.teamId };
5061
- }
5062
5177
  //#endregion
5063
5178
  //#region ../sdk/src/namespaces/signing-requests.ts
5064
5179
  function createSigningRequestsNamespace(context) {
@@ -9395,6 +9510,16 @@ var RuntimeProfileToolName = String$1({
9395
9510
  maxLength: 128,
9396
9511
  pattern: "^[a-zA-Z0-9._/-]+$"
9397
9512
  });
9513
+ var RuntimeProfileWorkspaceMode = Union([
9514
+ Literal("none"),
9515
+ Literal("shared_mount"),
9516
+ Literal("dedicated_worktree")
9517
+ ]);
9518
+ var RuntimeProfileAllowedWorkspaceModes = _Array_(RuntimeProfileWorkspaceMode, {
9519
+ minItems: 1,
9520
+ maxItems: 3,
9521
+ uniqueItems: true
9522
+ });
9398
9523
  var SandboxResumeCommandWhenSchema = _Object_({ workspaceMode: Optional(_Array_(Union([
9399
9524
  Literal("shared_mount"),
9400
9525
  Literal("dedicated_worktree"),
@@ -9498,6 +9623,14 @@ var RuntimeProfileMaxBatchSize = Integer({
9498
9623
  minimum: 1,
9499
9624
  maximum: 1e3
9500
9625
  });
9626
+ var RuntimeProfileMaxTurns = Integer({
9627
+ minimum: 0,
9628
+ maximum: 1e4
9629
+ });
9630
+ var RuntimeProfileMaxBashTimeouts = Integer({
9631
+ minimum: 0,
9632
+ maximum: 1e3
9633
+ });
9501
9634
  _Object_({
9502
9635
  id: String$1({ format: "uuid" }),
9503
9636
  teamId: String$1({ format: "uuid" }),
@@ -9515,6 +9648,8 @@ _Object_({
9515
9648
  sandbox: RuntimeProfileSandbox,
9516
9649
  sessionStorageMode: Literal("local"),
9517
9650
  workspaceStorageMode: Literal("local"),
9651
+ defaultWorkspaceMode: Union([RuntimeProfileWorkspaceMode, Null()]),
9652
+ allowedWorkspaceModes: RuntimeProfileAllowedWorkspaceModes,
9518
9653
  sessionTtlSec: Integer({
9519
9654
  minimum: 1,
9520
9655
  maximum: 86400
@@ -9526,6 +9661,8 @@ _Object_({
9526
9661
  leaseTtlSec: RuntimeProfileLeaseTtlSec,
9527
9662
  heartbeatIntervalMs: RuntimeProfileHeartbeatIntervalMs,
9528
9663
  maxBatchSize: RuntimeProfileMaxBatchSize,
9664
+ maxTurns: RuntimeProfileMaxTurns,
9665
+ maxBashTimeouts: RuntimeProfileMaxBashTimeouts,
9529
9666
  requiredEnv: _Array_(RuntimeProfileEnvName, { maxItems: 100 }),
9530
9667
  requiredTools: _Array_(RuntimeProfileToolName, { maxItems: 100 }),
9531
9668
  context: _Array_(RuntimeProfileContext, { maxItems: 5 }),
@@ -9543,6 +9680,64 @@ _Object_({
9543
9680
  additionalProperties: false
9544
9681
  });
9545
9682
  //#endregion
9683
+ //#region ../tasks/src/runtime-sessions.ts
9684
+ var RuntimeSessionKind = Union([
9685
+ Literal("root"),
9686
+ Literal("extend"),
9687
+ Literal("fork")
9688
+ ]);
9689
+ var RuntimeSessionCheckpointKind = Union([Literal("attempt_final")]);
9690
+ _Object_({
9691
+ id: String$1({ format: "uuid" }),
9692
+ teamId: String$1({ format: "uuid" }),
9693
+ taskId: String$1({ format: "uuid" }),
9694
+ attemptN: Integer({ minimum: 1 }),
9695
+ sourceSlotId: Union([String$1({ format: "uuid" }), Null()]),
9696
+ sourceRuntimeProfileId: Union([String$1({ format: "uuid" }), Null()]),
9697
+ sessionKind: RuntimeSessionKind,
9698
+ parentSessionId: Union([String$1({ format: "uuid" }), Null()]),
9699
+ contentType: String$1({
9700
+ minLength: 1,
9701
+ maxLength: 200
9702
+ }),
9703
+ contentEncoding: Union([String$1({
9704
+ minLength: 1,
9705
+ maxLength: 100
9706
+ }), Null()]),
9707
+ sizeBytes: Integer({ minimum: 0 }),
9708
+ sha256: String$1({
9709
+ minLength: 64,
9710
+ maxLength: 64
9711
+ }),
9712
+ storageClass: String$1({
9713
+ minLength: 1,
9714
+ maxLength: 100
9715
+ }),
9716
+ checkpointKind: RuntimeSessionCheckpointKind,
9717
+ uploadedAt: String$1({ format: "date-time" })
9718
+ }, { $id: "RuntimeSession" });
9719
+ _Object_({
9720
+ sourceSlotId: Optional(String$1({ format: "uuid" })),
9721
+ sourceRuntimeProfileId: Optional(String$1({ format: "uuid" })),
9722
+ sessionKind: RuntimeSessionKind,
9723
+ parentSessionId: Optional(String$1({ format: "uuid" }))
9724
+ }, {
9725
+ $id: "UploadRuntimeSessionQuery",
9726
+ additionalProperties: false
9727
+ });
9728
+ String$1({
9729
+ $id: "RuntimeSessionContent",
9730
+ description: "Runtime session content stream.",
9731
+ format: "binary"
9732
+ });
9733
+ _Object_({
9734
+ taskId: String$1({ format: "uuid" }),
9735
+ attemptN: Integer({ minimum: 1 })
9736
+ }, {
9737
+ $id: "RuntimeSessionAttemptParams",
9738
+ additionalProperties: false
9739
+ });
9740
+ //#endregion
9546
9741
  //#region ../tasks/src/runtime-slots.ts
9547
9742
  var RuntimeWorkspaceKind = Union([
9548
9743
  Literal("origin"),
@@ -13782,6 +13977,7 @@ var TaskBuilder = class {
13782
13977
  inputData;
13783
13978
  refs = [];
13784
13979
  body = {};
13980
+ teamIdValue;
13785
13981
  constructor(taskType, input) {
13786
13982
  this.taskType = taskType;
13787
13983
  this.inputData = { ...input };
@@ -13920,7 +14116,7 @@ var TaskBuilder = class {
13920
14116
  * @returns This builder, for chaining.
13921
14117
  */
13922
14118
  team(teamId) {
13923
- this.body.teamId = teamId;
14119
+ this.teamIdValue = teamId;
13924
14120
  return this;
13925
14121
  }
13926
14122
  /**
@@ -14031,16 +14227,17 @@ var TaskBuilder = class {
14031
14227
  * generated `correlationId` when omitted, so the persisted top-level body may
14032
14228
  * gain that one field.
14033
14229
  *
14034
- * @returns A validated `CreateTaskData['body']`.
14230
+ * @returns A {@link BuiltTask}: the validated body plus the team context
14231
+ * (which travels as the `x-moltnet-team-id` header, not the body).
14035
14232
  * @throws {TaskBuildError} when required fields are missing or the payload
14036
14233
  * fails the shared `@moltnet/tasks` validation, with field-level detail.
14037
14234
  * @example
14038
- * const body = buildFreeform({ brief }).team(t).diary(d).build();
14039
- * await agent.tasks.create(body);
14235
+ * const built = buildFreeform({ brief }).team(t).diary(d).build();
14236
+ * await agent.tasks.create(built);
14040
14237
  */
14041
14238
  build() {
14042
14239
  const missing = [];
14043
- if (!this.body.teamId) missing.push({
14240
+ if (!this.teamIdValue) missing.push({
14044
14241
  field: "teamId",
14045
14242
  message: "teamId is required"
14046
14243
  });
@@ -14058,12 +14255,14 @@ var TaskBuilder = class {
14058
14255
  const all = [...missing, ...validationErrors];
14059
14256
  if (all.length > 0) throw new TaskBuildError(all);
14060
14257
  return {
14061
- ...this.body,
14062
- taskType: this.taskType,
14063
- input: normalizedInput,
14064
- teamId: this.body.teamId,
14065
- diaryId: this.body.diaryId,
14066
- ...references ? { references } : {}
14258
+ body: {
14259
+ ...this.body,
14260
+ taskType: this.taskType,
14261
+ input: normalizedInput,
14262
+ diaryId: this.body.diaryId,
14263
+ ...references ? { references } : {}
14264
+ },
14265
+ teamId: this.teamIdValue
14067
14266
  };
14068
14267
  }
14069
14268
  };
@@ -14312,18 +14511,24 @@ function createTasksNamespace(context) {
14312
14511
  auth
14313
14512
  }));
14314
14513
  },
14315
- async list(query) {
14514
+ async list(query, options) {
14316
14515
  return unwrapResult(await listTasks({
14317
14516
  client,
14318
14517
  auth,
14319
- query
14518
+ query,
14519
+ headers: requiredTeamHeaders(options)
14320
14520
  }));
14321
14521
  },
14322
- async create(body) {
14522
+ async create(bodyOrBuilt, options) {
14523
+ const { body, teamId } = options !== void 0 ? {
14524
+ body: bodyOrBuilt,
14525
+ teamId: options.teamId
14526
+ } : bodyOrBuilt;
14323
14527
  return unwrapResult(await createTask({
14324
14528
  client,
14325
14529
  auth,
14326
- body
14530
+ body,
14531
+ headers: requiredTeamHeaders({ teamId })
14327
14532
  }));
14328
14533
  },
14329
14534
  buildTask,
@@ -14621,6 +14826,7 @@ function createAgent(options) {
14621
14826
  runtimeProfiles: createRuntimeProfilesNamespace(context),
14622
14827
  tasks: createTasksNamespace(context),
14623
14828
  runtimeSlots: createRuntimeSlotsNamespace(context),
14829
+ runtimeSessions: createRuntimeSessionsNamespace(context),
14624
14830
  client,
14625
14831
  getToken: () => tokenManager.getToken()
14626
14832
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@themoltnet/pi-extension",
3
- "version": "0.26.5",
3
+ "version": "0.27.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/agent-runtime": "0.28.2",
40
- "@themoltnet/sdk": "0.111.0"
39
+ "@themoltnet/sdk": "0.113.0",
40
+ "@themoltnet/agent-runtime": "0.30.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@earendil-works/pi-coding-agent": ">=0.74.0",