@nookplot/runtime 0.5.125 → 0.5.126
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/__tests__/autonomous.getAvailableActions.test.js +7 -4
- package/dist/__tests__/autonomous.getAvailableActions.test.js.map +1 -1
- package/dist/__tests__/autonomous.goalBootstrap.test.d.ts +2 -0
- package/dist/__tests__/autonomous.goalBootstrap.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.goalBootstrap.test.js +148 -0
- package/dist/__tests__/autonomous.goalBootstrap.test.js.map +1 -0
- package/dist/__tests__/autonomous.miningTrack.test.d.ts +2 -0
- package/dist/__tests__/autonomous.miningTrack.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.miningTrack.test.js +38 -0
- package/dist/__tests__/autonomous.miningTrack.test.js.map +1 -0
- package/dist/__tests__/codegen-drift.test.js +3 -1
- package/dist/__tests__/codegen-drift.test.js.map +1 -1
- package/dist/__tests__/conversation/modelThresholdsParity.test.js +6 -11
- package/dist/__tests__/conversation/modelThresholdsParity.test.js.map +1 -1
- package/dist/__tests__/goalLoop.test.d.ts +2 -0
- package/dist/__tests__/goalLoop.test.d.ts.map +1 -0
- package/dist/__tests__/goalLoop.test.js +335 -0
- package/dist/__tests__/goalLoop.test.js.map +1 -0
- package/dist/__tests__/helpers/mockRuntime.d.ts.map +1 -1
- package/dist/__tests__/helpers/mockRuntime.js +7 -0
- package/dist/__tests__/helpers/mockRuntime.js.map +1 -1
- package/dist/__tests__/loadProfile.test.d.ts +8 -0
- package/dist/__tests__/loadProfile.test.d.ts.map +1 -0
- package/dist/__tests__/loadProfile.test.js +134 -0
- package/dist/__tests__/loadProfile.test.js.map +1 -0
- package/dist/__tests__/mining.test.d.ts +2 -0
- package/dist/__tests__/mining.test.d.ts.map +1 -0
- package/dist/__tests__/mining.test.js +306 -0
- package/dist/__tests__/mining.test.js.map +1 -0
- package/dist/__tests__/presetLoader.test.d.ts +2 -0
- package/dist/__tests__/presetLoader.test.d.ts.map +1 -0
- package/dist/__tests__/presetLoader.test.js +749 -0
- package/dist/__tests__/presetLoader.test.js.map +1 -0
- package/dist/__tests__/sandbox.test.js +24 -24
- package/dist/actionCatalog.generated.js +2 -2
- package/dist/actionCatalog.generated.js.map +1 -1
- package/dist/autonomous.d.ts +15 -1
- package/dist/autonomous.d.ts.map +1 -1
- package/dist/autonomous.js +182 -37
- package/dist/autonomous.js.map +1 -1
- package/dist/bounties.js +1 -1
- package/dist/bounties.js.map +1 -1
- package/dist/chat/chatEngine.d.ts.map +1 -1
- package/dist/chat/chatEngine.js +8 -0
- package/dist/chat/chatEngine.js.map +1 -1
- package/dist/connection.d.ts +1 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2 -1
- package/dist/connection.js.map +1 -1
- package/dist/contentSafety.d.ts +1 -1
- package/dist/contentSafety.d.ts.map +1 -1
- package/dist/contentSafety.js +6 -2
- package/dist/contentSafety.js.map +1 -1
- package/dist/conversation/modelLimits.js +17 -17
- package/dist/discovery.js +1 -1
- package/dist/discovery.js.map +1 -1
- package/dist/goal/goalLoop.d.ts +78 -0
- package/dist/goal/goalLoop.d.ts.map +1 -0
- package/dist/goal/goalLoop.js +376 -0
- package/dist/goal/goalLoop.js.map +1 -0
- package/dist/goal/goalPrompts.d.ts +20 -0
- package/dist/goal/goalPrompts.d.ts.map +1 -0
- package/dist/goal/goalPrompts.js +54 -0
- package/dist/goal/goalPrompts.js.map +1 -0
- package/dist/goal/types.d.ts +98 -0
- package/dist/goal/types.d.ts.map +1 -0
- package/dist/goal/types.js +7 -0
- package/dist/goal/types.js.map +1 -0
- package/dist/identity.d.ts +51 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +50 -0
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/loadProfile.d.ts +100 -0
- package/dist/loadProfile.d.ts.map +1 -0
- package/dist/loadProfile.js +221 -0
- package/dist/loadProfile.js.map +1 -0
- package/dist/presetLoader.d.ts +130 -0
- package/dist/presetLoader.d.ts.map +1 -0
- package/dist/presetLoader.js +734 -0
- package/dist/presetLoader.js.map +1 -0
- package/dist/swarms.d.ts +13 -0
- package/dist/swarms.d.ts.map +1 -1
- package/dist/swarms.js +4 -0
- package/dist/swarms.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +7 -2
- package/dist/tools.js.map +1 -1
- package/package.json +60 -60
package/dist/autonomous.js
CHANGED
|
@@ -44,6 +44,7 @@ import { wrapUntrusted, sanitizeForPrompt, UNTRUSTED_CONTENT_INSTRUCTION } from
|
|
|
44
44
|
import { getAvailableActionsFromMap } from "./signalActionMap.js";
|
|
45
45
|
import { getCategoryListing, getToolsInCategory } from "./actionCatalog.js";
|
|
46
46
|
import { WakeUpStack } from "./wakeUpStack.js";
|
|
47
|
+
import { GoalLoop } from "./goal/goalLoop.js";
|
|
47
48
|
import { hooks as defaultHooks } from "./hooks.js";
|
|
48
49
|
import { guardrails as defaultGuardrails, GuardrailTripped, InputGuardrailTripped, } from "./guardrails.js";
|
|
49
50
|
import { buildCorrectivePrompt, checkForDoomLoopFromSignatures, makeSignature, } from "./doomLoop.js";
|
|
@@ -60,6 +61,7 @@ const ON_CHAIN_ACTIONS = new Set([
|
|
|
60
61
|
"approve_bounty_claimer", "approve_bounty_work", "dispute_bounty_work",
|
|
61
62
|
"cancel_bounty", "unclaim_bounty",
|
|
62
63
|
"expire_disputed_bounty", "sweep_treasury_fees", // V8
|
|
64
|
+
"sweep_creator_refund", // V9 H4 admin recovery
|
|
63
65
|
"create_listing", "list_service", "update_service", "create_agreement",
|
|
64
66
|
"deliver_work", "settle_agreement", "dispute_agreement", "cancel_agreement",
|
|
65
67
|
"expire_dispute", "expire_delivered",
|
|
@@ -238,6 +240,21 @@ export class AutonomousAgent {
|
|
|
238
240
|
if (this.verbose) {
|
|
239
241
|
console.log("[autonomous] AutonomousAgent started — handling signals + actions");
|
|
240
242
|
}
|
|
243
|
+
// Pre-load tool categories so the LLM always has web_search +
|
|
244
|
+
// search_knowledge visible without a browse_tools cold-start.
|
|
245
|
+
// Saves ~1 LLM turn per goal-driven agent and simplifies the first
|
|
246
|
+
// step for reactive agents too (CLAUDE.md rule — small code change).
|
|
247
|
+
this.loadedCategories.add("tools");
|
|
248
|
+
this.loadedCategories.add("discovery");
|
|
249
|
+
this.loadedCategories.add("knowledge");
|
|
250
|
+
// Goal bootstrap — run the GoalLoop in background if this agent was
|
|
251
|
+
// forged with initial_goal set (L1 swarm auto-deploy). Failures are
|
|
252
|
+
// non-fatal: the agent continues in normal reactive mode.
|
|
253
|
+
this.maybeBootstrapGoal().catch((err) => {
|
|
254
|
+
if (this.verbose) {
|
|
255
|
+
console.error("[autonomous] Goal bootstrap failed:", err);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
241
258
|
}
|
|
242
259
|
/** Stop the autonomous agent. */
|
|
243
260
|
stop() {
|
|
@@ -247,6 +264,157 @@ export class AutonomousAgent {
|
|
|
247
264
|
}
|
|
248
265
|
}
|
|
249
266
|
// ================================================================
|
|
267
|
+
// Goal bootstrap (L3 — migration 247)
|
|
268
|
+
// ================================================================
|
|
269
|
+
/**
|
|
270
|
+
* Check whether this agent has an initial_goal + pending status, and
|
|
271
|
+
* if so, spin up a GoalLoop in the background. Non-blocking — start()
|
|
272
|
+
* returns immediately so WebSocket signal subscriptions are live even
|
|
273
|
+
* while the goal loop is running its first step.
|
|
274
|
+
*/
|
|
275
|
+
async maybeBootstrapGoal() {
|
|
276
|
+
let goalConfig;
|
|
277
|
+
try {
|
|
278
|
+
goalConfig = await this.runtime.identity.getGoal();
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
if (this.verbose) {
|
|
282
|
+
console.error("[autonomous] getGoal failed — treating as no goal:", err);
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (!goalConfig || !goalConfig.initialGoal)
|
|
287
|
+
return;
|
|
288
|
+
if (goalConfig.goalStatus !== "pending") {
|
|
289
|
+
if (this.verbose) {
|
|
290
|
+
console.log(`[autonomous] Skipping goal bootstrap — status is ${goalConfig.goalStatus}, not 'pending'`);
|
|
291
|
+
}
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (this.verbose) {
|
|
295
|
+
console.log(`[autonomous] Goal bootstrap: "${goalConfig.initialGoal.slice(0, 80)}..." budget=${goalConfig.goalBudgetNook ?? "unlimited"}`);
|
|
296
|
+
}
|
|
297
|
+
// Transition status atomically before running the loop. If the
|
|
298
|
+
// gateway rejects (network, permissions), bail out — we do not want
|
|
299
|
+
// to run the loop with a mismatched DB state.
|
|
300
|
+
try {
|
|
301
|
+
await this.runtime.identity.updateGoalStatus("in_progress");
|
|
302
|
+
}
|
|
303
|
+
catch (err) {
|
|
304
|
+
if (this.verbose) {
|
|
305
|
+
console.error("[autonomous] Failed to transition goal → in_progress:", err);
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const budgetNook = goalConfig.goalBudgetNook ? BigInt(goalConfig.goalBudgetNook) : 0n;
|
|
310
|
+
const loopOptions = {
|
|
311
|
+
runtime: this.runtime,
|
|
312
|
+
goal: goalConfig.initialGoal,
|
|
313
|
+
budgetNook,
|
|
314
|
+
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
315
|
+
verbose: this.verbose,
|
|
316
|
+
};
|
|
317
|
+
const loop = new GoalLoop(loopOptions);
|
|
318
|
+
let result;
|
|
319
|
+
try {
|
|
320
|
+
result = await loop.run();
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
324
|
+
if (this.verbose) {
|
|
325
|
+
console.error("[autonomous] GoalLoop threw:", err);
|
|
326
|
+
}
|
|
327
|
+
// Transition to failed so the UI reflects the error.
|
|
328
|
+
await this.runtime.identity.updateGoalStatus("failed").catch(() => { });
|
|
329
|
+
await this.runtime.identity.createPendingTask({
|
|
330
|
+
reason: "unclear_goal",
|
|
331
|
+
description: `Goal loop crashed: ${msg.slice(0, 400)}`,
|
|
332
|
+
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
333
|
+
}).catch(() => { });
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
await this.handleGoalResult(result, goalConfig);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Dispatch on the terminal state of a GoalLoop run:
|
|
340
|
+
* - complete → store artifact in private KG, pause agent
|
|
341
|
+
* - blocked_budget → create pending task (budget_exhausted), pause
|
|
342
|
+
* - blocked_stuck → create pending task (stuck_3x), pause
|
|
343
|
+
* - blocked_capability → create pending task (needs_capability), pause
|
|
344
|
+
*/
|
|
345
|
+
async handleGoalResult(result, goalConfig) {
|
|
346
|
+
if (result.outcome === "complete") {
|
|
347
|
+
// Store deliverable in private KG
|
|
348
|
+
let artifactId = null;
|
|
349
|
+
try {
|
|
350
|
+
const storeResult = (await this.runtime.connection.request("POST", "/v1/agents/me/knowledge", {
|
|
351
|
+
contentText: result.artifact.body,
|
|
352
|
+
title: result.artifact.title,
|
|
353
|
+
domain: result.artifact.domain,
|
|
354
|
+
visibility: "private",
|
|
355
|
+
knowledgeType: "fact",
|
|
356
|
+
sourceType: "import",
|
|
357
|
+
metadata: {
|
|
358
|
+
goal: goalConfig.initialGoal,
|
|
359
|
+
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
360
|
+
stepsExecuted: result.stepsExecuted,
|
|
361
|
+
spentNook: result.spentNook.toString(),
|
|
362
|
+
},
|
|
363
|
+
}));
|
|
364
|
+
artifactId = storeResult?.id ?? null;
|
|
365
|
+
}
|
|
366
|
+
catch (err) {
|
|
367
|
+
if (this.verbose) {
|
|
368
|
+
console.error("[autonomous] Failed to store goal artifact:", err);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
await this.runtime.identity.completeGoal(artifactId ?? "unknown");
|
|
373
|
+
}
|
|
374
|
+
catch (err) {
|
|
375
|
+
if (this.verbose) {
|
|
376
|
+
console.error("[autonomous] completeGoal failed:", err);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Q3: agent pauses after completion, does not stay reactive
|
|
380
|
+
this.stop();
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (result.outcome === "blocked_budget") {
|
|
384
|
+
// initialGoal is non-null here — maybeBootstrapGoal returned early otherwise.
|
|
385
|
+
const goalText = goalConfig.initialGoal ?? "(unknown)";
|
|
386
|
+
await this.runtime.identity.createPendingTask({
|
|
387
|
+
reason: "budget_exhausted",
|
|
388
|
+
description: `Needs top-off to continue goal: ${goalText.slice(0, 300)}`,
|
|
389
|
+
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
390
|
+
}).catch(() => { });
|
|
391
|
+
await this.runtime.identity.updateGoalStatus("paused_awaiting_topoff").catch(() => { });
|
|
392
|
+
this.stop();
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (result.outcome === "blocked_stuck") {
|
|
396
|
+
await this.runtime.identity.createPendingTask({
|
|
397
|
+
reason: "stuck_3x",
|
|
398
|
+
description: result.stuckReason,
|
|
399
|
+
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
400
|
+
}).catch(() => { });
|
|
401
|
+
await this.runtime.identity.updateGoalStatus("blocked_needs_decision").catch(() => { });
|
|
402
|
+
this.stop();
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
if (result.outcome === "blocked_capability") {
|
|
406
|
+
await this.runtime.identity.createPendingTask({
|
|
407
|
+
reason: "needs_capability",
|
|
408
|
+
description: result.capabilityNeeded,
|
|
409
|
+
suggestedPresetId: result.suggestedPreset,
|
|
410
|
+
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
411
|
+
}).catch(() => { });
|
|
412
|
+
await this.runtime.identity.updateGoalStatus("blocked_needs_decision").catch(() => { });
|
|
413
|
+
this.stop();
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// ================================================================
|
|
250
418
|
// Signal handling (proactive.signal)
|
|
251
419
|
// ================================================================
|
|
252
420
|
/**
|
|
@@ -477,9 +645,7 @@ export class AutonomousAgent {
|
|
|
477
645
|
case "community_gap":
|
|
478
646
|
await this.handleCommunityGap(data);
|
|
479
647
|
break;
|
|
480
|
-
case
|
|
481
|
-
await this.handleDirective(data);
|
|
482
|
-
break;
|
|
648
|
+
// DD-7: directive case removed — swarm coordination uses DMs
|
|
483
649
|
case "files_committed":
|
|
484
650
|
await this.handleFilesCommitted(data);
|
|
485
651
|
break;
|
|
@@ -2006,40 +2172,7 @@ export class AutonomousAgent {
|
|
|
2006
2172
|
console.error("[autonomous] Community gap handling failed:", err);
|
|
2007
2173
|
}
|
|
2008
2174
|
}
|
|
2009
|
-
|
|
2010
|
-
const directiveContent = data.messagePreview ?? "";
|
|
2011
|
-
const channelId = data.channelId;
|
|
2012
|
-
const community = data.community ?? "general";
|
|
2013
|
-
try {
|
|
2014
|
-
const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
|
|
2015
|
-
"You received a directive on Nookplot.\n" +
|
|
2016
|
-
`Directive:\n${wrapUntrusted(directiveContent, "directive")}\n\n` +
|
|
2017
|
-
"Follow the directive and compose your response.\n" +
|
|
2018
|
-
"If it asks you to post, write the post content.\n" +
|
|
2019
|
-
"If it asks you to discuss, write a discussion message.\n" +
|
|
2020
|
-
"If you can't follow this directive, respond with exactly: [SKIP]\n\n" +
|
|
2021
|
-
"Your response (under 500 chars):";
|
|
2022
|
-
const response = await this.generateResponse(prompt);
|
|
2023
|
-
const content = response?.trim() ?? "";
|
|
2024
|
-
if (content && content !== "[SKIP]") {
|
|
2025
|
-
if (channelId) {
|
|
2026
|
-
await this.runtime.channels.send(channelId, content);
|
|
2027
|
-
if (this.verbose)
|
|
2028
|
-
console.log(`[autonomous] ✓ Directive response sent to channel ${channelId.slice(0, 12)}`);
|
|
2029
|
-
}
|
|
2030
|
-
else {
|
|
2031
|
-
const title = content.slice(0, 100);
|
|
2032
|
-
await this.runtime.memory.publishKnowledge({ title, body: content, community });
|
|
2033
|
-
if (this.verbose)
|
|
2034
|
-
console.log(`[autonomous] ✓ Directive response posted in ${community}`);
|
|
2035
|
-
}
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
catch (err) {
|
|
2039
|
-
if (this.verbose)
|
|
2040
|
-
console.error("[autonomous] Directive handling failed:", err);
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2175
|
+
// DD-7: handleDirective removed — swarm coordination uses DMs exclusively
|
|
2043
2176
|
// ================================================================
|
|
2044
2177
|
// Project collaboration signal handlers
|
|
2045
2178
|
// ================================================================
|
|
@@ -2726,6 +2859,18 @@ export class AutonomousAgent {
|
|
|
2726
2859
|
triggers: this.doomLoopTriggers,
|
|
2727
2860
|
actionType,
|
|
2728
2861
|
});
|
|
2862
|
+
// Track C.2: also push to gateway as fire-and-forget telemetry so
|
|
2863
|
+
// ops dashboards can answer "which tools most often misbehave?"
|
|
2864
|
+
// and "is this agent stuck right now?" — see
|
|
2865
|
+
// gateway/src/services/doomLoopMetrics.ts. Errors are swallowed so
|
|
2866
|
+
// a backend outage never blocks the runtime's recovery path.
|
|
2867
|
+
void this.runtime.connection
|
|
2868
|
+
.request("POST", "/v1/agents/me/doom-loop-event", {
|
|
2869
|
+
offender: doomOffender,
|
|
2870
|
+
triggers: this.doomLoopTriggers,
|
|
2871
|
+
actionType,
|
|
2872
|
+
})
|
|
2873
|
+
.catch(() => { });
|
|
2729
2874
|
if (this.doomLoopTriggers >= AUTONOMOUS_DOOM_LOOP_MAX_TRIGGERS) {
|
|
2730
2875
|
if (this.verbose) {
|
|
2731
2876
|
console.warn(`[autonomous] ✗ doom loop on '${doomOffender}' (${this.doomLoopTriggers} triggers) — aborting cycle`);
|