@nookplot/runtime 0.5.140 → 0.5.142
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.dedup.test.js +0 -11
- package/dist/__tests__/autonomous.dedup.test.js.map +1 -1
- package/dist/__tests__/autonomous.getAvailableActions.test.js +1 -13
- package/dist/__tests__/autonomous.getAvailableActions.test.js.map +1 -1
- package/dist/__tests__/codegen-drift.test.js +1 -3
- package/dist/__tests__/codegen-drift.test.js.map +1 -1
- package/dist/__tests__/conversation/modelThresholdsParity.test.js +11 -6
- package/dist/__tests__/conversation/modelThresholdsParity.test.js.map +1 -1
- package/dist/__tests__/economy.frontierInference.test.d.ts +2 -0
- package/dist/__tests__/economy.frontierInference.test.d.ts.map +1 -0
- package/dist/__tests__/economy.frontierInference.test.js +61 -0
- package/dist/__tests__/economy.frontierInference.test.js.map +1 -0
- package/dist/__tests__/helpers/mockRuntime.d.ts.map +1 -1
- package/dist/__tests__/helpers/mockRuntime.js +0 -7
- package/dist/__tests__/helpers/mockRuntime.js.map +1 -1
- package/dist/actionCatalog.d.ts.map +1 -1
- package/dist/actionCatalog.generated.d.ts +1 -1
- package/dist/actionCatalog.generated.d.ts.map +1 -1
- package/dist/actionCatalog.generated.js +60 -95
- package/dist/actionCatalog.generated.js.map +1 -1
- package/dist/actionCatalog.js +10 -0
- package/dist/actionCatalog.js.map +1 -1
- package/dist/autonomous.d.ts +9 -16
- package/dist/autonomous.d.ts.map +1 -1
- package/dist/autonomous.js +66 -232
- package/dist/autonomous.js.map +1 -1
- package/dist/contentSafety.d.ts +1 -1
- package/dist/contentSafety.d.ts.map +1 -1
- package/dist/contentSafety.js +2 -6
- package/dist/contentSafety.js.map +1 -1
- package/dist/discovery.js +1 -1
- package/dist/discovery.js.map +1 -1
- package/dist/economy.d.ts +13 -0
- package/dist/economy.d.ts.map +1 -1
- package/dist/economy.js +26 -0
- package/dist/economy.js.map +1 -1
- package/dist/frontierPass.d.ts +30 -0
- package/dist/frontierPass.d.ts.map +1 -0
- package/dist/frontierPass.js +42 -0
- package/dist/frontierPass.js.map +1 -0
- package/dist/identity.d.ts +0 -51
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -50
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/signalActionMap.d.ts.map +1 -1
- package/dist/signalActionMap.js +3 -9
- package/dist/signalActionMap.js.map +1 -1
- package/dist/swarms.d.ts +0 -13
- package/dist/swarms.d.ts.map +1 -1
- package/dist/swarms.js +0 -4
- package/dist/swarms.js.map +1 -1
- package/dist/tools.js +1 -1
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/dist/__tests__/autonomous.goalBootstrap.test.d.ts +0 -2
- package/dist/__tests__/autonomous.goalBootstrap.test.d.ts.map +0 -1
- package/dist/__tests__/autonomous.goalBootstrap.test.js +0 -148
- package/dist/__tests__/autonomous.goalBootstrap.test.js.map +0 -1
- package/dist/__tests__/autonomous.miningTrack.test.d.ts +0 -2
- package/dist/__tests__/autonomous.miningTrack.test.d.ts.map +0 -1
- package/dist/__tests__/autonomous.miningTrack.test.js +0 -38
- package/dist/__tests__/autonomous.miningTrack.test.js.map +0 -1
- package/dist/__tests__/autonomous.workspaceOpportunity.test.d.ts +0 -2
- package/dist/__tests__/autonomous.workspaceOpportunity.test.d.ts.map +0 -1
- package/dist/__tests__/autonomous.workspaceOpportunity.test.js +0 -200
- package/dist/__tests__/autonomous.workspaceOpportunity.test.js.map +0 -1
- package/dist/__tests__/goalLoop.test.d.ts +0 -2
- package/dist/__tests__/goalLoop.test.d.ts.map +0 -1
- package/dist/__tests__/goalLoop.test.js +0 -335
- package/dist/__tests__/goalLoop.test.js.map +0 -1
- package/dist/__tests__/loadProfile.test.d.ts +0 -8
- package/dist/__tests__/loadProfile.test.d.ts.map +0 -1
- package/dist/__tests__/loadProfile.test.js +0 -134
- package/dist/__tests__/loadProfile.test.js.map +0 -1
- package/dist/__tests__/mining.test.d.ts +0 -2
- package/dist/__tests__/mining.test.d.ts.map +0 -1
- package/dist/__tests__/mining.test.js +0 -306
- package/dist/__tests__/mining.test.js.map +0 -1
- package/dist/__tests__/presetLoader.test.d.ts +0 -2
- package/dist/__tests__/presetLoader.test.d.ts.map +0 -1
- package/dist/__tests__/presetLoader.test.js +0 -749
- package/dist/__tests__/presetLoader.test.js.map +0 -1
- package/dist/goal/goalLoop.d.ts +0 -78
- package/dist/goal/goalLoop.d.ts.map +0 -1
- package/dist/goal/goalLoop.js +0 -376
- package/dist/goal/goalLoop.js.map +0 -1
- package/dist/goal/goalPrompts.d.ts +0 -20
- package/dist/goal/goalPrompts.d.ts.map +0 -1
- package/dist/goal/goalPrompts.js +0 -54
- package/dist/goal/goalPrompts.js.map +0 -1
- package/dist/goal/types.d.ts +0 -98
- package/dist/goal/types.d.ts.map +0 -1
- package/dist/goal/types.js +0 -7
- package/dist/goal/types.js.map +0 -1
- package/dist/loadProfile.d.ts +0 -100
- package/dist/loadProfile.d.ts.map +0 -1
- package/dist/loadProfile.js +0 -221
- package/dist/loadProfile.js.map +0 -1
- package/dist/presetLoader.d.ts +0 -130
- package/dist/presetLoader.d.ts.map +0 -1
- package/dist/presetLoader.js +0 -734
- package/dist/presetLoader.js.map +0 -1
package/dist/autonomous.js
CHANGED
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
* @module autonomous
|
|
41
41
|
*/
|
|
42
42
|
import { prepareSignRelay } from "./signing.js";
|
|
43
|
+
import { runFrontierPass } from "./frontierPass.js";
|
|
43
44
|
import { wrapUntrusted, sanitizeForPrompt, UNTRUSTED_CONTENT_INSTRUCTION } from "./contentSafety.js";
|
|
44
45
|
import { getAvailableActionsFromMap } from "./signalActionMap.js";
|
|
45
46
|
import { getCategoryListing, getToolsInCategory } from "./actionCatalog.js";
|
|
46
47
|
import { WakeUpStack } from "./wakeUpStack.js";
|
|
47
|
-
import { GoalLoop } from "./goal/goalLoop.js";
|
|
48
48
|
import { hooks as defaultHooks } from "./hooks.js";
|
|
49
49
|
import { guardrails as defaultGuardrails, GuardrailTripped, InputGuardrailTripped, } from "./guardrails.js";
|
|
50
50
|
import { buildCorrectivePrompt, checkForDoomLoopFromSignatures, makeSignature, } from "./doomLoop.js";
|
|
@@ -243,21 +243,6 @@ export class AutonomousAgent {
|
|
|
243
243
|
if (this.verbose) {
|
|
244
244
|
console.log("[autonomous] AutonomousAgent started — handling signals + actions");
|
|
245
245
|
}
|
|
246
|
-
// Pre-load tool categories so the LLM always has web_search +
|
|
247
|
-
// search_knowledge visible without a browse_tools cold-start.
|
|
248
|
-
// Saves ~1 LLM turn per goal-driven agent and simplifies the first
|
|
249
|
-
// step for reactive agents too (CLAUDE.md rule — small code change).
|
|
250
|
-
this.loadedCategories.add("tools");
|
|
251
|
-
this.loadedCategories.add("discovery");
|
|
252
|
-
this.loadedCategories.add("knowledge");
|
|
253
|
-
// Goal bootstrap — run the GoalLoop in background if this agent was
|
|
254
|
-
// forged with initial_goal set (L1 swarm auto-deploy). Failures are
|
|
255
|
-
// non-fatal: the agent continues in normal reactive mode.
|
|
256
|
-
this.maybeBootstrapGoal().catch((err) => {
|
|
257
|
-
if (this.verbose) {
|
|
258
|
-
console.error("[autonomous] Goal bootstrap failed:", err);
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
246
|
}
|
|
262
247
|
/** Stop the autonomous agent. */
|
|
263
248
|
stop() {
|
|
@@ -267,157 +252,6 @@ export class AutonomousAgent {
|
|
|
267
252
|
}
|
|
268
253
|
}
|
|
269
254
|
// ================================================================
|
|
270
|
-
// Goal bootstrap (L3 — migration 247)
|
|
271
|
-
// ================================================================
|
|
272
|
-
/**
|
|
273
|
-
* Check whether this agent has an initial_goal + pending status, and
|
|
274
|
-
* if so, spin up a GoalLoop in the background. Non-blocking — start()
|
|
275
|
-
* returns immediately so WebSocket signal subscriptions are live even
|
|
276
|
-
* while the goal loop is running its first step.
|
|
277
|
-
*/
|
|
278
|
-
async maybeBootstrapGoal() {
|
|
279
|
-
let goalConfig;
|
|
280
|
-
try {
|
|
281
|
-
goalConfig = await this.runtime.identity.getGoal();
|
|
282
|
-
}
|
|
283
|
-
catch (err) {
|
|
284
|
-
if (this.verbose) {
|
|
285
|
-
console.error("[autonomous] getGoal failed — treating as no goal:", err);
|
|
286
|
-
}
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
if (!goalConfig || !goalConfig.initialGoal)
|
|
290
|
-
return;
|
|
291
|
-
if (goalConfig.goalStatus !== "pending") {
|
|
292
|
-
if (this.verbose) {
|
|
293
|
-
console.log(`[autonomous] Skipping goal bootstrap — status is ${goalConfig.goalStatus}, not 'pending'`);
|
|
294
|
-
}
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
if (this.verbose) {
|
|
298
|
-
console.log(`[autonomous] Goal bootstrap: "${goalConfig.initialGoal.slice(0, 80)}..." budget=${goalConfig.goalBudgetNook ?? "unlimited"}`);
|
|
299
|
-
}
|
|
300
|
-
// Transition status atomically before running the loop. If the
|
|
301
|
-
// gateway rejects (network, permissions), bail out — we do not want
|
|
302
|
-
// to run the loop with a mismatched DB state.
|
|
303
|
-
try {
|
|
304
|
-
await this.runtime.identity.updateGoalStatus("in_progress");
|
|
305
|
-
}
|
|
306
|
-
catch (err) {
|
|
307
|
-
if (this.verbose) {
|
|
308
|
-
console.error("[autonomous] Failed to transition goal → in_progress:", err);
|
|
309
|
-
}
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
const budgetNook = goalConfig.goalBudgetNook ? BigInt(goalConfig.goalBudgetNook) : 0n;
|
|
313
|
-
const loopOptions = {
|
|
314
|
-
runtime: this.runtime,
|
|
315
|
-
goal: goalConfig.initialGoal,
|
|
316
|
-
budgetNook,
|
|
317
|
-
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
318
|
-
verbose: this.verbose,
|
|
319
|
-
};
|
|
320
|
-
const loop = new GoalLoop(loopOptions);
|
|
321
|
-
let result;
|
|
322
|
-
try {
|
|
323
|
-
result = await loop.run();
|
|
324
|
-
}
|
|
325
|
-
catch (err) {
|
|
326
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
327
|
-
if (this.verbose) {
|
|
328
|
-
console.error("[autonomous] GoalLoop threw:", err);
|
|
329
|
-
}
|
|
330
|
-
// Transition to failed so the UI reflects the error.
|
|
331
|
-
await this.runtime.identity.updateGoalStatus("failed").catch(() => { });
|
|
332
|
-
await this.runtime.identity.createPendingTask({
|
|
333
|
-
reason: "unclear_goal",
|
|
334
|
-
description: `Goal loop crashed: ${msg.slice(0, 400)}`,
|
|
335
|
-
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
336
|
-
}).catch(() => { });
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
await this.handleGoalResult(result, goalConfig);
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Dispatch on the terminal state of a GoalLoop run:
|
|
343
|
-
* - complete → store artifact in private KG, pause agent
|
|
344
|
-
* - blocked_budget → create pending task (budget_exhausted), pause
|
|
345
|
-
* - blocked_stuck → create pending task (stuck_3x), pause
|
|
346
|
-
* - blocked_capability → create pending task (needs_capability), pause
|
|
347
|
-
*/
|
|
348
|
-
async handleGoalResult(result, goalConfig) {
|
|
349
|
-
if (result.outcome === "complete") {
|
|
350
|
-
// Store deliverable in private KG
|
|
351
|
-
let artifactId = null;
|
|
352
|
-
try {
|
|
353
|
-
const storeResult = (await this.runtime.connection.request("POST", "/v1/agents/me/knowledge", {
|
|
354
|
-
contentText: result.artifact.body,
|
|
355
|
-
title: result.artifact.title,
|
|
356
|
-
domain: result.artifact.domain,
|
|
357
|
-
visibility: "private",
|
|
358
|
-
knowledgeType: "fact",
|
|
359
|
-
sourceType: "import",
|
|
360
|
-
metadata: {
|
|
361
|
-
goal: goalConfig.initialGoal,
|
|
362
|
-
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
363
|
-
stepsExecuted: result.stepsExecuted,
|
|
364
|
-
spentNook: result.spentNook.toString(),
|
|
365
|
-
},
|
|
366
|
-
}));
|
|
367
|
-
artifactId = storeResult?.id ?? null;
|
|
368
|
-
}
|
|
369
|
-
catch (err) {
|
|
370
|
-
if (this.verbose) {
|
|
371
|
-
console.error("[autonomous] Failed to store goal artifact:", err);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
try {
|
|
375
|
-
await this.runtime.identity.completeGoal(artifactId ?? "unknown");
|
|
376
|
-
}
|
|
377
|
-
catch (err) {
|
|
378
|
-
if (this.verbose) {
|
|
379
|
-
console.error("[autonomous] completeGoal failed:", err);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
// Q3: agent pauses after completion, does not stay reactive
|
|
383
|
-
this.stop();
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
if (result.outcome === "blocked_budget") {
|
|
387
|
-
// initialGoal is non-null here — maybeBootstrapGoal returned early otherwise.
|
|
388
|
-
const goalText = goalConfig.initialGoal ?? "(unknown)";
|
|
389
|
-
await this.runtime.identity.createPendingTask({
|
|
390
|
-
reason: "budget_exhausted",
|
|
391
|
-
description: `Needs top-off to continue goal: ${goalText.slice(0, 300)}`,
|
|
392
|
-
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
393
|
-
}).catch(() => { });
|
|
394
|
-
await this.runtime.identity.updateGoalStatus("paused_awaiting_topoff").catch(() => { });
|
|
395
|
-
this.stop();
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
if (result.outcome === "blocked_stuck") {
|
|
399
|
-
await this.runtime.identity.createPendingTask({
|
|
400
|
-
reason: "stuck_3x",
|
|
401
|
-
description: result.stuckReason,
|
|
402
|
-
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
403
|
-
}).catch(() => { });
|
|
404
|
-
await this.runtime.identity.updateGoalStatus("blocked_needs_decision").catch(() => { });
|
|
405
|
-
this.stop();
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
if (result.outcome === "blocked_capability") {
|
|
409
|
-
await this.runtime.identity.createPendingTask({
|
|
410
|
-
reason: "needs_capability",
|
|
411
|
-
description: result.capabilityNeeded,
|
|
412
|
-
suggestedPresetId: result.suggestedPreset,
|
|
413
|
-
parentSwarmId: goalConfig.goalParentSwarmId,
|
|
414
|
-
}).catch(() => { });
|
|
415
|
-
await this.runtime.identity.updateGoalStatus("blocked_needs_decision").catch(() => { });
|
|
416
|
-
this.stop();
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
// ================================================================
|
|
421
255
|
// Signal handling (proactive.signal)
|
|
422
256
|
// ================================================================
|
|
423
257
|
/**
|
|
@@ -499,8 +333,6 @@ export class AutonomousAgent {
|
|
|
499
333
|
return `proj_bounty_done:${data.bountyId ?? ""}`;
|
|
500
334
|
case "guild_opportunity":
|
|
501
335
|
return `guild:${data.guildId ?? ""}:${addr}`;
|
|
502
|
-
case "workspace_opportunity":
|
|
503
|
-
return `workspace:${data.workspaceId ?? data.sourceId ?? ""}:${addr}`;
|
|
504
336
|
case "team_assembly_suggested":
|
|
505
337
|
return `team_suggest:${data.txHash ?? ""}`;
|
|
506
338
|
case "team_invitation":
|
|
@@ -650,7 +482,9 @@ export class AutonomousAgent {
|
|
|
650
482
|
case "community_gap":
|
|
651
483
|
await this.handleCommunityGap(data);
|
|
652
484
|
break;
|
|
653
|
-
|
|
485
|
+
case "directive":
|
|
486
|
+
await this.handleDirective(data);
|
|
487
|
+
break;
|
|
654
488
|
case "files_committed":
|
|
655
489
|
await this.handleFilesCommitted(data);
|
|
656
490
|
break;
|
|
@@ -763,10 +597,6 @@ export class AutonomousAgent {
|
|
|
763
597
|
case "guild_opportunity":
|
|
764
598
|
await this.handleGuildOpportunity(data);
|
|
765
599
|
break;
|
|
766
|
-
// ── Open Cognitive Workspaces (P3): discoverable/open workspace to join ──
|
|
767
|
-
case "workspace_opportunity":
|
|
768
|
-
await this.handleWorkspaceOpportunity(data);
|
|
769
|
-
break;
|
|
770
600
|
// ── Mining signals ──
|
|
771
601
|
case "mining_opportunity":
|
|
772
602
|
await this.handleMiningOpportunity(data);
|
|
@@ -1293,51 +1123,6 @@ export class AutonomousAgent {
|
|
|
1293
1123
|
console.error("[autonomous] Guild opportunity handling failed:", err);
|
|
1294
1124
|
}
|
|
1295
1125
|
}
|
|
1296
|
-
async handleWorkspaceOpportunity(data) {
|
|
1297
|
-
const meta = data;
|
|
1298
|
-
const name = meta.name ?? meta.title ?? "Unknown Workspace";
|
|
1299
|
-
const workspaceId = meta.workspaceId ?? meta.sourceId ?? "";
|
|
1300
|
-
const visibility = meta.visibility ?? "discoverable";
|
|
1301
|
-
const description = meta.description ?? data.messagePreview ?? "";
|
|
1302
|
-
const memberCount = meta.memberCount ?? 0;
|
|
1303
|
-
const regionCounts = meta.regionCounts ?? {};
|
|
1304
|
-
const openJoinRole = meta.openJoinRole ?? 0;
|
|
1305
|
-
try {
|
|
1306
|
-
const isOpen = visibility === "open";
|
|
1307
|
-
const joinNote = isOpen
|
|
1308
|
-
? `You can self-join instantly (you would join as ${openJoinRole === 1 ? "editor" : "viewer"}).`
|
|
1309
|
-
: "You can request to join; the owner approves.";
|
|
1310
|
-
const regionSummary = Object.entries(regionCounts)
|
|
1311
|
-
.map(([r, c]) => `${r}: ${c}`)
|
|
1312
|
-
.join(", ") || "no cognitive state yet";
|
|
1313
|
-
const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
|
|
1314
|
-
"A cognitive workspace opportunity was found on Nookplot.\n" +
|
|
1315
|
-
`Workspace: ${sanitizeForPrompt(name)}\n` +
|
|
1316
|
-
`Description: ${wrapUntrusted(description, "workspace description")}\n` +
|
|
1317
|
-
`Visibility: ${visibility}\n` +
|
|
1318
|
-
`Members: ${memberCount}\n` +
|
|
1319
|
-
`Cognitive state: ${sanitizeForPrompt(regionSummary)}\n` +
|
|
1320
|
-
`ID: ${workspaceId}\n` +
|
|
1321
|
-
`${joinNote}\n\n` +
|
|
1322
|
-
"Should you join this workspace to collaborate on its shared reasoning state? Respond with INTERESTED or SKIP.\n" +
|
|
1323
|
-
"If interested, briefly explain why (under 200 chars).\n\n" +
|
|
1324
|
-
"Format:\nDECISION: INTERESTED or SKIP\nREASON: why you want to join";
|
|
1325
|
-
const response = await this.generateResponse(prompt);
|
|
1326
|
-
const text = response?.trim() ?? "";
|
|
1327
|
-
if (text.toUpperCase().includes("INTERESTED")) {
|
|
1328
|
-
if (this.verbose) {
|
|
1329
|
-
console.log(`[autonomous] ✓ Interested in workspace "${name}" (supervised — join surfaced as an action)`);
|
|
1330
|
-
}
|
|
1331
|
-
// Joining is surfaced as an available action (join_workspace /
|
|
1332
|
-
// request_workspace_join) for the agent's decision loop — not
|
|
1333
|
-
// auto-executed here (adversarial default: no auto-join).
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
catch (err) {
|
|
1337
|
-
if (this.verbose)
|
|
1338
|
-
console.error("[autonomous] Workspace opportunity handling failed:", err);
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
1126
|
async handleMiningOpportunity(data) {
|
|
1342
1127
|
const meta = data;
|
|
1343
1128
|
const opportunityType = meta.opportunityType ?? "unknown";
|
|
@@ -2230,7 +2015,40 @@ export class AutonomousAgent {
|
|
|
2230
2015
|
console.error("[autonomous] Community gap handling failed:", err);
|
|
2231
2016
|
}
|
|
2232
2017
|
}
|
|
2233
|
-
|
|
2018
|
+
async handleDirective(data) {
|
|
2019
|
+
const directiveContent = data.messagePreview ?? "";
|
|
2020
|
+
const channelId = data.channelId;
|
|
2021
|
+
const community = data.community ?? "general";
|
|
2022
|
+
try {
|
|
2023
|
+
const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
|
|
2024
|
+
"You received a directive on Nookplot.\n" +
|
|
2025
|
+
`Directive:\n${wrapUntrusted(directiveContent, "directive")}\n\n` +
|
|
2026
|
+
"Follow the directive and compose your response.\n" +
|
|
2027
|
+
"If it asks you to post, write the post content.\n" +
|
|
2028
|
+
"If it asks you to discuss, write a discussion message.\n" +
|
|
2029
|
+
"If you can't follow this directive, respond with exactly: [SKIP]\n\n" +
|
|
2030
|
+
"Your response (under 500 chars):";
|
|
2031
|
+
const response = await this.generateResponse(prompt);
|
|
2032
|
+
const content = response?.trim() ?? "";
|
|
2033
|
+
if (content && content !== "[SKIP]") {
|
|
2034
|
+
if (channelId) {
|
|
2035
|
+
await this.runtime.channels.send(channelId, content);
|
|
2036
|
+
if (this.verbose)
|
|
2037
|
+
console.log(`[autonomous] ✓ Directive response sent to channel ${channelId.slice(0, 12)}`);
|
|
2038
|
+
}
|
|
2039
|
+
else {
|
|
2040
|
+
const title = content.slice(0, 100);
|
|
2041
|
+
await this.runtime.memory.publishKnowledge({ title, body: content, community });
|
|
2042
|
+
if (this.verbose)
|
|
2043
|
+
console.log(`[autonomous] ✓ Directive response posted in ${community}`);
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
catch (err) {
|
|
2048
|
+
if (this.verbose)
|
|
2049
|
+
console.error("[autonomous] Directive handling failed:", err);
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2234
2052
|
// ================================================================
|
|
2235
2053
|
// Project collaboration signal handlers
|
|
2236
2054
|
// ================================================================
|
|
@@ -2864,6 +2682,16 @@ export class AutonomousAgent {
|
|
|
2864
2682
|
// ================================================================
|
|
2865
2683
|
// Action request handling (proactive.action.request)
|
|
2866
2684
|
// ================================================================
|
|
2685
|
+
/**
|
|
2686
|
+
* Execute a `use_frontier_model` action — delegates to the shared
|
|
2687
|
+
* {@link runFrontierPass} so the runtime + CLI dispatch paths can't drift on
|
|
2688
|
+
* this money path. Consumes an owner-reserved pass, runs a one-shot Surplus
|
|
2689
|
+
* completion paid by the agent's OWN x402 key, finalizes (or reverts on
|
|
2690
|
+
* failure). Returns the frontier answer, or an `{ error }` tool result.
|
|
2691
|
+
*/
|
|
2692
|
+
async executeFrontierPass(args, agentAddress) {
|
|
2693
|
+
return runFrontierPass(this.runtime.connection, this.runtime.economy, args, agentAddress);
|
|
2694
|
+
}
|
|
2867
2695
|
async handleActionRequest(event) {
|
|
2868
2696
|
if (!this.isRunning)
|
|
2869
2697
|
return;
|
|
@@ -2917,18 +2745,6 @@ export class AutonomousAgent {
|
|
|
2917
2745
|
triggers: this.doomLoopTriggers,
|
|
2918
2746
|
actionType,
|
|
2919
2747
|
});
|
|
2920
|
-
// Track C.2: also push to gateway as fire-and-forget telemetry so
|
|
2921
|
-
// ops dashboards can answer "which tools most often misbehave?"
|
|
2922
|
-
// and "is this agent stuck right now?" — see
|
|
2923
|
-
// gateway/src/services/doomLoopMetrics.ts. Errors are swallowed so
|
|
2924
|
-
// a backend outage never blocks the runtime's recovery path.
|
|
2925
|
-
void this.runtime.connection
|
|
2926
|
-
.request("POST", "/v1/agents/me/doom-loop-event", {
|
|
2927
|
-
offender: doomOffender,
|
|
2928
|
-
triggers: this.doomLoopTriggers,
|
|
2929
|
-
actionType,
|
|
2930
|
-
})
|
|
2931
|
-
.catch(() => { });
|
|
2932
2748
|
if (this.doomLoopTriggers >= AUTONOMOUS_DOOM_LOOP_MAX_TRIGGERS) {
|
|
2933
2749
|
if (this.verbose) {
|
|
2934
2750
|
console.warn(`[autonomous] ✗ doom loop on '${doomOffender}' (${this.doomLoopTriggers} triggers) — aborting cycle`);
|
|
@@ -3034,6 +2850,24 @@ export class AutonomousAgent {
|
|
|
3034
2850
|
});
|
|
3035
2851
|
return;
|
|
3036
2852
|
}
|
|
2853
|
+
// ── Intercept use_frontier_model (client-executed frontier pass) ──
|
|
2854
|
+
// Not a gateway tool: consume an owner-reserved pass, run a one-shot
|
|
2855
|
+
// Surplus completion paid by the agent's OWN client-signed x402 key, then
|
|
2856
|
+
// finalize (or revert on failure). The gateway can't run this
|
|
2857
|
+
// non-custodially. See ROADMAP_frontier-passes.md.
|
|
2858
|
+
if (actionType === "use_frontier_model") {
|
|
2859
|
+
result = await this.executeFrontierPass(args, agentAddress);
|
|
2860
|
+
result = await guardrails.runOutput(actionType, result);
|
|
2861
|
+
hooks.emitFireAndForget("tool_output", { toolName: actionType, args, result });
|
|
2862
|
+
if (actionId)
|
|
2863
|
+
await this.runtime.proactive.completeAction(actionId, undefined, result);
|
|
2864
|
+
if (this.verbose)
|
|
2865
|
+
console.log(`[autonomous] ✓ use_frontier_model`);
|
|
2866
|
+
hooks.emitFireAndForget("action_end", {
|
|
2867
|
+
actionType, args, result, durationMs: Date.now() - startTime, actionId,
|
|
2868
|
+
});
|
|
2869
|
+
return;
|
|
2870
|
+
}
|
|
3037
2871
|
// ── Unified dispatch via POST /v1/actions/execute ──
|
|
3038
2872
|
// The gateway's ToolDispatcher routes the call to the correct internal
|
|
3039
2873
|
// endpoint, replacing the 2000+ line switch statement that was here before.
|