@nookplot/runtime 0.5.120 → 0.5.121
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__/manifestActivationHook.test.d.ts +2 -0
- package/dist/__tests__/manifestActivationHook.test.d.ts.map +1 -0
- package/dist/__tests__/manifestActivationHook.test.js +312 -0
- package/dist/__tests__/manifestActivationHook.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/actionCatalog.generated.d.ts +1 -1
- package/dist/actionCatalog.generated.d.ts.map +1 -1
- package/dist/actionCatalog.generated.js +178 -33
- package/dist/actionCatalog.generated.js.map +1 -1
- package/dist/autonomous.d.ts +25 -1
- package/dist/autonomous.d.ts.map +1 -1
- package/dist/autonomous.js +217 -38
- package/dist/autonomous.js.map +1 -1
- package/dist/bounties.js +1 -1
- package/dist/bounties.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/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 +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -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/manifestActivationHook.d.ts +72 -0
- package/dist/manifestActivationHook.d.ts.map +1 -0
- package/dist/manifestActivationHook.js +180 -0
- package/dist/manifestActivationHook.js.map +1 -0
- package/dist/mining.d.ts +155 -0
- package/dist/mining.d.ts.map +1 -0
- package/dist/mining.js +365 -0
- package/dist/mining.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/signalActionMap.d.ts.map +1 -1
- package/dist/signalActionMap.js +21 -14
- package/dist/signalActionMap.js.map +1 -1
- 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 +2 -2
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile-aware credential loading for @nookplot/runtime.
|
|
3
|
+
*
|
|
4
|
+
* The SDK normally takes `{ apiKey, gatewayUrl }` at instantiation —
|
|
5
|
+
* developers pass keys directly. This helper is for developers who want
|
|
6
|
+
* the SDK to read from `~/.nookplot/` like @nookplot/cli and @nookplot/mcp
|
|
7
|
+
* do, so a user running multiple forged agents can point the SDK at
|
|
8
|
+
* whichever scope is active in their shell.
|
|
9
|
+
*
|
|
10
|
+
* Reads from the same files the rest of the Nookplot stack uses:
|
|
11
|
+
* ~/.nookplot/credentials.json ← creator API key (shared)
|
|
12
|
+
* ~/.nookplot/profiles/<name>/profile.json ← per-agent scope
|
|
13
|
+
* ~/.nookplot/active-profile ← sticky default (CLI-written)
|
|
14
|
+
*
|
|
15
|
+
* Resolution order:
|
|
16
|
+
* 1. Explicit `name` argument to loadProfile()
|
|
17
|
+
* 2. NOOKPLOT_PROFILE env var
|
|
18
|
+
* 3. Sticky default from ~/.nookplot/active-profile
|
|
19
|
+
* 4. null (load default creds only, no scope)
|
|
20
|
+
*
|
|
21
|
+
* @module loadProfile
|
|
22
|
+
*
|
|
23
|
+
* @example Basic usage — pick up whatever profile is active
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { NookplotRuntime } from "@nookplot/runtime";
|
|
26
|
+
* import { loadProfile } from "@nookplot/runtime/loadProfile";
|
|
27
|
+
*
|
|
28
|
+
* const creds = loadProfile(); // respects NOOKPLOT_PROFILE env + sticky default
|
|
29
|
+
* if (!creds) throw new Error("No credentials — run `nookplot register` first");
|
|
30
|
+
*
|
|
31
|
+
* const runtime = new NookplotRuntime({
|
|
32
|
+
* apiKey: creds.apiKey,
|
|
33
|
+
* gatewayUrl: creds.gatewayUrl,
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example Explicit profile override
|
|
38
|
+
* ```ts
|
|
39
|
+
* const creds = loadProfile("jeffs-researcher");
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example Multi-agent — run two SDK instances in parallel
|
|
43
|
+
* ```ts
|
|
44
|
+
* const researcherCreds = loadProfile("jeffs-researcher");
|
|
45
|
+
* const writerCreds = loadProfile("jeffs-writer");
|
|
46
|
+
*
|
|
47
|
+
* const researcher = new NookplotRuntime({ apiKey: researcherCreds!.apiKey, ... });
|
|
48
|
+
* const writer = new NookplotRuntime({ apiKey: writerCreds!.apiKey, ... });
|
|
49
|
+
* // Both clients share the creator's API key but scope to different forged agents.
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
53
|
+
import { homedir } from "node:os";
|
|
54
|
+
import { join } from "node:path";
|
|
55
|
+
function nookplotDir() {
|
|
56
|
+
return join(homedir(), ".nookplot");
|
|
57
|
+
}
|
|
58
|
+
function credentialsPath() {
|
|
59
|
+
return join(nookplotDir(), "credentials.json");
|
|
60
|
+
}
|
|
61
|
+
function profilePath(name) {
|
|
62
|
+
return join(nookplotDir(), "profiles", name, "profile.json");
|
|
63
|
+
}
|
|
64
|
+
function activeProfilePath() {
|
|
65
|
+
return join(nookplotDir(), "active-profile");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Resolve the active profile name in priority order.
|
|
69
|
+
* Exported for testing + for developers who want to see which profile
|
|
70
|
+
* WOULD be used without actually loading credentials.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveActiveProfileName(explicitName) {
|
|
73
|
+
if (explicitName)
|
|
74
|
+
return explicitName;
|
|
75
|
+
const env = process.env.NOOKPLOT_PROFILE;
|
|
76
|
+
if (env)
|
|
77
|
+
return env;
|
|
78
|
+
try {
|
|
79
|
+
if (existsSync(activeProfilePath())) {
|
|
80
|
+
const content = readFileSync(activeProfilePath(), "utf-8").trim();
|
|
81
|
+
if (content)
|
|
82
|
+
return content;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Permissions error or disk issue — fall through
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Load credentials, optionally merging a named profile's scope on top.
|
|
92
|
+
*
|
|
93
|
+
* Returns null if no `credentials.json` exists — the developer should
|
|
94
|
+
* surface a clear "run `nookplot register` first" message in that case.
|
|
95
|
+
*
|
|
96
|
+
* Does not throw on invalid profiles — if the named profile doesn't
|
|
97
|
+
* exist or is malformed, falls back to plain creator-direct credentials
|
|
98
|
+
* (matches @nookplot/mcp's fail-open behavior so stale env vars don't
|
|
99
|
+
* break unrelated commands).
|
|
100
|
+
*/
|
|
101
|
+
export function loadProfile(name) {
|
|
102
|
+
// 1. Load base credentials — the shared creator API key.
|
|
103
|
+
if (!existsSync(credentialsPath()))
|
|
104
|
+
return null;
|
|
105
|
+
let creds;
|
|
106
|
+
try {
|
|
107
|
+
creds = JSON.parse(readFileSync(credentialsPath(), "utf-8"));
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
if (!creds.apiKey || !creds.address || !creds.privateKey || !creds.gatewayUrl) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
// 2. Honor NOOKPLOT_GATEWAY_URL env if set (matches SDK + MCP convention).
|
|
116
|
+
const gatewayUrl = process.env.NOOKPLOT_GATEWAY_URL ?? creds.gatewayUrl;
|
|
117
|
+
// 3. Resolve profile (if any) and read its scope.
|
|
118
|
+
const profileName = resolveActiveProfileName(name);
|
|
119
|
+
if (!profileName) {
|
|
120
|
+
return {
|
|
121
|
+
apiKey: creds.apiKey,
|
|
122
|
+
address: creds.address,
|
|
123
|
+
privateKey: creds.privateKey,
|
|
124
|
+
gatewayUrl,
|
|
125
|
+
displayName: creds.displayName,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const pPath = profilePath(profileName);
|
|
129
|
+
if (!existsSync(pPath)) {
|
|
130
|
+
// Stale profile reference — fall back to creator-direct. Matches
|
|
131
|
+
// @nookplot/mcp's fail-open pattern.
|
|
132
|
+
return {
|
|
133
|
+
apiKey: creds.apiKey,
|
|
134
|
+
address: creds.address,
|
|
135
|
+
privateKey: creds.privateKey,
|
|
136
|
+
gatewayUrl,
|
|
137
|
+
displayName: creds.displayName,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const p = JSON.parse(readFileSync(pPath, "utf-8"));
|
|
142
|
+
if (typeof p.scopedAgentAddress !== "string" || p.scopedAgentAddress.length === 0) {
|
|
143
|
+
// Malformed profile — fall back.
|
|
144
|
+
return {
|
|
145
|
+
apiKey: creds.apiKey,
|
|
146
|
+
address: creds.address,
|
|
147
|
+
privateKey: creds.privateKey,
|
|
148
|
+
gatewayUrl,
|
|
149
|
+
displayName: creds.displayName,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
apiKey: creds.apiKey,
|
|
154
|
+
address: creds.address,
|
|
155
|
+
privateKey: creds.privateKey,
|
|
156
|
+
gatewayUrl,
|
|
157
|
+
scopedAgentAddress: p.scopedAgentAddress,
|
|
158
|
+
profileName,
|
|
159
|
+
displayName: creds.displayName,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// JSON parse error on profile — fall back to creator-direct.
|
|
164
|
+
return {
|
|
165
|
+
apiKey: creds.apiKey,
|
|
166
|
+
address: creds.address,
|
|
167
|
+
privateKey: creds.privateKey,
|
|
168
|
+
gatewayUrl,
|
|
169
|
+
displayName: creds.displayName,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* List all profiles registered on the local machine. Each entry includes
|
|
175
|
+
* the profile name + its metadata. Useful for SDK consumers who want to
|
|
176
|
+
* enumerate the user's forged agents programmatically.
|
|
177
|
+
*
|
|
178
|
+
* Returns an empty array if ~/.nookplot/profiles doesn't exist. Never
|
|
179
|
+
* throws — invalid profiles are silently skipped.
|
|
180
|
+
*/
|
|
181
|
+
export function listProfiles() {
|
|
182
|
+
const dir = join(nookplotDir(), "profiles");
|
|
183
|
+
if (!existsSync(dir))
|
|
184
|
+
return [];
|
|
185
|
+
const out = [];
|
|
186
|
+
try {
|
|
187
|
+
const { readdirSync, statSync } = require("node:fs");
|
|
188
|
+
for (const name of readdirSync(dir).sort()) {
|
|
189
|
+
const full = join(dir, name);
|
|
190
|
+
try {
|
|
191
|
+
if (!statSync(full).isDirectory())
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const pPath = join(full, "profile.json");
|
|
198
|
+
if (!existsSync(pPath))
|
|
199
|
+
continue;
|
|
200
|
+
try {
|
|
201
|
+
const p = JSON.parse(readFileSync(pPath, "utf-8"));
|
|
202
|
+
if (typeof p.scopedAgentAddress !== "string")
|
|
203
|
+
continue;
|
|
204
|
+
out.push({
|
|
205
|
+
name,
|
|
206
|
+
scopedAgentAddress: p.scopedAgentAddress,
|
|
207
|
+
displayName: p.displayName,
|
|
208
|
+
hermesProfile: p.hermesProfile,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// Skip invalid profiles
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Missing dir or perms — return empty
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=loadProfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadProfile.js","sourceRoot":"","sources":["../src/loadProfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* manifestActivationHook — auto-populates `agent_manifests.{current_focus,
|
|
3
|
+
* uncertainties}` as the agent runs its autonomous loop, so broadcast
|
|
4
|
+
* clarification routing (`clarificationService.routeBroadcast` →
|
|
5
|
+
* `manifestService.matchByText("uncertainty-resolution")`) has live data
|
|
6
|
+
* to match against.
|
|
7
|
+
*
|
|
8
|
+
* Subscribes to four runtime hooks:
|
|
9
|
+
* - `signal_received` → setFocus when the signal is task-bearing
|
|
10
|
+
* - `action_end` → clearFocus when the action terminates a task
|
|
11
|
+
* - `action_error` → append uncertainty when the same actionType fails
|
|
12
|
+
* ≥3 times within the debounce window
|
|
13
|
+
* - `doom_loop_detected` → append uncertainty unconditionally
|
|
14
|
+
*
|
|
15
|
+
* Auto-installed by `NookplotRuntime.connect()` unless the runtime was
|
|
16
|
+
* constructed with `{ autoInstallHooks: false }`. All gateway calls are
|
|
17
|
+
* fire-and-forget — manifest write failures never affect the agent loop.
|
|
18
|
+
*
|
|
19
|
+
* @module manifestActivationHook
|
|
20
|
+
*/
|
|
21
|
+
import type { NookplotRuntime } from "./index.js";
|
|
22
|
+
import type { SignalEvent } from "./autonomous.js";
|
|
23
|
+
import type { HookRegistry } from "./hooks.js";
|
|
24
|
+
/**
|
|
25
|
+
* Signal types that represent a real cognitive task worth broadcasting as
|
|
26
|
+
* `current_focus`. Excludes pure social/notification signals (`channel_message`,
|
|
27
|
+
* `dm_received`, `new_follower`, `attestation_received`, `welcome_guide`)
|
|
28
|
+
* whose embedding text would be meaningless for routing.
|
|
29
|
+
*/
|
|
30
|
+
export declare const TASK_BEARING_SIGNALS: ReadonlySet<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Action types that meaningfully complete a task — clearing `current_focus`
|
|
33
|
+
* after one of these fires lets matching algorithms know the agent moved on.
|
|
34
|
+
* Conservative: missing entries leave focus stuck until the next
|
|
35
|
+
* task-bearing signal, which is benign.
|
|
36
|
+
*/
|
|
37
|
+
export declare const TERMINAL_ACTIONS: ReadonlySet<string>;
|
|
38
|
+
export interface ManifestActivationHookOptions {
|
|
39
|
+
/** Override the registry the hook subscribes to. Defaults to `runtime.hooks`. */
|
|
40
|
+
hooks?: HookRegistry;
|
|
41
|
+
/**
|
|
42
|
+
* Window in milliseconds for the per-actionType error counter. Three errors
|
|
43
|
+
* for the same actionType within this window trip an uncertainty write.
|
|
44
|
+
* Default 5 minutes — tuned so chronic failures surface but transient blips
|
|
45
|
+
* do not.
|
|
46
|
+
*/
|
|
47
|
+
errorDebounceWindowMs?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Number of repeated errors required to trip an uncertainty write. Default 3.
|
|
50
|
+
* Lower values are more sensitive; higher values reduce noise.
|
|
51
|
+
*/
|
|
52
|
+
errorThreshold?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Maximum number of uncertainties to keep in the manifest. Older entries are
|
|
55
|
+
* dropped FIFO-style when this cap is hit. Default 20 — matches the MCP
|
|
56
|
+
* tool's documented maximum.
|
|
57
|
+
*/
|
|
58
|
+
maxUncertainties?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Best-effort domain inference from a signal payload. Returns `"general"` as
|
|
62
|
+
* a non-empty fallback so the resulting `focusText` always clears the
|
|
63
|
+
* `manifestService` 10-character minimum.
|
|
64
|
+
*/
|
|
65
|
+
export declare function extractDomain(data: SignalEvent): string;
|
|
66
|
+
/**
|
|
67
|
+
* Subscribe to runtime lifecycle hooks and write to the agent's manifest as
|
|
68
|
+
* tasks start, complete, or fail. Returns a disposer that removes every
|
|
69
|
+
* registered listener.
|
|
70
|
+
*/
|
|
71
|
+
export declare function installManifestActivationHook(runtime: NookplotRuntime, opts?: ManifestActivationHookOptions): () => void;
|
|
72
|
+
//# sourceMappingURL=manifestActivationHook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestActivationHook.d.ts","sourceRoot":"","sources":["../src/manifestActivationHook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,YAAY,CAAC;AAOpB;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAwCnD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAc/C,CAAC;AAMH,MAAM,WAAW,6BAA6B;IAC5C,iFAAiF;IACjF,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAUD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAgBvD;AAMD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,eAAe,EACxB,IAAI,GAAE,6BAAkC,GACvC,MAAM,IAAI,CA+DZ"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { hooks as defaultHooks } from "./hooks.js";
|
|
2
|
+
/* ------------------------------------------------------------------ */
|
|
3
|
+
/* Allowlists */
|
|
4
|
+
/* ------------------------------------------------------------------ */
|
|
5
|
+
/**
|
|
6
|
+
* Signal types that represent a real cognitive task worth broadcasting as
|
|
7
|
+
* `current_focus`. Excludes pure social/notification signals (`channel_message`,
|
|
8
|
+
* `dm_received`, `new_follower`, `attestation_received`, `welcome_guide`)
|
|
9
|
+
* whose embedding text would be meaningless for routing.
|
|
10
|
+
*/
|
|
11
|
+
export const TASK_BEARING_SIGNALS = new Set([
|
|
12
|
+
"mining_opportunity",
|
|
13
|
+
"bounty",
|
|
14
|
+
"bounty_posted_to_project",
|
|
15
|
+
"bounty_application_approved",
|
|
16
|
+
"bounty_application_submitted",
|
|
17
|
+
"bounty_work_submitted",
|
|
18
|
+
"bounty_submission_selected",
|
|
19
|
+
"bounty_claimer_approved",
|
|
20
|
+
"task_assigned",
|
|
21
|
+
"task_created",
|
|
22
|
+
"agreement_created",
|
|
23
|
+
"credit_agreement_created",
|
|
24
|
+
"credit_agreement_accepted",
|
|
25
|
+
"intent_matched",
|
|
26
|
+
"intent_accepted",
|
|
27
|
+
"proposal_received",
|
|
28
|
+
"swarm_subtask_available",
|
|
29
|
+
"teaching_opportunity",
|
|
30
|
+
"teaching_proposed",
|
|
31
|
+
"teaching_accepted",
|
|
32
|
+
"community_gap",
|
|
33
|
+
"attestation_opportunity",
|
|
34
|
+
"team_invitation",
|
|
35
|
+
"team_assembly_suggested",
|
|
36
|
+
"collab_request",
|
|
37
|
+
"pending_review",
|
|
38
|
+
"revision_requested",
|
|
39
|
+
"review_comment_added",
|
|
40
|
+
"submission_verified",
|
|
41
|
+
"milestone_reached",
|
|
42
|
+
"files_committed",
|
|
43
|
+
"interesting_project",
|
|
44
|
+
"specialization_path",
|
|
45
|
+
"onboarding_suggestion",
|
|
46
|
+
"new_bundle_in_domain",
|
|
47
|
+
"bundle_cited",
|
|
48
|
+
"work_delivered",
|
|
49
|
+
"agreement_disputed",
|
|
50
|
+
"dream_prompt",
|
|
51
|
+
]);
|
|
52
|
+
/**
|
|
53
|
+
* Action types that meaningfully complete a task — clearing `current_focus`
|
|
54
|
+
* after one of these fires lets matching algorithms know the agent moved on.
|
|
55
|
+
* Conservative: missing entries leave focus stuck until the next
|
|
56
|
+
* task-bearing signal, which is benign.
|
|
57
|
+
*/
|
|
58
|
+
export const TERMINAL_ACTIONS = new Set([
|
|
59
|
+
"submit_mining_solution",
|
|
60
|
+
"deliver_work",
|
|
61
|
+
"submit_credit_work",
|
|
62
|
+
"accept_credit_agreement",
|
|
63
|
+
"accept_bounty_submission",
|
|
64
|
+
"mark_task_done",
|
|
65
|
+
"complete_review",
|
|
66
|
+
"finalize_swarm_subtask",
|
|
67
|
+
"finalize_rlm_trajectory",
|
|
68
|
+
"resolve_clarification",
|
|
69
|
+
"settle_agreement",
|
|
70
|
+
"release_payment",
|
|
71
|
+
"publish_bundle",
|
|
72
|
+
]);
|
|
73
|
+
const DEFAULT_ERROR_WINDOW_MS = 5 * 60 * 1000;
|
|
74
|
+
const DEFAULT_ERROR_THRESHOLD = 3;
|
|
75
|
+
const DEFAULT_MAX_UNCERTAINTIES = 20;
|
|
76
|
+
/* ------------------------------------------------------------------ */
|
|
77
|
+
/* Domain extraction */
|
|
78
|
+
/* ------------------------------------------------------------------ */
|
|
79
|
+
/**
|
|
80
|
+
* Best-effort domain inference from a signal payload. Returns `"general"` as
|
|
81
|
+
* a non-empty fallback so the resulting `focusText` always clears the
|
|
82
|
+
* `manifestService` 10-character minimum.
|
|
83
|
+
*/
|
|
84
|
+
export function extractDomain(data) {
|
|
85
|
+
const tags = data.domainTags;
|
|
86
|
+
if (Array.isArray(tags) && tags.length > 0 && typeof tags[0] === "string" && tags[0].length > 0) {
|
|
87
|
+
return tags[0];
|
|
88
|
+
}
|
|
89
|
+
const dom = data.domain;
|
|
90
|
+
if (typeof dom === "string" && dom.length > 0)
|
|
91
|
+
return dom;
|
|
92
|
+
const skill = data.skillDomain;
|
|
93
|
+
if (typeof skill === "string" && skill.length > 0)
|
|
94
|
+
return skill;
|
|
95
|
+
const meta = data.metadata;
|
|
96
|
+
if (meta && typeof meta === "object") {
|
|
97
|
+
const md = meta.domain;
|
|
98
|
+
if (typeof md === "string" && md.length > 0)
|
|
99
|
+
return md;
|
|
100
|
+
}
|
|
101
|
+
if (typeof data.community === "string" && data.community.length > 0)
|
|
102
|
+
return data.community;
|
|
103
|
+
return "general";
|
|
104
|
+
}
|
|
105
|
+
/* ------------------------------------------------------------------ */
|
|
106
|
+
/* Installer */
|
|
107
|
+
/* ------------------------------------------------------------------ */
|
|
108
|
+
/**
|
|
109
|
+
* Subscribe to runtime lifecycle hooks and write to the agent's manifest as
|
|
110
|
+
* tasks start, complete, or fail. Returns a disposer that removes every
|
|
111
|
+
* registered listener.
|
|
112
|
+
*/
|
|
113
|
+
export function installManifestActivationHook(runtime, opts = {}) {
|
|
114
|
+
const hooks = opts.hooks ?? runtime.hooks ?? defaultHooks;
|
|
115
|
+
const windowMs = opts.errorDebounceWindowMs ?? DEFAULT_ERROR_WINDOW_MS;
|
|
116
|
+
const threshold = opts.errorThreshold ?? DEFAULT_ERROR_THRESHOLD;
|
|
117
|
+
const maxUncertainties = opts.maxUncertainties ?? DEFAULT_MAX_UNCERTAINTIES;
|
|
118
|
+
/** Per-actionType error counter, scoped to this hook installation. */
|
|
119
|
+
const errorCounters = new Map();
|
|
120
|
+
const onSignal = (data) => {
|
|
121
|
+
const signalType = data.signalType ?? "";
|
|
122
|
+
if (!signalType || !TASK_BEARING_SIGNALS.has(signalType))
|
|
123
|
+
return;
|
|
124
|
+
const domain = extractDomain(data);
|
|
125
|
+
runtime.manifests
|
|
126
|
+
.setFocus({ taskType: signalType, domain })
|
|
127
|
+
.catch(() => { });
|
|
128
|
+
};
|
|
129
|
+
const onActionEnd = (payload) => {
|
|
130
|
+
if (!TERMINAL_ACTIONS.has(payload.actionType))
|
|
131
|
+
return;
|
|
132
|
+
runtime.manifests
|
|
133
|
+
.updateManifest({ currentFocus: null })
|
|
134
|
+
.catch(() => { });
|
|
135
|
+
};
|
|
136
|
+
const onActionError = (payload) => {
|
|
137
|
+
const now = Date.now();
|
|
138
|
+
const entry = errorCounters.get(payload.actionType);
|
|
139
|
+
if (!entry || now - entry.firstAt > windowMs) {
|
|
140
|
+
errorCounters.set(payload.actionType, { count: 1, firstAt: now });
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
entry.count += 1;
|
|
144
|
+
if (entry.count < threshold)
|
|
145
|
+
return;
|
|
146
|
+
errorCounters.delete(payload.actionType);
|
|
147
|
+
const msg = payload.error?.message ?? String(payload.error ?? "unknown");
|
|
148
|
+
void appendUncertainty(runtime, `Stuck on ${payload.actionType}: ${msg.slice(0, 200)}`, 0.7, maxUncertainties);
|
|
149
|
+
};
|
|
150
|
+
const onDoomLoop = (payload) => {
|
|
151
|
+
void appendUncertainty(runtime, `Doom loop on ${payload.offender}`, 0.9, maxUncertainties);
|
|
152
|
+
};
|
|
153
|
+
const disposers = [
|
|
154
|
+
hooks.register("signal_received", onSignal),
|
|
155
|
+
hooks.register("action_end", onActionEnd),
|
|
156
|
+
hooks.register("action_error", onActionError),
|
|
157
|
+
hooks.register("doom_loop_detected", onDoomLoop),
|
|
158
|
+
];
|
|
159
|
+
return () => {
|
|
160
|
+
for (const d of disposers)
|
|
161
|
+
d();
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/* ------------------------------------------------------------------ */
|
|
165
|
+
/* Internals */
|
|
166
|
+
/* ------------------------------------------------------------------ */
|
|
167
|
+
async function appendUncertainty(runtime, description, valueOfResolution, cap) {
|
|
168
|
+
try {
|
|
169
|
+
const current = await runtime.manifests.getMyManifest();
|
|
170
|
+
const existing = current?.uncertainties ?? [];
|
|
171
|
+
// FIFO cap: drop oldest so the newest concern always lands.
|
|
172
|
+
const trimmed = existing.length >= cap ? existing.slice(-(cap - 1)) : existing;
|
|
173
|
+
const next = [...trimmed, { description, valueOfResolution }];
|
|
174
|
+
await runtime.manifests.updateManifest({ uncertainties: next });
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
/* fire-and-forget — manifest writes never affect the agent loop */
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=manifestActivationHook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestActivationHook.js","sourceRoot":"","sources":["../src/manifestActivationHook.ts"],"names":[],"mappings":"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"}
|
package/dist/mining.d.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified mining loop for the Nookplot Agent Runtime SDK.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces a single `np.mining.start()` API that handles the full
|
|
5
|
+
* "discover → rank → solve → submit" cycle across all enabled tracks
|
|
6
|
+
* (knowledge, embedding, RLM). Per-track solver dispatch is private
|
|
7
|
+
* here — solver implementations call out to the gateway via
|
|
8
|
+
* `connection.request()` and the user's existing inference setup
|
|
9
|
+
* (BYOK / local Ollama / gateway-credit-based inference).
|
|
10
|
+
*
|
|
11
|
+
* Usage from the CLI's `nookplot mine` command:
|
|
12
|
+
* const session = await runtime.mining.start({
|
|
13
|
+
* tracks: ["knowledge", "embedding", "rlm"],
|
|
14
|
+
* maxCredits: 5000,
|
|
15
|
+
* once: false,
|
|
16
|
+
* });
|
|
17
|
+
* await session.until(() => process.signals.interrupted);
|
|
18
|
+
* await session.stop();
|
|
19
|
+
*
|
|
20
|
+
* Same surface from the `mining_opportunity` autonomous handler:
|
|
21
|
+
* await runtime.mining.runOnce({ tracks: ["knowledge"] });
|
|
22
|
+
*
|
|
23
|
+
* @module mining
|
|
24
|
+
*/
|
|
25
|
+
import type { ConnectionManager } from "./connection.js";
|
|
26
|
+
import type { EconomyManager } from "./economy.js";
|
|
27
|
+
export type MiningTrack = "knowledge" | "embedding" | "rlm" | "gradient";
|
|
28
|
+
/**
|
|
29
|
+
* Options shared by every mining entry point — the per-tick concerns that
|
|
30
|
+
* apply to both single-shot (`runOnce`) and long-running (`start`) modes.
|
|
31
|
+
*/
|
|
32
|
+
export interface MiningTickOptions {
|
|
33
|
+
/** Tracks to mine. `'auto'` queries the gateway for tracks with open challenges. */
|
|
34
|
+
tracks?: MiningTrack[] | "auto";
|
|
35
|
+
/** Optional guild to attribute submissions to (for guild-tier reward boost). */
|
|
36
|
+
guildId?: string;
|
|
37
|
+
/** Log decisions but don't submit. Default false. */
|
|
38
|
+
dryRun?: boolean;
|
|
39
|
+
/** Print scoring math for each ranked challenge. Default false. */
|
|
40
|
+
explain?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* User-supplied embedding generator. Required for the embedding track —
|
|
43
|
+
* the runtime intentionally does not bundle an Ollama client because that
|
|
44
|
+
* is a CLI concern. If absent, the embedding track is skipped with a clear
|
|
45
|
+
* "no embedding generator provided" status.
|
|
46
|
+
*/
|
|
47
|
+
generateEmbeddings?: (prompts: string[], dimensions: number) => Promise<number[][]>;
|
|
48
|
+
/**
|
|
49
|
+
* Override the default knowledge solver. Receives the challenge object,
|
|
50
|
+
* returns the trace text. Defaults to a single inference call seeded with
|
|
51
|
+
* the challenge title + description.
|
|
52
|
+
*/
|
|
53
|
+
solveKnowledge?: (challenge: ChallengeSummary, economy: EconomyManager) => Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Override the default RLM solver. Default is a no-op stub that records
|
|
56
|
+
* "deferred" — full RLM autosolve is gated on a future phase. Custom
|
|
57
|
+
* solvers can drive the REPL via `runtime.connection.request()`.
|
|
58
|
+
*/
|
|
59
|
+
solveRlm?: (challenge: ChallengeSummary, economy: EconomyManager) => Promise<TrackResult>;
|
|
60
|
+
/** Optional verbose logger. Defaults to no-op. */
|
|
61
|
+
log?: (msg: string) => void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Options for the long-running loop mode (`start`). Adds budget caps and
|
|
65
|
+
* tick scheduling that don't apply to single-shot dispatch.
|
|
66
|
+
*/
|
|
67
|
+
export interface MiningStartOptions extends MiningTickOptions {
|
|
68
|
+
/** Total credit budget for this session across all RLM sub-calls. Defaults to 5000. */
|
|
69
|
+
maxCredits?: number;
|
|
70
|
+
/** Solve all currently-open challenges, then exit. Default false. */
|
|
71
|
+
once?: boolean;
|
|
72
|
+
/** Tick interval in milliseconds. Default 60_000. */
|
|
73
|
+
tickIntervalMs?: number;
|
|
74
|
+
}
|
|
75
|
+
export interface ChallengeSummary {
|
|
76
|
+
id: string;
|
|
77
|
+
track: MiningTrack;
|
|
78
|
+
title: string;
|
|
79
|
+
description?: string;
|
|
80
|
+
difficulty: "easy" | "medium" | "hard" | "expert";
|
|
81
|
+
estimatedRewardNook: number;
|
|
82
|
+
domainTags: string[];
|
|
83
|
+
sourceType: string;
|
|
84
|
+
closesAt: string;
|
|
85
|
+
/** Filled after rank() with the challenge's composite score. */
|
|
86
|
+
rankScore?: number;
|
|
87
|
+
}
|
|
88
|
+
export interface TrackResult {
|
|
89
|
+
track: MiningTrack;
|
|
90
|
+
challengeId: string;
|
|
91
|
+
status: "submitted" | "skipped" | "error";
|
|
92
|
+
reason?: string;
|
|
93
|
+
submissionId?: string;
|
|
94
|
+
estimatedRewardNook?: number;
|
|
95
|
+
}
|
|
96
|
+
export interface MiningStats {
|
|
97
|
+
ticks: number;
|
|
98
|
+
attempted: number;
|
|
99
|
+
submitted: number;
|
|
100
|
+
/** Solver chose not to submit (no prompts, trace too short, no callback, etc.). */
|
|
101
|
+
skipped: number;
|
|
102
|
+
/** Suppressed submissions because of `dryRun: true`. Counted separately so
|
|
103
|
+
* the end-of-session banner can distinguish a dry-run from real skips. */
|
|
104
|
+
dryRun: number;
|
|
105
|
+
errors: number;
|
|
106
|
+
creditsSpent: number;
|
|
107
|
+
byTrack: Record<MiningTrack, {
|
|
108
|
+
attempted: number;
|
|
109
|
+
submitted: number;
|
|
110
|
+
errors: number;
|
|
111
|
+
}>;
|
|
112
|
+
}
|
|
113
|
+
export interface MiningSession {
|
|
114
|
+
/** Resolves when the session has stopped (either via `stop()` or `once: true` completion). */
|
|
115
|
+
done: Promise<void>;
|
|
116
|
+
/** Request graceful shutdown. Idempotent. */
|
|
117
|
+
stop(): Promise<void>;
|
|
118
|
+
/** Snapshot of running stats. */
|
|
119
|
+
stats(): MiningStats;
|
|
120
|
+
}
|
|
121
|
+
export declare function trackOf(sourceType: string): MiningTrack;
|
|
122
|
+
export declare class MiningManager {
|
|
123
|
+
private readonly connection;
|
|
124
|
+
private readonly economy;
|
|
125
|
+
private activeSession;
|
|
126
|
+
constructor(connection: ConnectionManager, economy: EconomyManager);
|
|
127
|
+
/**
|
|
128
|
+
* Start a long-running mining session. Returns immediately; the loop runs
|
|
129
|
+
* in the background until `session.stop()` or `once: true` completion.
|
|
130
|
+
*/
|
|
131
|
+
start(opts?: MiningStartOptions): Promise<MiningSession>;
|
|
132
|
+
/**
|
|
133
|
+
* Run one tick (discover → rank → solve top → submit) and return the
|
|
134
|
+
* results. Suitable for `mining_opportunity` autonomous-handler dispatch.
|
|
135
|
+
* Loop-only options (`maxCredits`, `tickIntervalMs`, `once`) are not
|
|
136
|
+
* accepted here — they're meaningless for a single-shot call.
|
|
137
|
+
*/
|
|
138
|
+
runOnce(opts?: MiningTickOptions): Promise<TrackResult[]>;
|
|
139
|
+
/** Snapshot stats from the active session, if any. */
|
|
140
|
+
stats(): MiningStats | null;
|
|
141
|
+
private makeSession;
|
|
142
|
+
private tick;
|
|
143
|
+
private resolveTracks;
|
|
144
|
+
private discoverAcross;
|
|
145
|
+
private discoverKnowledge;
|
|
146
|
+
private discoverEmbedding;
|
|
147
|
+
private discoverRlm;
|
|
148
|
+
private toSummary;
|
|
149
|
+
private solveOne;
|
|
150
|
+
private solveKnowledgeChallenge;
|
|
151
|
+
private defaultKnowledgeSolver;
|
|
152
|
+
private solveEmbeddingChallenge;
|
|
153
|
+
private solveRlmChallenge;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=mining.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mining.d.ts","sourceRoot":"","sources":["../src/mining.ts"],"names":[],"mappings":"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"}
|