@themoltnet/pi-runtime 0.6.2 → 0.7.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/dist/index.d.ts +13 -0
- package/dist/index.js +59 -39
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { BashOperations } from '@earendil-works/pi-coding-agent';
|
|
|
5
5
|
import { ClaimedTask } from '@themoltnet/agent-runtime';
|
|
6
6
|
import { CommandAnalysis } from '@themoltnet/shell-command-analyzer';
|
|
7
7
|
import { connect } from '@themoltnet/sdk';
|
|
8
|
+
import { Context } from '@opentelemetry/api';
|
|
8
9
|
import { ContextRef } from '@themoltnet/agent-runtime';
|
|
9
10
|
import { EditOperations } from '@earendil-works/pi-coding-agent';
|
|
10
11
|
import { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
@@ -97,6 +98,12 @@ declare interface BuildAgentSessionArgs {
|
|
|
97
98
|
skillsOverride?: () => LoadSkillsResult;
|
|
98
99
|
/** Span attributes merged onto every OTel span the session emits. */
|
|
99
100
|
otelSpanAttrs: Record<string, string | number | boolean>;
|
|
101
|
+
/** Parent context for the Pi session span, normally the task execute span. */
|
|
102
|
+
otelSessionParentContext?: Context;
|
|
103
|
+
/** Resolves the provider-request context used to parent each Pi turn. */
|
|
104
|
+
getOtelTurnParentContext?: () => Context | undefined;
|
|
105
|
+
/** Receives the live Pi session context for provider-span parenting. */
|
|
106
|
+
onOtelSessionContextChange?: (context: Context | undefined) => void;
|
|
100
107
|
/** Agent name for `gen_ai.agent.name` on the root span. */
|
|
101
108
|
agentName: string;
|
|
102
109
|
/**
|
|
@@ -885,6 +892,12 @@ export declare interface PiOtelOptions {
|
|
|
885
892
|
* since the extension is authoritative for those.
|
|
886
893
|
*/
|
|
887
894
|
spanAttributes?: Record<string, string | number | boolean>;
|
|
895
|
+
/** Explicit parent for the session-level `invoke_agent` span. */
|
|
896
|
+
sessionParentContext?: Context;
|
|
897
|
+
/** Parent context for the next Pi turn, normally a provider-request span. */
|
|
898
|
+
getTurnParentContext?: () => Context | undefined;
|
|
899
|
+
/** Publishes the live session span context to the embedding runtime. */
|
|
900
|
+
onSessionContextChange?: (context: Context | undefined) => void;
|
|
888
901
|
}
|
|
889
902
|
|
|
890
903
|
export declare type PiRetryTriage = (input: PiRetryTriageInput) => Promise<PiRetryTriageResult>;
|
package/dist/index.js
CHANGED
|
@@ -18,12 +18,11 @@ import { createHash } from "crypto";
|
|
|
18
18
|
import { createHash as createHash$1 } from "node:crypto";
|
|
19
19
|
import * as json from "multiformats/codecs/json";
|
|
20
20
|
import "@ipld/dag-cbor";
|
|
21
|
-
import { FREEFORM_TYPE, SUBMIT_OUTPUT_GATE_ID, TaskContext, buildTaskUserPrompt, getSubmitOutputContract, materializeTaskOutput, mergeRuntimeProfileContext, resolveTaskContext, taskTypeUsesSubagents, validateTaskOutput, validateTaskSubmission } from "@themoltnet/agent-runtime";
|
|
21
|
+
import { FREEFORM_TYPE, SUBMIT_OUTPUT_GATE_ID, TaskContext, buildTaskUserPrompt, getSubmitOutputContract, materializeTaskOutput, mergeRuntimeProfileContext, resolveTaskContext, taskTypeUsesSubagents, traceRuntimePhase, validateTaskOutput, validateTaskSubmission } from "@themoltnet/agent-runtime";
|
|
22
22
|
import { connect } from "@themoltnet/sdk";
|
|
23
23
|
import { ShellCommandAnalyzer } from "@themoltnet/shell-command-analyzer";
|
|
24
24
|
import { homedir } from "node:os";
|
|
25
25
|
import { MemoryProvider, RealFSProvider, ShadowProvider, VM, VmCheckpoint, createHttpHooks, createShadowPathPredicate, ensureImageSelector, isWriteFlag, loadGuestAssets } from "@earendil-works/gondolin";
|
|
26
|
-
import * as Format from "typebox/format";
|
|
27
26
|
import { Type as Type$1 } from "typebox";
|
|
28
27
|
import { Value } from "typebox/value";
|
|
29
28
|
import { parseEnv } from "node:util";
|
|
@@ -1057,20 +1056,23 @@ function createPiOtelExtension(options = {}) {
|
|
|
1057
1056
|
sessionSpan.end();
|
|
1058
1057
|
sessionSpan = void 0;
|
|
1059
1058
|
sessionCtx = context.active();
|
|
1059
|
+
options.onSessionContextChange?.(void 0);
|
|
1060
1060
|
}
|
|
1061
1061
|
currentModel = void 0;
|
|
1062
1062
|
}
|
|
1063
1063
|
pi.on("session_start", (event, ctx) => {
|
|
1064
1064
|
endSessionSpan();
|
|
1065
1065
|
const agentName = options.agentName ?? "pi";
|
|
1066
|
+
const parentContext = options.sessionParentContext ?? context.active();
|
|
1066
1067
|
sessionSpan = tracer.startSpan(`invoke_agent ${agentName}`, { attributes: {
|
|
1067
1068
|
...extraAttrs,
|
|
1068
1069
|
"gen_ai.operation.name": "invoke_agent",
|
|
1069
1070
|
"gen_ai.agent.name": agentName,
|
|
1070
1071
|
"session.reason": event.reason,
|
|
1071
1072
|
"session.cwd": ctx.cwd
|
|
1072
|
-
} },
|
|
1073
|
-
sessionCtx = trace.setSpan(
|
|
1073
|
+
} }, parentContext);
|
|
1074
|
+
sessionCtx = trace.setSpan(parentContext, sessionSpan);
|
|
1075
|
+
options.onSessionContextChange?.(sessionCtx);
|
|
1074
1076
|
turnCtx = sessionCtx;
|
|
1075
1077
|
});
|
|
1076
1078
|
pi.on("session_shutdown", () => {
|
|
@@ -1089,14 +1091,15 @@ function createPiOtelExtension(options = {}) {
|
|
|
1089
1091
|
pi.on("turn_start", (event) => {
|
|
1090
1092
|
if (!sessionSpan) return;
|
|
1091
1093
|
const modelLabel = currentModel?.id ?? "unknown";
|
|
1094
|
+
const turnParentContext = options.getTurnParentContext?.() ?? sessionCtx;
|
|
1092
1095
|
turnSpan = tracer.startSpan(`chat ${modelLabel}`, { attributes: {
|
|
1093
1096
|
...extraAttrs,
|
|
1094
1097
|
"gen_ai.operation.name": "chat",
|
|
1095
1098
|
"gen_ai.request.model": currentModel?.id ?? "unknown",
|
|
1096
1099
|
"gen_ai.provider.name": currentModel?.provider ?? "unknown",
|
|
1097
1100
|
"turn.index": event.turnIndex
|
|
1098
|
-
} },
|
|
1099
|
-
turnCtx = trace.setSpan(
|
|
1101
|
+
} }, turnParentContext);
|
|
1102
|
+
turnCtx = trace.setSpan(turnParentContext, turnSpan);
|
|
1100
1103
|
});
|
|
1101
1104
|
pi.on("turn_end", (event) => {
|
|
1102
1105
|
if (!turnSpan) return;
|
|
@@ -1247,7 +1250,10 @@ var NO_SKILLS = () => ({
|
|
|
1247
1250
|
async function buildAgentSession(args) {
|
|
1248
1251
|
const piOtelExtension = createPiOtelExtension({
|
|
1249
1252
|
agentName: args.agentName,
|
|
1250
|
-
spanAttributes: args.otelSpanAttrs
|
|
1253
|
+
spanAttributes: args.otelSpanAttrs,
|
|
1254
|
+
sessionParentContext: args.otelSessionParentContext,
|
|
1255
|
+
getTurnParentContext: args.getOtelTurnParentContext,
|
|
1256
|
+
onSessionContextChange: args.onOtelSessionContextChange
|
|
1251
1257
|
});
|
|
1252
1258
|
const modelOptions = {
|
|
1253
1259
|
temperature: args.temperature,
|
|
@@ -1339,19 +1345,6 @@ function resolvePiCodingAgentDir() {
|
|
|
1339
1345
|
return process.env["PI_CODING_AGENT_DIR"] ?? path.join(homedir(), ".pi", "agent");
|
|
1340
1346
|
}
|
|
1341
1347
|
//#endregion
|
|
1342
|
-
//#region ../tasks/src/formats.ts
|
|
1343
|
-
/**
|
|
1344
|
-
* Register TypeBox string formats used across Task / TaskOutput / task-type
|
|
1345
|
-
* schemas. Import this module for its side effect (the package index does so
|
|
1346
|
-
* automatically) before compiling or Check()ing any schema that references
|
|
1347
|
-
* `format: 'uuid'` or `format: 'date-time'`.
|
|
1348
|
-
*
|
|
1349
|
-
* Idempotent: registration is guarded by `Format.Has(...)`.
|
|
1350
|
-
*/
|
|
1351
|
-
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1352
|
-
if (!Format.Has("uuid")) Format.Set("uuid", (v) => UUID_RE.test(v));
|
|
1353
|
-
if (!Format.Has("date-time")) Format.Set("date-time", (v) => !Number.isNaN(Date.parse(v)));
|
|
1354
|
-
//#endregion
|
|
1355
1348
|
//#region ../tasks/src/context.ts
|
|
1356
1349
|
/**
|
|
1357
1350
|
* How an executor delivers a context entry to its underlying LLM.
|
|
@@ -3898,7 +3891,7 @@ Type$1.Object({
|
|
|
3898
3891
|
daemonState: Type$1.Union([DaemonState, Type$1.Null()])
|
|
3899
3892
|
}, {
|
|
3900
3893
|
$id: "TaskAttempt",
|
|
3901
|
-
additionalProperties:
|
|
3894
|
+
additionalProperties: true
|
|
3902
3895
|
});
|
|
3903
3896
|
Type$1.Object({
|
|
3904
3897
|
taskId: Uuid,
|
|
@@ -7194,6 +7187,7 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7194
7187
|
const task = claimedTask.task;
|
|
7195
7188
|
const attemptN = claimedTask.attemptN;
|
|
7196
7189
|
const startTime = Date.now();
|
|
7190
|
+
const taskOtelContext = context.active();
|
|
7197
7191
|
const requestedMountPath = opts.mountPath ?? process.cwd();
|
|
7198
7192
|
const agentRootDir = opts.agentRootDir ?? requestedMountPath;
|
|
7199
7193
|
const executionPlan = await opts.makeExecutionPlan?.(claimedTask) ?? null;
|
|
@@ -7217,6 +7211,8 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7217
7211
|
let reporterOpen = opts.reporterAlreadyOpened ?? false;
|
|
7218
7212
|
let managed = null;
|
|
7219
7213
|
let session = null;
|
|
7214
|
+
let piSessionContext;
|
|
7215
|
+
let providerRequestContext;
|
|
7220
7216
|
let subagentHandle = null;
|
|
7221
7217
|
const finalUsage = emptyUsage(opts.provider, opts.model);
|
|
7222
7218
|
let cancelListener = null;
|
|
@@ -7287,19 +7283,22 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7287
7283
|
let effectiveSandboxConfig;
|
|
7288
7284
|
try {
|
|
7289
7285
|
if (!resolvedVmTemplate && opts.runtimeDefinition) resolvedVmTemplate = opts.resolveVmTemplate ? await opts.resolveVmTemplate() : await opts.runtimeDefinition.vm.resolve({ onProgress: opts.onSnapshotProgress });
|
|
7290
|
-
checkpointPath = resolvedVmTemplate?.checkpointPath ?? opts.checkpointPath ?? (opts.resolveCheckpointPath ? await opts.resolveCheckpointPath() : await ensureSnapshot({
|
|
7286
|
+
checkpointPath = await traceRuntimePhase("moltnet.execution.snapshot.prepare", { "moltnet.snapshot.source": resolvedVmTemplate ? "resolved_template" : opts.checkpointPath ? "configured_checkpoint" : opts.resolveCheckpointPath ? "resolver" : "build_or_cache" }, async () => resolvedVmTemplate?.checkpointPath ?? opts.checkpointPath ?? (opts.resolveCheckpointPath ? await opts.resolveCheckpointPath() : await ensureSnapshot({
|
|
7291
7287
|
config: opts.sandboxConfig?.snapshot,
|
|
7292
7288
|
onProgress: opts.onSnapshotProgress ?? ((m) => {
|
|
7293
7289
|
process.stderr.write(`[snapshot] ${m}\n`);
|
|
7294
7290
|
})
|
|
7295
|
-
}));
|
|
7291
|
+
})));
|
|
7296
7292
|
} catch (err) {
|
|
7297
7293
|
const message = err instanceof Error ? err.message : String(err);
|
|
7298
7294
|
await emitError("snapshot", message);
|
|
7299
7295
|
return makeFailedOutput("snapshot_failed", message);
|
|
7300
7296
|
}
|
|
7301
7297
|
try {
|
|
7302
|
-
workspace =
|
|
7298
|
+
workspace = await traceRuntimePhase("moltnet.execution.workspace.prepare", {
|
|
7299
|
+
"moltnet.workspace.mode": executionPlan?.workspaceMode ?? "shared_mount",
|
|
7300
|
+
"moltnet.workspace.scope": executionPlan?.workspaceScope ?? "attempt"
|
|
7301
|
+
}, async () => prepareTaskWorkspace(task, requestedMountPath, executionPlan));
|
|
7303
7302
|
mountPath = workspace.mountPath;
|
|
7304
7303
|
cwdPath = workspace.cwdPath;
|
|
7305
7304
|
} catch (err) {
|
|
@@ -7307,23 +7306,25 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7307
7306
|
await emitError("worktree_setup", message);
|
|
7308
7307
|
return makeFailedOutput("worktree_setup_failed", message);
|
|
7309
7308
|
}
|
|
7309
|
+
if (!workspace) throw new Error("task workspace not prepared");
|
|
7310
|
+
const preparedWorkspace = workspace;
|
|
7310
7311
|
try {
|
|
7311
7312
|
effectiveSandboxConfig = applyExecutionPlanSandboxOverrides(resolvedVmTemplate ? {
|
|
7312
7313
|
...opts.sandboxConfig,
|
|
7313
7314
|
snapshot: void 0,
|
|
7314
7315
|
resumeCommands: [...resolvedVmTemplate.resumeCommands]
|
|
7315
7316
|
} : opts.sandboxConfig, executionPlan);
|
|
7316
|
-
managed = await resumeVm({
|
|
7317
|
+
managed = await traceRuntimePhase("moltnet.execution.vm.resume", { "moltnet.workspace.mode": preparedWorkspace.mode }, () => resumeVm({
|
|
7317
7318
|
checkpointPath,
|
|
7318
7319
|
agentName: opts.agentName,
|
|
7319
7320
|
agentRootDir,
|
|
7320
7321
|
mountPath,
|
|
7321
|
-
workspaceMode:
|
|
7322
|
+
workspaceMode: preparedWorkspace.mode,
|
|
7322
7323
|
extraAllowedHosts: opts.extraAllowedHosts,
|
|
7323
7324
|
sandboxConfig: effectiveSandboxConfig,
|
|
7324
7325
|
forwardEnv: opts.forwardEnv,
|
|
7325
7326
|
signal: reporter.cancelSignal
|
|
7326
|
-
});
|
|
7327
|
+
}));
|
|
7327
7328
|
} catch (err) {
|
|
7328
7329
|
const message = err instanceof Error ? err.message : String(err);
|
|
7329
7330
|
if (reporter.cancelSignal.aborted) {
|
|
@@ -7336,9 +7337,8 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7336
7337
|
const diaryId = task.diaryId ?? "";
|
|
7337
7338
|
const taskTeamId = task.teamId ?? "";
|
|
7338
7339
|
activateAgentEnv(managed.credentials.agentEnv, agentRootDir);
|
|
7339
|
-
const activeWorkspace =
|
|
7340
|
+
const activeWorkspace = preparedWorkspace;
|
|
7340
7341
|
const activeManaged = managed;
|
|
7341
|
-
if (!activeWorkspace) throw new Error("task workspace not prepared");
|
|
7342
7342
|
await emit("info", {
|
|
7343
7343
|
event: "execute_start",
|
|
7344
7344
|
correlationId: task.correlationId ?? null,
|
|
@@ -7381,10 +7381,10 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7381
7381
|
const rawContext = task.input.context;
|
|
7382
7382
|
let effectiveRuntimeContext;
|
|
7383
7383
|
try {
|
|
7384
|
-
effectiveRuntimeContext = resolveEffectiveRuntimeContext({
|
|
7384
|
+
effectiveRuntimeContext = await traceRuntimePhase("moltnet.execution.context.resolve", {}, async () => resolveEffectiveRuntimeContext({
|
|
7385
7385
|
rawTaskContext: rawContext,
|
|
7386
7386
|
runtimeProfileContext: opts.runtimeProfileContext
|
|
7387
|
-
});
|
|
7387
|
+
}));
|
|
7388
7388
|
} catch (err) {
|
|
7389
7389
|
const message = err instanceof Error ? err.message : String(err);
|
|
7390
7390
|
await emit("error", {
|
|
@@ -7426,11 +7426,11 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7426
7426
|
}
|
|
7427
7427
|
let injectedContext;
|
|
7428
7428
|
try {
|
|
7429
|
-
injectedContext = await injectRuntimeContext({
|
|
7429
|
+
injectedContext = await traceRuntimePhase("moltnet.execution.context.inject", { "moltnet.context.ref_count": effectiveRuntimeContext.length }, () => injectRuntimeContext({
|
|
7430
7430
|
context: effectiveRuntimeContext,
|
|
7431
|
-
fs:
|
|
7432
|
-
guestWorkspace:
|
|
7433
|
-
});
|
|
7431
|
+
fs: activeManaged.vm.fs,
|
|
7432
|
+
guestWorkspace: activeManaged.guestWorkspace
|
|
7433
|
+
}));
|
|
7434
7434
|
} catch (err) {
|
|
7435
7435
|
const message = err instanceof Error ? err.message : String(err);
|
|
7436
7436
|
await emit("error", {
|
|
@@ -7658,7 +7658,10 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7658
7658
|
...submitTools,
|
|
7659
7659
|
...parentSubagentTools
|
|
7660
7660
|
];
|
|
7661
|
-
session = await
|
|
7661
|
+
session = await traceRuntimePhase("moltnet.execution.session.create", {
|
|
7662
|
+
"gen_ai.provider.name": opts.provider,
|
|
7663
|
+
"gen_ai.request.model": opts.model
|
|
7664
|
+
}, () => buildAgentSession({
|
|
7662
7665
|
mountPath,
|
|
7663
7666
|
cwdPath,
|
|
7664
7667
|
piAuthDir,
|
|
@@ -7686,13 +7689,18 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7686
7689
|
"moltnet.task.attempt": attemptN,
|
|
7687
7690
|
"moltnet.task.type": task.taskType
|
|
7688
7691
|
},
|
|
7692
|
+
otelSessionParentContext: taskOtelContext,
|
|
7693
|
+
getOtelTurnParentContext: () => providerRequestContext,
|
|
7694
|
+
onOtelSessionContextChange: (context) => {
|
|
7695
|
+
piSessionContext = context;
|
|
7696
|
+
},
|
|
7689
7697
|
sessionPersistence: executionPlan?.sessionPersistence ?? void 0,
|
|
7690
7698
|
extraExtensionFactories: [
|
|
7691
7699
|
...runtimeParentExtensions,
|
|
7692
7700
|
...toolPolicyExtensions,
|
|
7693
7701
|
submitCompletion.extension
|
|
7694
7702
|
]
|
|
7695
|
-
});
|
|
7703
|
+
}));
|
|
7696
7704
|
} catch (err) {
|
|
7697
7705
|
const message = err instanceof Error ? err.message : String(err);
|
|
7698
7706
|
await emit("error", {
|
|
@@ -7774,7 +7782,11 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
7774
7782
|
onPromptError: (message) => emit("error", {
|
|
7775
7783
|
message,
|
|
7776
7784
|
phase: "session_prompt"
|
|
7777
|
-
})
|
|
7785
|
+
}),
|
|
7786
|
+
parentContext: piSessionContext,
|
|
7787
|
+
onRequestContextChange: (context) => {
|
|
7788
|
+
providerRequestContext = context;
|
|
7789
|
+
}
|
|
7778
7790
|
});
|
|
7779
7791
|
const submitMissingConfig = resolveSubmitMissingConfig({
|
|
7780
7792
|
submitToolHandle,
|
|
@@ -8330,7 +8342,15 @@ async function promptWithProviderErrorRetries(args) {
|
|
|
8330
8342
|
let promptText = args.initialPrompt;
|
|
8331
8343
|
while (true) {
|
|
8332
8344
|
try {
|
|
8333
|
-
await
|
|
8345
|
+
await traceRuntimePhase("moltnet.execution.provider.request", { "moltnet.provider.retry": retryCount }, async (span) => {
|
|
8346
|
+
const requestContext = trace.setSpan(args.parentContext ?? context.active(), span);
|
|
8347
|
+
args.onRequestContextChange?.(requestContext);
|
|
8348
|
+
try {
|
|
8349
|
+
await args.session.prompt(promptText);
|
|
8350
|
+
} finally {
|
|
8351
|
+
args.onRequestContextChange?.(void 0);
|
|
8352
|
+
}
|
|
8353
|
+
}, args.parentContext);
|
|
8334
8354
|
} catch (err) {
|
|
8335
8355
|
const message = err instanceof Error ? err.message : String(err);
|
|
8336
8356
|
await args.onPromptError?.(message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/pi-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Composable MoltNet runtime kernel for Pi agents in Gondolin VMs",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"@opentelemetry/api": "^1.9.0",
|
|
32
32
|
"multiformats": "^13.3.0",
|
|
33
33
|
"typebox": "^1.2.8",
|
|
34
|
-
"@themoltnet/
|
|
34
|
+
"@themoltnet/agent-runtime": "0.41.0",
|
|
35
35
|
"@themoltnet/shell-command-analyzer": "0.3.0",
|
|
36
|
-
"@themoltnet/
|
|
36
|
+
"@themoltnet/sdk": "0.129.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@earendil-works/pi-ai": "0.79.4",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"vite": "^8.0.0",
|
|
51
51
|
"vite-plugin-dts": "^4.5.4",
|
|
52
52
|
"vitest": "^3.0.0",
|
|
53
|
-
"@moltnet/models": "0.1.0",
|
|
54
53
|
"@moltnet/tasks": "0.1.0",
|
|
55
|
-
"@moltnet/crypto-service": "0.1.0"
|
|
54
|
+
"@moltnet/crypto-service": "0.1.0",
|
|
55
|
+
"@moltnet/models": "0.1.0"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|
|
58
58
|
"node": ">=22"
|