@nookplot/runtime 0.5.142 → 0.5.144
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__/bdAgentPack.test.d.ts +2 -0
- package/dist/__tests__/bdAgentPack.test.d.ts.map +1 -0
- package/dist/__tests__/bdAgentPack.test.js +44 -0
- package/dist/__tests__/bdAgentPack.test.js.map +1 -0
- package/dist/__tests__/externalMcpTools.test.d.ts +2 -0
- package/dist/__tests__/externalMcpTools.test.d.ts.map +1 -0
- package/dist/__tests__/externalMcpTools.test.js +94 -0
- package/dist/__tests__/externalMcpTools.test.js.map +1 -0
- package/dist/__tests__/pack.gating.test.d.ts +2 -0
- package/dist/__tests__/pack.gating.test.d.ts.map +1 -0
- package/dist/__tests__/pack.gating.test.js +134 -0
- package/dist/__tests__/pack.gating.test.js.map +1 -0
- package/dist/__tests__/pack.test.d.ts +2 -0
- package/dist/__tests__/pack.test.d.ts.map +1 -0
- package/dist/__tests__/pack.test.js +299 -0
- package/dist/__tests__/pack.test.js.map +1 -0
- package/dist/__tests__/packLoader.test.d.ts +2 -0
- package/dist/__tests__/packLoader.test.d.ts.map +1 -0
- package/dist/__tests__/packLoader.test.js +304 -0
- package/dist/__tests__/packLoader.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 +766 -0
- package/dist/__tests__/presetLoader.test.js.map +1 -0
- 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 +7 -2
- package/dist/actionCatalog.generated.js.map +1 -1
- package/dist/actionCatalog.js +4 -12
- package/dist/actionCatalog.js.map +1 -1
- package/dist/autonomous.d.ts +24 -1
- package/dist/autonomous.d.ts.map +1 -1
- package/dist/autonomous.js +66 -8
- package/dist/autonomous.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/pack.d.ts +181 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/pack.js +379 -0
- package/dist/pack.js.map +1 -0
- package/dist/packLoader.d.ts +109 -0
- package/dist/packLoader.d.ts.map +1 -0
- package/dist/packLoader.js +236 -0
- package/dist/packLoader.js.map +1 -0
- package/dist/presetLoader.d.ts +132 -0
- package/dist/presetLoader.d.ts.map +1 -0
- package/dist/presetLoader.js +740 -0
- package/dist/presetLoader.js.map +1 -0
- package/dist/signalActionMap.d.ts +17 -1
- package/dist/signalActionMap.d.ts.map +1 -1
- package/dist/signalActionMap.js +37 -2
- package/dist/signalActionMap.js.map +1 -1
- package/dist/tools.d.ts +23 -7
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +20 -6
- package/dist/tools.js.map +1 -1
- package/package.json +2 -2
package/dist/autonomous.js
CHANGED
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
import { prepareSignRelay } from "./signing.js";
|
|
43
43
|
import { runFrontierPass } from "./frontierPass.js";
|
|
44
44
|
import { wrapUntrusted, sanitizeForPrompt, UNTRUSTED_CONTENT_INSTRUCTION } from "./contentSafety.js";
|
|
45
|
-
import { getAvailableActionsFromMap } from "./signalActionMap.js";
|
|
45
|
+
import { getAvailableActionsFromMap, resolveDispatchToolName, CORE_ACTIONS } from "./signalActionMap.js";
|
|
46
|
+
import { resolvePackActions } from "./pack.js";
|
|
46
47
|
import { getCategoryListing, getToolsInCategory } from "./actionCatalog.js";
|
|
47
48
|
import { WakeUpStack } from "./wakeUpStack.js";
|
|
48
49
|
import { hooks as defaultHooks } from "./hooks.js";
|
|
@@ -145,8 +146,8 @@ const ON_CHAIN_ACTIONS = new Set([
|
|
|
145
146
|
* // → "- reply: Send a text reply in the current context. Params: content (string)\n..."
|
|
146
147
|
* ```
|
|
147
148
|
*/
|
|
148
|
-
export function getAvailableActions(signalType, loadedCategories) {
|
|
149
|
-
return getAvailableActionsFromMap(signalType, loadedCategories ?? new Set());
|
|
149
|
+
export function getAvailableActions(signalType, loadedCategories, externalActions, packActions) {
|
|
150
|
+
return getAvailableActionsFromMap(signalType, loadedCategories ?? new Set(), externalActions, packActions);
|
|
150
151
|
}
|
|
151
152
|
/**
|
|
152
153
|
* Maps a `mining_opportunity` signal's optional `track` field to the
|
|
@@ -207,6 +208,29 @@ export class AutonomousAgent {
|
|
|
207
208
|
this.approvalHandler = options.onApproval;
|
|
208
209
|
this.cooldownSec = options.responseCooldown ?? 120;
|
|
209
210
|
this.wakeUpStack = new WakeUpStack(runtime);
|
|
211
|
+
this.packActions = options.pack ? resolvePackActions(options.pack) : null;
|
|
212
|
+
}
|
|
213
|
+
/** External MCP tools (mounted servers) exposed as `mcp__<server>__<tool>` actions. */
|
|
214
|
+
externalMcpActions = [];
|
|
215
|
+
/**
|
|
216
|
+
* Resolved action set of the loaded pack (null = no pack, ungated).
|
|
217
|
+
* Set once at construction from options.pack — packs are immutable per load.
|
|
218
|
+
*/
|
|
219
|
+
packActions;
|
|
220
|
+
/**
|
|
221
|
+
* Fetch the agent's mounted external MCP tools and expose them as
|
|
222
|
+
* available actions (ROADMAP_external-mcp-connectors Phase 1). Runs at
|
|
223
|
+
* start(); call again after connectMcpServer to pick up new mounts.
|
|
224
|
+
*/
|
|
225
|
+
async refreshExternalMcpActions() {
|
|
226
|
+
const tools = await this.runtime.tools.listMcpTools();
|
|
227
|
+
// The gateway computes the provider-safe wire name at discovery; tools
|
|
228
|
+
// without one (unmappable names) are visible in listMcpTools but can
|
|
229
|
+
// never be dispatched, so they don't surface as actions.
|
|
230
|
+
this.externalMcpActions = tools
|
|
231
|
+
.map((t) => t.wireName)
|
|
232
|
+
.filter((n) => typeof n === "string" && n.startsWith("mcp__"));
|
|
233
|
+
return this.externalMcpActions;
|
|
210
234
|
}
|
|
211
235
|
/** Start listening for proactive signals and action requests. */
|
|
212
236
|
start() {
|
|
@@ -243,6 +267,13 @@ export class AutonomousAgent {
|
|
|
243
267
|
if (this.verbose) {
|
|
244
268
|
console.log("[autonomous] AutonomousAgent started — handling signals + actions");
|
|
245
269
|
}
|
|
270
|
+
// External MCP tools — loaded once at boot so mounted servers' tools
|
|
271
|
+
// surface in getAvailableActions and dispatch as `mcp:<server>:<tool>`.
|
|
272
|
+
this.refreshExternalMcpActions().catch((err) => {
|
|
273
|
+
if (this.verbose) {
|
|
274
|
+
console.error("[autonomous] External MCP tool load failed:", err);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
246
277
|
}
|
|
247
278
|
/** Stop the autonomous agent. */
|
|
248
279
|
stop() {
|
|
@@ -1407,7 +1438,11 @@ export class AutonomousAgent {
|
|
|
1407
1438
|
console.log("[autonomous] No action parsed from response");
|
|
1408
1439
|
return;
|
|
1409
1440
|
}
|
|
1410
|
-
|
|
1441
|
+
// Wire names (`mcp__<server>__<tool>`) are case-sensitive registry keys —
|
|
1442
|
+
// lowercasing a mixed-case server/tool segment would dispatch a name that
|
|
1443
|
+
// doesn't exist (and trip pack gating with a misleading refusal).
|
|
1444
|
+
const rawAction = actionMatch[1];
|
|
1445
|
+
const actionType = rawAction.startsWith("mcp__") ? rawAction : rawAction.toLowerCase();
|
|
1411
1446
|
let payload = {};
|
|
1412
1447
|
const paramsMatch = text.match(/PARAMS:\s*(\{[\s\S]*\})/i);
|
|
1413
1448
|
if (paramsMatch) {
|
|
@@ -2707,6 +2742,29 @@ export class AutonomousAgent {
|
|
|
2707
2742
|
if (this.verbose) {
|
|
2708
2743
|
console.log(`[autonomous] Action request: ${actionType}${actionId ? ` (${actionId})` : ""}`);
|
|
2709
2744
|
}
|
|
2745
|
+
// Pack gating (ROADMAP_external-mcp-connectors Phase 3): with a pack
|
|
2746
|
+
// loaded, refuse anything outside CORE ∪ pack ∪ mounted-MCP. Gated
|
|
2747
|
+
// prompts never offer these — this guard catches handler-injected or
|
|
2748
|
+
// hallucinated action types.
|
|
2749
|
+
if (this.packActions) {
|
|
2750
|
+
const allowed = actionType.startsWith("mcp__")
|
|
2751
|
+
? this.externalMcpActions.includes(actionType)
|
|
2752
|
+
: CORE_ACTIONS.includes(actionType) || this.packActions.includes(actionType);
|
|
2753
|
+
if (!allowed) {
|
|
2754
|
+
if (this.verbose)
|
|
2755
|
+
console.log(`[autonomous] Action denied by pack gating: ${actionType}`);
|
|
2756
|
+
hooks.emitFireAndForget("action_rejected", {
|
|
2757
|
+
actionType, args, reason: "Not allowed by loaded pack", actionId,
|
|
2758
|
+
});
|
|
2759
|
+
if (actionId) {
|
|
2760
|
+
try {
|
|
2761
|
+
await this.runtime.proactive.rejectDelegatedAction(actionId, "Not allowed by loaded pack");
|
|
2762
|
+
}
|
|
2763
|
+
catch { /* best-effort */ }
|
|
2764
|
+
}
|
|
2765
|
+
return;
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2710
2768
|
// Approval gate: on-chain actions require approval when handler is set
|
|
2711
2769
|
if (this.approvalHandler && ON_CHAIN_ACTIONS.has(actionType)) {
|
|
2712
2770
|
const approved = await this.approvalHandler(actionType, args);
|
|
@@ -2875,7 +2933,7 @@ export class AutonomousAgent {
|
|
|
2875
2933
|
// the original `payload` — otherwise input-guardrail mutations
|
|
2876
2934
|
// (lowercase normalization, content sanitization, etc.) silently get
|
|
2877
2935
|
// dropped on the way to the gateway.
|
|
2878
|
-
const toolName =
|
|
2936
|
+
const toolName = resolveDispatchToolName(actionType);
|
|
2879
2937
|
const dispatchPayload = {
|
|
2880
2938
|
...args,
|
|
2881
2939
|
...(suggestedContent ? { suggestedContent } : {}),
|
|
@@ -3444,7 +3502,7 @@ export class AutonomousAgent {
|
|
|
3444
3502
|
if (!this.generateResponse)
|
|
3445
3503
|
return;
|
|
3446
3504
|
try {
|
|
3447
|
-
const actions = getAvailableActionsFromMap("swarm_subtask_available", this.loadedCategories);
|
|
3505
|
+
const actions = getAvailableActionsFromMap("swarm_subtask_available", this.loadedCategories, this.externalMcpActions, this.packActions);
|
|
3448
3506
|
const prompt = `A swarm "${sanitizeForPrompt(swarmTitle.slice(0, 100))}" has open subtasks matching your skills.\n` +
|
|
3449
3507
|
`Swarm ID: ${swarmId}\n` +
|
|
3450
3508
|
`Matching skills: ${skillTags.slice(0, 10).join(", ")}\n\n` +
|
|
@@ -3472,7 +3530,7 @@ export class AutonomousAgent {
|
|
|
3472
3530
|
if (!this.generateResponse)
|
|
3473
3531
|
return;
|
|
3474
3532
|
try {
|
|
3475
|
-
const actions = getAvailableActionsFromMap("swarm_result_submitted", this.loadedCategories);
|
|
3533
|
+
const actions = getAvailableActionsFromMap("swarm_result_submitted", this.loadedCategories, this.externalMcpActions, this.packActions);
|
|
3476
3534
|
const prompt = `A result was submitted for subtask "${sanitizeForPrompt(subtaskTitle.slice(0, 100))}" in your swarm.\n` +
|
|
3477
3535
|
`Swarm ID: ${swarmId}\n` +
|
|
3478
3536
|
`Submitted by: ${sanitizeForPrompt((submittedBy).slice(0, 12))}...\n\n` +
|
|
@@ -3522,7 +3580,7 @@ export class AutonomousAgent {
|
|
|
3522
3580
|
searchResult = await this.parseAndExecuteAction(searchText);
|
|
3523
3581
|
}
|
|
3524
3582
|
// Step 2: Based on search results, store an insight
|
|
3525
|
-
const actions = getAvailableActionsFromMap("dream_prompt", this.loadedCategories);
|
|
3583
|
+
const actions = getAvailableActionsFromMap("dream_prompt", this.loadedCategories, this.externalMcpActions, this.packActions);
|
|
3526
3584
|
const searchContext = searchResult
|
|
3527
3585
|
? `\nSearch results (summarized): ${JSON.stringify(searchResult).slice(0, 1500)}\n`
|
|
3528
3586
|
: "\nNo search results found — consider creating foundational knowledge for these domains.\n";
|