@themoltnet/agent-daemon 0.27.2 → 0.29.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/README.md +6 -5
- package/dist/main.js +231 -5
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -244,10 +244,11 @@ and private diary id.
|
|
|
244
244
|
### 3. Start the daemon against the local stack
|
|
245
245
|
|
|
246
246
|
The daemon picks up the API URL from the agent's `moltnet.json`. It is a
|
|
247
|
-
workspace package, not a global CLI — invoke it
|
|
247
|
+
workspace package, not a global CLI — invoke it through Nx so execution stays
|
|
248
|
+
rooted in the workspace task graph:
|
|
248
249
|
|
|
249
250
|
```bash
|
|
250
|
-
pnpm
|
|
251
|
+
pnpm exec nx run @themoltnet/agent-daemon:dev -- poll \
|
|
251
252
|
--agent local-dev \
|
|
252
253
|
--team "$MOLTNET_TEAM_ID" \
|
|
253
254
|
--task-types fulfill_brief \
|
|
@@ -259,8 +260,8 @@ pnpm --filter @themoltnet/agent-daemon dev poll \
|
|
|
259
260
|
registered type.
|
|
260
261
|
- Pick a runtime profile whose provider/model matches your Pi auth credits.
|
|
261
262
|
Set `MOLTNET_AGENT_PROFILE` to the profile UUID or team-scoped profile name.
|
|
262
|
-
- `dev` (= `tsx watch src/main.ts`) is fine for local. Use `cli`
|
|
263
|
-
one-shot run without watch.
|
|
263
|
+
- `dev` (= `tsx watch src/main.ts`) is fine for local. Use the Nx `cli` target
|
|
264
|
+
for a one-shot run without watch.
|
|
264
265
|
|
|
265
266
|
Leave it running. It idles until a task lands in its queue.
|
|
266
267
|
|
|
@@ -325,7 +326,7 @@ against the local e2e stack before the new schema exists on a deployed API.
|
|
|
325
326
|
Start the daemon with `--task-types pr_review`:
|
|
326
327
|
|
|
327
328
|
```bash
|
|
328
|
-
pnpm
|
|
329
|
+
pnpm exec nx run @themoltnet/agent-daemon:dev -- poll \
|
|
329
330
|
--agent local-dev \
|
|
330
331
|
--team "$MOLTNET_TEAM_ID" \
|
|
331
332
|
--task-types pr_review \
|
package/dist/main.js
CHANGED
|
@@ -10,7 +10,7 @@ import crypto from "crypto";
|
|
|
10
10
|
import { delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
11
11
|
import { parseArgs, promisify } from "node:util";
|
|
12
12
|
import { AgentRuntime, ApiTaskReporter, ApiTaskSource, PollingApiTaskSource } from "@themoltnet/agent-runtime";
|
|
13
|
-
import { createPiTaskExecutor, findMainWorktree } from "@themoltnet/pi-extension";
|
|
13
|
+
import { createPiRetryTriage, createPiTaskExecutor, findMainWorktree, normalizeRetryTriageResult, redactRetryTriageSecrets } from "@themoltnet/pi-extension";
|
|
14
14
|
import { execFile, execFileSync } from "node:child_process";
|
|
15
15
|
import { accessSync, constants, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
16
16
|
import { MoltNetError, connect } from "@themoltnet/sdk";
|
|
@@ -22,6 +22,7 @@ import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
|
22
22
|
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
23
23
|
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
|
|
24
24
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
25
|
+
import { getModel } from "@earendil-works/pi-ai";
|
|
25
26
|
import { mkdir, realpath, stat } from "node:fs/promises";
|
|
26
27
|
import { pipeline } from "node:stream/promises";
|
|
27
28
|
import { createHash } from "node:crypto";
|
|
@@ -9217,6 +9218,27 @@ var TaskUsage = _Object_({
|
|
|
9217
9218
|
$id: "TaskUsage",
|
|
9218
9219
|
additionalProperties: false
|
|
9219
9220
|
});
|
|
9221
|
+
var TaskRetryDecision = Union([Literal("retry"), Literal("do_not_retry")]);
|
|
9222
|
+
var TaskRetryConfidence = Union([
|
|
9223
|
+
Literal("low"),
|
|
9224
|
+
Literal("medium"),
|
|
9225
|
+
Literal("high")
|
|
9226
|
+
]);
|
|
9227
|
+
var TaskRetryInfo = _Object_({
|
|
9228
|
+
source: Union([
|
|
9229
|
+
Literal("explicit"),
|
|
9230
|
+
Literal("deterministic"),
|
|
9231
|
+
Literal("attempts_exhausted"),
|
|
9232
|
+
Literal("triage"),
|
|
9233
|
+
Literal("triage_failed")
|
|
9234
|
+
]),
|
|
9235
|
+
decision: Optional(TaskRetryDecision),
|
|
9236
|
+
confidence: Optional(TaskRetryConfidence),
|
|
9237
|
+
reason: Optional(String$1())
|
|
9238
|
+
}, {
|
|
9239
|
+
$id: "TaskRetryInfo",
|
|
9240
|
+
additionalProperties: false
|
|
9241
|
+
});
|
|
9220
9242
|
/**
|
|
9221
9243
|
* Structured error returned from a failed attempt.
|
|
9222
9244
|
*/
|
|
@@ -9224,7 +9246,8 @@ var TaskError = _Object_({
|
|
|
9224
9246
|
code: String$1(),
|
|
9225
9247
|
message: String$1(),
|
|
9226
9248
|
stack: Optional(String$1()),
|
|
9227
|
-
retryable: Optional(Boolean$1())
|
|
9249
|
+
retryable: Optional(Boolean$1()),
|
|
9250
|
+
retry: Optional(TaskRetryInfo)
|
|
9228
9251
|
}, {
|
|
9229
9252
|
$id: "TaskError",
|
|
9230
9253
|
additionalProperties: false
|
|
@@ -10010,6 +10033,157 @@ function recoverScratchWorkspacePath(producer, stateDirs) {
|
|
|
10010
10033
|
return existsSync(fallback) ? fallback : null;
|
|
10011
10034
|
}
|
|
10012
10035
|
//#endregion
|
|
10036
|
+
//#region src/lib/retry-triage.ts
|
|
10037
|
+
var RETRYABLE_CODES = new Set([
|
|
10038
|
+
"checkpoint_upload_failed",
|
|
10039
|
+
"complete_call_failed",
|
|
10040
|
+
"daemon_abort",
|
|
10041
|
+
"dispatch_expired",
|
|
10042
|
+
"lease_expired",
|
|
10043
|
+
"llm_api_error",
|
|
10044
|
+
"runtime_session_checkpoint_failed",
|
|
10045
|
+
"session_prompt_failed"
|
|
10046
|
+
]);
|
|
10047
|
+
var NON_RETRYABLE_CODES = new Set([
|
|
10048
|
+
"bad_api_key",
|
|
10049
|
+
"invalid_api_key",
|
|
10050
|
+
"invalid_model",
|
|
10051
|
+
"output_rejected_by_server",
|
|
10052
|
+
"output_validation_failed",
|
|
10053
|
+
"producer_context_missing",
|
|
10054
|
+
"running_max_bash_timeouts_exceeded",
|
|
10055
|
+
"running_max_turns_exceeded",
|
|
10056
|
+
"task_cancelled",
|
|
10057
|
+
"unknown_task_type"
|
|
10058
|
+
]);
|
|
10059
|
+
var RETRYABLE_MESSAGE_PATTERNS = [
|
|
10060
|
+
/\b429\b/i,
|
|
10061
|
+
/\b5(?:02|03|04)\b/i,
|
|
10062
|
+
/\btimeout\b/i,
|
|
10063
|
+
/\btimed out\b/i,
|
|
10064
|
+
/\brate limit/i,
|
|
10065
|
+
/\btemporar(?:y|ily)\b/i,
|
|
10066
|
+
/\bunavailable\b/i,
|
|
10067
|
+
/\bECONNRESET\b/i,
|
|
10068
|
+
/\bECONNREFUSED\b/i,
|
|
10069
|
+
/\bETIMEDOUT\b/i,
|
|
10070
|
+
/\bENOTFOUND\b/i,
|
|
10071
|
+
/\bEAI_AGAIN\b/i,
|
|
10072
|
+
/\bDNS\b/i
|
|
10073
|
+
];
|
|
10074
|
+
var NON_RETRYABLE_MESSAGE_PATTERNS = [
|
|
10075
|
+
/\b401\b/i,
|
|
10076
|
+
/\b403\b/i,
|
|
10077
|
+
/\bunauthori[sz]ed\b/i,
|
|
10078
|
+
/\bforbidden\b/i,
|
|
10079
|
+
/\binvalid (?:api )?key\b/i,
|
|
10080
|
+
/\bmissing credentials?\b/i,
|
|
10081
|
+
/\bmodel .*not (?:found|registered|available)\b/i,
|
|
10082
|
+
/\bunknown task type\b/i,
|
|
10083
|
+
/\bvalidation failed\b/i,
|
|
10084
|
+
/\bcancelled\b/i,
|
|
10085
|
+
/\bmax (?:turn|bash)/i
|
|
10086
|
+
];
|
|
10087
|
+
async function classifyAttemptFailure(input) {
|
|
10088
|
+
if (input.remainingAttempts !== null && input.remainingAttempts !== void 0) {
|
|
10089
|
+
if (input.remainingAttempts <= 0) return {
|
|
10090
|
+
error: withRetryInfo(input.error, {
|
|
10091
|
+
retryable: false,
|
|
10092
|
+
source: "attempts_exhausted",
|
|
10093
|
+
reason: `Attempt budget exhausted at attempt ${input.attemptN}${input.maxAttempts ? ` of ${input.maxAttempts}` : ""}.`
|
|
10094
|
+
}),
|
|
10095
|
+
source: "attempts_exhausted"
|
|
10096
|
+
};
|
|
10097
|
+
}
|
|
10098
|
+
const deterministic = classifyDeterministically(input.error);
|
|
10099
|
+
if (deterministic !== "ambiguous") {
|
|
10100
|
+
const retryable = deterministic === "retryable";
|
|
10101
|
+
const source = input.error.retryable === retryable ? "explicit" : "deterministic";
|
|
10102
|
+
return {
|
|
10103
|
+
error: withRetryInfo(input.error, {
|
|
10104
|
+
retryable,
|
|
10105
|
+
source,
|
|
10106
|
+
decision: retryable ? "retry" : "do_not_retry",
|
|
10107
|
+
confidence: "high",
|
|
10108
|
+
reason: retryable ? "Matched deterministic retry policy." : "Matched deterministic no-retry policy."
|
|
10109
|
+
}),
|
|
10110
|
+
source
|
|
10111
|
+
};
|
|
10112
|
+
}
|
|
10113
|
+
if (!input.triage) return {
|
|
10114
|
+
error: withRetryInfo(input.error, {
|
|
10115
|
+
retryable: false,
|
|
10116
|
+
source: "triage_failed",
|
|
10117
|
+
reason: "Failure was ambiguous and no retry triage agent was configured; defaulted to no retry."
|
|
10118
|
+
}),
|
|
10119
|
+
source: "triage_failed"
|
|
10120
|
+
};
|
|
10121
|
+
try {
|
|
10122
|
+
const triage = normalizeRetryTriageResult(await input.triage(input));
|
|
10123
|
+
const retryable = triage.decision === "retry" && (triage.confidence === "medium" || triage.confidence === "high");
|
|
10124
|
+
return {
|
|
10125
|
+
error: withRetryInfo({
|
|
10126
|
+
...input.error,
|
|
10127
|
+
message: appendTriageReason(input.error.message, triage)
|
|
10128
|
+
}, {
|
|
10129
|
+
retryable,
|
|
10130
|
+
source: "triage",
|
|
10131
|
+
decision: triage.decision,
|
|
10132
|
+
confidence: triage.confidence,
|
|
10133
|
+
reason: triage.reason
|
|
10134
|
+
}),
|
|
10135
|
+
source: "triage",
|
|
10136
|
+
triage
|
|
10137
|
+
};
|
|
10138
|
+
} catch (err) {
|
|
10139
|
+
return {
|
|
10140
|
+
error: withRetryInfo({
|
|
10141
|
+
...input.error,
|
|
10142
|
+
message: appendTriageFailure(input.error.message, err)
|
|
10143
|
+
}, {
|
|
10144
|
+
retryable: false,
|
|
10145
|
+
source: "triage_failed",
|
|
10146
|
+
reason: `Retry triage failed: ${sanitizeReason(err)}`
|
|
10147
|
+
}),
|
|
10148
|
+
source: "triage_failed"
|
|
10149
|
+
};
|
|
10150
|
+
}
|
|
10151
|
+
}
|
|
10152
|
+
function classifyDeterministically(error) {
|
|
10153
|
+
const code = error.code.toLowerCase();
|
|
10154
|
+
const message = error.message;
|
|
10155
|
+
if (NON_RETRYABLE_CODES.has(code)) return "non_retryable";
|
|
10156
|
+
if (NON_RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message))) return "non_retryable";
|
|
10157
|
+
if (RETRYABLE_CODES.has(code)) return "retryable";
|
|
10158
|
+
if (RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message))) return "retryable";
|
|
10159
|
+
if (error.retryable === true) return "retryable";
|
|
10160
|
+
return "ambiguous";
|
|
10161
|
+
}
|
|
10162
|
+
function appendTriageReason(message, triage) {
|
|
10163
|
+
const suffix = ` Retry triage: ${triage.decision}/${triage.confidence}: ${triage.reason}`;
|
|
10164
|
+
if (message.includes("Retry triage:")) return message;
|
|
10165
|
+
return `${message}${suffix}`.slice(0, 4e3);
|
|
10166
|
+
}
|
|
10167
|
+
function appendTriageFailure(message, err) {
|
|
10168
|
+
if (message.includes("Retry triage failed:")) return message;
|
|
10169
|
+
return `${message} Retry triage failed: ${sanitizeReason(err)}`.slice(0, 4e3);
|
|
10170
|
+
}
|
|
10171
|
+
function sanitizeReason(value) {
|
|
10172
|
+
return redactRetryTriageSecrets(value instanceof Error ? value.message : String(value)).slice(0, 500);
|
|
10173
|
+
}
|
|
10174
|
+
function withRetryInfo(error, info) {
|
|
10175
|
+
return {
|
|
10176
|
+
...error,
|
|
10177
|
+
retryable: info.retryable,
|
|
10178
|
+
retry: {
|
|
10179
|
+
source: info.source,
|
|
10180
|
+
...info.decision ? { decision: info.decision } : {},
|
|
10181
|
+
...info.confidence ? { confidence: info.confidence } : {},
|
|
10182
|
+
...info.reason ? { reason: info.reason.slice(0, 500) } : {}
|
|
10183
|
+
}
|
|
10184
|
+
};
|
|
10185
|
+
}
|
|
10186
|
+
//#endregion
|
|
10013
10187
|
//#region src/lib/finalize.ts
|
|
10014
10188
|
/**
|
|
10015
10189
|
* Build the `daemonState` payload for a `/complete` call. Freeform
|
|
@@ -10045,9 +10219,10 @@ async function finalizeTask(agent, output, ctx = {}) {
|
|
|
10045
10219
|
...daemonState ? { daemonState } : {}
|
|
10046
10220
|
});
|
|
10047
10221
|
} catch (err) {
|
|
10048
|
-
const
|
|
10222
|
+
const classified = await prepareAttemptFailure(agent, output, errorToFailReason(err), ctx);
|
|
10049
10223
|
ctx.log?.("complete-rejected-falling-back-to-fail", err);
|
|
10050
|
-
|
|
10224
|
+
ctx.log?.(`attempt-failure-classified:${classified.source}`);
|
|
10225
|
+
await agent.tasks.failAttempt(output.taskId, output.attemptN, { error: classified.error });
|
|
10051
10226
|
return;
|
|
10052
10227
|
}
|
|
10053
10228
|
await maybeWriteAnchors(output, ctx);
|
|
@@ -10059,10 +10234,16 @@ async function finalizeTask(agent, output, ctx = {}) {
|
|
|
10059
10234
|
retryable: false
|
|
10060
10235
|
};
|
|
10061
10236
|
if ((await agent.tasks.heartbeat(output.taskId, output.attemptN, {})).cancelled) return;
|
|
10062
|
-
await agent
|
|
10237
|
+
const classified = await prepareAttemptFailure(agent, output, error, ctx);
|
|
10238
|
+
ctx.log?.(`attempt-failure-classified:${classified.source}`);
|
|
10239
|
+
await agent.tasks.failAttempt(output.taskId, output.attemptN, { error: classified.error });
|
|
10063
10240
|
}
|
|
10064
10241
|
function errorToFailReason(err) {
|
|
10065
10242
|
if (err instanceof MoltNetError) {
|
|
10243
|
+
if (err.code !== "VALIDATION_FAILED" && err.statusCode !== 400) return {
|
|
10244
|
+
code: "complete_call_failed",
|
|
10245
|
+
message: `Failed to report task completion (${err.code}, status ${err.statusCode ?? "?"}): ${err.detail ?? err.message}`
|
|
10246
|
+
};
|
|
10066
10247
|
const fields = err.validationErrors?.length ? "; " + err.validationErrors.map((e) => `${e.field}: ${e.message}`).join(" | ") : "";
|
|
10067
10248
|
return {
|
|
10068
10249
|
code: "output_rejected_by_server",
|
|
@@ -10076,6 +10257,28 @@ function errorToFailReason(err) {
|
|
|
10076
10257
|
retryable: false
|
|
10077
10258
|
};
|
|
10078
10259
|
}
|
|
10260
|
+
async function prepareAttemptFailure(agent, output, error, ctx) {
|
|
10261
|
+
const task = ctx.task ?? {
|
|
10262
|
+
id: output.taskId,
|
|
10263
|
+
taskType: "unknown",
|
|
10264
|
+
teamId: "unknown",
|
|
10265
|
+
input: {},
|
|
10266
|
+
maxAttempts: null
|
|
10267
|
+
};
|
|
10268
|
+
const recentMessages = classifyDeterministically(error) === "ambiguous" && ctx.retryTriage && ctx.task ? await agent.tasks.listMessages(output.taskId, output.attemptN).then((messages) => messages.slice(-12)).catch((err) => {
|
|
10269
|
+
ctx.log?.("attempt-failure-message-fetch-failed", err);
|
|
10270
|
+
return [];
|
|
10271
|
+
}) : [];
|
|
10272
|
+
return classifyAttemptFailure({
|
|
10273
|
+
task,
|
|
10274
|
+
attemptN: output.attemptN,
|
|
10275
|
+
maxAttempts: ctx.task?.maxAttempts ?? null,
|
|
10276
|
+
remainingAttempts: ctx.task?.maxAttempts === void 0 ? null : Math.max(0, ctx.task.maxAttempts - output.attemptN),
|
|
10277
|
+
error,
|
|
10278
|
+
recentMessages,
|
|
10279
|
+
triage: ctx.retryTriage
|
|
10280
|
+
});
|
|
10281
|
+
}
|
|
10079
10282
|
async function maybeWriteAnchors(output, ctx) {
|
|
10080
10283
|
const { task, writeCorrelationAnchors, log } = ctx;
|
|
10081
10284
|
if (!task || task.taskType !== "fulfill_brief") return;
|
|
@@ -10387,6 +10590,17 @@ function isExecutable(path) {
|
|
|
10387
10590
|
}
|
|
10388
10591
|
}
|
|
10389
10592
|
//#endregion
|
|
10593
|
+
//#region src/lib/runtime-profile-retry-triage.ts
|
|
10594
|
+
function createRuntimeProfileRetryTriage(options) {
|
|
10595
|
+
return createPiRetryTriage({
|
|
10596
|
+
model: getModel(options.runtimeProfile.provider, options.runtimeProfile.model),
|
|
10597
|
+
thinkingLevel: options.runtimeProfile.thinkingLevel,
|
|
10598
|
+
piAgentDir: options.piAgentDir,
|
|
10599
|
+
timeoutMs: options.timeoutMs,
|
|
10600
|
+
cwd: options.cwd
|
|
10601
|
+
});
|
|
10602
|
+
}
|
|
10603
|
+
//#endregion
|
|
10390
10604
|
//#region src/lib/runtime-sessions.ts
|
|
10391
10605
|
function resolveRuntimeSessionKind(claimedTask) {
|
|
10392
10606
|
const continueFrom = resolveContinueFrom(claimedTask);
|
|
@@ -10882,6 +11096,11 @@ async function runPolling(opts) {
|
|
|
10882
11096
|
return finalizeTask(ctx.agent, terminalOutput, {
|
|
10883
11097
|
task: claimedTask.task,
|
|
10884
11098
|
slot: resolved ? { expiresAtMs: resolved.slot.expiresAtMs } : null,
|
|
11099
|
+
retryTriage: createRuntimeProfileRetryTriage({
|
|
11100
|
+
runtimeProfile: selected.profile,
|
|
11101
|
+
piAgentDir: selected.piAgentDir.path,
|
|
11102
|
+
cwd: ctx.agentRootDir
|
|
11103
|
+
}),
|
|
10885
11104
|
writeCorrelationAnchors: makePrBodyAnchorWriter({
|
|
10886
11105
|
gh: createGhCliClient(),
|
|
10887
11106
|
logger: rootLogger.child({
|
|
@@ -11010,6 +11229,7 @@ async function runPolling(opts) {
|
|
|
11010
11229
|
topK: profile.topK,
|
|
11011
11230
|
maxOutputTokens: profile.maxOutputTokens,
|
|
11012
11231
|
sandboxConfig: sandbox.config,
|
|
11232
|
+
forwardEnv: profile.requiredEnv,
|
|
11013
11233
|
makeExecutionPlan: (task) => executionPlans.getOrCreate(task),
|
|
11014
11234
|
makeOnTurnEvent: makeTurnEventHandlerFactory(taskLogger),
|
|
11015
11235
|
maxTurns: common.maxTurns,
|
|
@@ -11264,6 +11484,7 @@ async function runOnce(argv) {
|
|
|
11264
11484
|
topK: profile.topK,
|
|
11265
11485
|
maxOutputTokens: profile.maxOutputTokens,
|
|
11266
11486
|
sandboxConfig: sandbox.config,
|
|
11487
|
+
forwardEnv: profile.requiredEnv,
|
|
11267
11488
|
makeExecutionPlan: (claimedTask) => executionPlans.getOrCreate(claimedTask),
|
|
11268
11489
|
onTurnEvent: makeTurnEventHandler(rootLogger, { taskId }),
|
|
11269
11490
|
maxTurns: opts.maxTurns,
|
|
@@ -11379,6 +11600,11 @@ async function runOnce(argv) {
|
|
|
11379
11600
|
return finalizeTask(ctx.agent, terminalOutput, {
|
|
11380
11601
|
task: claimedTask.task,
|
|
11381
11602
|
slot: resolved ? { expiresAtMs: resolved.slot.expiresAtMs } : null,
|
|
11603
|
+
retryTriage: createRuntimeProfileRetryTriage({
|
|
11604
|
+
runtimeProfile: profile,
|
|
11605
|
+
piAgentDir: piAgentDir.path,
|
|
11606
|
+
cwd: ctx.agentRootDir
|
|
11607
|
+
}),
|
|
11382
11608
|
writeCorrelationAnchors,
|
|
11383
11609
|
log: (msg, err) => rootLogger.warn({ err }, msg)
|
|
11384
11610
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/agent-daemon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "MoltNet agent daemon — claims and executes tasks (fulfill_brief, assess_brief) from the MoltNet task-service via Pi-headless. CLI: moltnet-agent.",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"@opentelemetry/semantic-conventions": "^1.39.0",
|
|
46
46
|
"pino": "^10.3.1",
|
|
47
47
|
"pino-pretty": "^13.1.3",
|
|
48
|
-
"@themoltnet/
|
|
49
|
-
"@themoltnet/pi-extension": "0.
|
|
50
|
-
"@themoltnet/
|
|
48
|
+
"@themoltnet/agent-runtime": "0.33.1",
|
|
49
|
+
"@themoltnet/pi-extension": "0.31.0",
|
|
50
|
+
"@themoltnet/sdk": "0.117.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"tsx": "^4.7.0",
|
|
@@ -55,11 +55,12 @@
|
|
|
55
55
|
"vite": "^8.0.0",
|
|
56
56
|
"vitest": "^3.0.0",
|
|
57
57
|
"@moltnet/crypto-service": "0.1.0",
|
|
58
|
-
"@moltnet/observability": "0.1.0",
|
|
59
58
|
"@moltnet/tasks": "0.1.0",
|
|
60
|
-
"@moltnet/bootstrap": "0.1.0"
|
|
59
|
+
"@moltnet/bootstrap": "0.1.0",
|
|
60
|
+
"@moltnet/observability": "0.1.0"
|
|
61
61
|
},
|
|
62
62
|
"nx": {
|
|
63
|
+
"projectType": "application",
|
|
63
64
|
"tags": [
|
|
64
65
|
"type:app",
|
|
65
66
|
"scope:agent",
|