@nookplot/runtime 0.5.139 → 0.5.140

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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Branch coverage for EconomyManager.inference() — the single runtime
3
+ * inference chokepoint (Pass 3 finding).
4
+ *
5
+ * Enforced contract:
6
+ * 1. inferenceSource "surplus" + a local key → pays Surplus via x402 and the
7
+ * gateway `/v1/inference/chat` is NEVER called. (Runs the real x402 client
8
+ * against a stubbed global fetch that returns 200 — no 402 → passthrough —
9
+ * so it also smoke-tests that the optional peers resolve + the client
10
+ * constructs.)
11
+ * 2. inferenceSource "surplus" + NO key → throws a keyless SurplusError and
12
+ * makes NO network call at all (default-restrictive; never a silent
13
+ * fallback to a paid platform call).
14
+ * 3. inferenceSource "platform" (default) → the gateway path is unchanged.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=economy.surplusBranch.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"economy.surplusBranch.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/economy.surplusBranch.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Branch coverage for EconomyManager.inference() — the single runtime
3
+ * inference chokepoint (Pass 3 finding).
4
+ *
5
+ * Enforced contract:
6
+ * 1. inferenceSource "surplus" + a local key → pays Surplus via x402 and the
7
+ * gateway `/v1/inference/chat` is NEVER called. (Runs the real x402 client
8
+ * against a stubbed global fetch that returns 200 — no 402 → passthrough —
9
+ * so it also smoke-tests that the optional peers resolve + the client
10
+ * constructs.)
11
+ * 2. inferenceSource "surplus" + NO key → throws a keyless SurplusError and
12
+ * makes NO network call at all (default-restrictive; never a silent
13
+ * fallback to a paid platform call).
14
+ * 3. inferenceSource "platform" (default) → the gateway path is unchanged.
15
+ */
16
+ import { describe, it, expect, vi, beforeEach } from "vitest";
17
+ import { ConnectionManager } from "../connection.js";
18
+ import { EconomyManager } from "../economy.js";
19
+ import { SURPLUS_URL } from "../inference/surplusInference.js";
20
+ const TEST_PK = "0x" + "ab".repeat(32);
21
+ const TEST_BASE = "https://gateway.example.com";
22
+ const MSGS = [{ role: "user", content: "hi" }];
23
+ function urlOf(args) {
24
+ const a = args[0];
25
+ if (typeof a === "string")
26
+ return a;
27
+ if (a instanceof URL)
28
+ return a.toString();
29
+ if (a && typeof a === "object" && "url" in a)
30
+ return String(a.url);
31
+ return String(a);
32
+ }
33
+ const SURPLUS_OK = () => new Response(JSON.stringify({
34
+ choices: [{ message: { content: "surplus says hi" } }],
35
+ model: "llama-3.3-70b",
36
+ usage: { prompt_tokens: 3, completion_tokens: 2, total_tokens: 5 },
37
+ }), { status: 200, headers: { "Content-Type": "application/json" } });
38
+ const GATEWAY_OK = () => new Response(JSON.stringify({
39
+ content: "gateway says hi",
40
+ model: "claude",
41
+ provider: "anthropic",
42
+ usage: { promptTokens: 1, completionTokens: 1, totalTokens: 2, creditsCost: 5 },
43
+ }), { status: 200, headers: { "Content-Type": "application/json" } });
44
+ beforeEach(() => {
45
+ vi.restoreAllMocks();
46
+ });
47
+ describe("EconomyManager.inference() — source routing", () => {
48
+ it("source=surplus with a key pays Surplus and NEVER calls the gateway", async () => {
49
+ const calls = [];
50
+ const fetchSpy = vi.fn(async (...args) => {
51
+ calls.push(urlOf(args));
52
+ return SURPLUS_OK();
53
+ });
54
+ vi.stubGlobal("fetch", fetchSpy);
55
+ const economy = new EconomyManager(new ConnectionManager({
56
+ gatewayUrl: TEST_BASE,
57
+ apiKey: "nk_test",
58
+ privateKey: TEST_PK,
59
+ inferenceSource: "surplus",
60
+ surplus: { model: "llama-3.3-70b" },
61
+ }));
62
+ const result = await economy.inference(MSGS);
63
+ expect(result.provider).toBe("surplus");
64
+ expect(result.content).toBe("surplus says hi");
65
+ expect(result.usage.creditsCost).toBe(0);
66
+ // The whole point of the passthrough design: the gateway is bypassed.
67
+ expect(calls.some((u) => u.includes("/v1/inference/chat"))).toBe(false);
68
+ expect(calls.some((u) => u.startsWith(SURPLUS_URL))).toBe(true);
69
+ });
70
+ it("source=surplus WITHOUT a key throws keyless and makes no network call", async () => {
71
+ const fetchSpy = vi.fn(async () => SURPLUS_OK());
72
+ vi.stubGlobal("fetch", fetchSpy);
73
+ const economy = new EconomyManager(new ConnectionManager({
74
+ gatewayUrl: TEST_BASE,
75
+ apiKey: "nk_test",
76
+ inferenceSource: "surplus", // no privateKey
77
+ }));
78
+ await expect(economy.inference(MSGS)).rejects.toMatchObject({ code: "keyless" });
79
+ expect(fetchSpy).not.toHaveBeenCalled();
80
+ });
81
+ it("source=platform (default) routes to the gateway /v1/inference/chat unchanged", async () => {
82
+ const calls = [];
83
+ const fetchSpy = vi.fn(async (...args) => {
84
+ calls.push(urlOf(args));
85
+ return GATEWAY_OK();
86
+ });
87
+ vi.stubGlobal("fetch", fetchSpy);
88
+ const economy = new EconomyManager(new ConnectionManager({ gatewayUrl: TEST_BASE, apiKey: "nk_test", privateKey: TEST_PK }));
89
+ const result = await economy.inference(MSGS, { model: "claude" });
90
+ expect(result.provider).toBe("anthropic");
91
+ expect(calls.some((u) => u === `${TEST_BASE}/v1/inference/chat`)).toBe(true);
92
+ expect(calls.some((u) => u.includes("surplusintelligence"))).toBe(false);
93
+ });
94
+ });
95
+ //# sourceMappingURL=economy.surplusBranch.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"economy.surplusBranch.test.js","sourceRoot":"","sources":["../../src/__tests__/economy.surplusBranch.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Unit coverage for the Surplus Intelligence x402 inference provider.
3
+ *
4
+ * These tests exercise the module's OWN logic — the spend-control selector
5
+ * (cap / asset / payTo), OpenAI body mapping, response + settlement parsing,
6
+ * the mandatory keyless gate, and error handling — with an injected
7
+ * `paymentFetch` (no real x402 handshake, no funds). The real on-chain
8
+ * settlement is the paid round-trip exit gate (see the roadmap), not a unit.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=surplusInference.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surplusInference.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/surplusInference.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,346 @@
1
+ /**
2
+ * Unit coverage for the Surplus Intelligence x402 inference provider.
3
+ *
4
+ * These tests exercise the module's OWN logic — the spend-control selector
5
+ * (cap / asset / payTo), OpenAI body mapping, response + settlement parsing,
6
+ * the mandatory keyless gate, and error handling — with an injected
7
+ * `paymentFetch` (no real x402 handshake, no funds). The real on-chain
8
+ * settlement is the paid round-trip exit gate (see the roadmap), not a unit.
9
+ */
10
+ import { describe, it, expect, vi } from "vitest";
11
+ import { mkdtempSync, readFileSync, writeFileSync, rmSync } from "node:fs";
12
+ import { tmpdir } from "node:os";
13
+ import { join } from "node:path";
14
+ import { surplusInference, makeSurplusSelector, buildSurplusBody, parseSurplusResponse, usdcToBaseUnits, resolveSurplusPayTo, createSurplusSpendTracker, SurplusError, SURPLUS_URL, SURPLUS_PAYTO, BASE_USDC, DEFAULT_MAX_USDC_PER_SESSION, } from "../inference/surplusInference.js";
15
+ const DAY_MS = 24 * 60 * 60 * 1000;
16
+ const TEST_PK = "0x" + "ab".repeat(32);
17
+ function req(over = {}) {
18
+ return {
19
+ scheme: "exact",
20
+ network: "eip155:8453",
21
+ asset: BASE_USDC,
22
+ payTo: "0x8581784D3E598cCa3482375CFF2409Ac9DD8c402",
23
+ amount: "3306",
24
+ ...over,
25
+ };
26
+ }
27
+ /** A Response with an OpenAI-compatible chat-completions body. */
28
+ function openAIResponse(body, init) {
29
+ const headers = { "Content-Type": "application/json" };
30
+ if (init?.settleHeader)
31
+ headers["X-PAYMENT-RESPONSE"] = init.settleHeader;
32
+ return new Response(JSON.stringify(body), { status: init?.status ?? 200, headers });
33
+ }
34
+ const OK_BODY = {
35
+ choices: [{ message: { role: "assistant", content: "hello from surplus" } }],
36
+ model: "llama-3.3-70b",
37
+ usage: { prompt_tokens: 12, completion_tokens: 7, total_tokens: 19 },
38
+ };
39
+ // ─────────────────────────────────────────────────────────────────────────
40
+ describe("usdcToBaseUnits", () => {
41
+ it("converts human USDC to 6-decimal atomic units", () => {
42
+ expect(usdcToBaseUnits(1)).toBe(1000000n);
43
+ expect(usdcToBaseUnits(0.003306)).toBe(3306n);
44
+ expect(usdcToBaseUnits(0.1)).toBe(100000n);
45
+ });
46
+ it("rejects negative / non-finite caps", () => {
47
+ expect(() => usdcToBaseUnits(-1)).toThrow(SurplusError);
48
+ expect(() => usdcToBaseUnits(Number.NaN)).toThrow(SurplusError);
49
+ });
50
+ });
51
+ // ─────────────────────────────────────────────────────────────────────────
52
+ describe("makeSurplusSelector — spend controls", () => {
53
+ const cap = usdcToBaseUnits(1); // $1.00 = 1_000_000 base units
54
+ it("returns a valid in-cap exact/USDC quote", () => {
55
+ const sel = makeSurplusSelector({ maxBaseUnits: cap });
56
+ expect(sel(2, [req()])).toMatchObject({ amount: "3306" });
57
+ });
58
+ it("picks the cheapest of multiple eligible quotes", () => {
59
+ const sel = makeSurplusSelector({ maxBaseUnits: cap });
60
+ const chosen = sel(2, [req({ amount: "9000" }), req({ amount: "3306" }), req({ amount: "5000" })]);
61
+ expect(chosen.amount).toBe("3306");
62
+ });
63
+ it("rejects a quote that exceeds the per-call cap", () => {
64
+ const sel = makeSurplusSelector({ maxBaseUnits: cap });
65
+ expect(() => sel(2, [req({ amount: "2000000" })])).toThrow(/exceeds the per-call cap/);
66
+ try {
67
+ sel(2, [req({ amount: "2000000" })]);
68
+ }
69
+ catch (e) {
70
+ expect(e.code).toBe("over_cap");
71
+ }
72
+ });
73
+ it("rejects when no exact/Base/USDC quote is on offer (wrong asset)", () => {
74
+ const sel = makeSurplusSelector({ maxBaseUnits: cap });
75
+ expect(() => sel(2, [req({ asset: "0xdeadbeef00000000000000000000000000000000" })])).toThrow(/no `exact` USDC payment option/);
76
+ });
77
+ it("rejects a non-exact scheme (e.g. upto) and a non-Base network", () => {
78
+ const sel = makeSurplusSelector({ maxBaseUnits: cap });
79
+ expect(() => sel(2, [req({ scheme: "upto" })])).toThrow(SurplusError);
80
+ expect(() => sel(2, [req({ network: "eip155:1" })])).toThrow(SurplusError);
81
+ });
82
+ it("asserts payTo only when configured", () => {
83
+ const pinned = makeSurplusSelector({ maxBaseUnits: cap, payTo: "0x1111111111111111111111111111111111111111" });
84
+ expect(() => pinned(2, [req()])).toThrow(/payTo .* does not match/);
85
+ const matching = makeSurplusSelector({ maxBaseUnits: cap, payTo: req().payTo });
86
+ expect(matching(2, [req()])).toMatchObject({ amount: "3306" });
87
+ // Unset payTo → recipient is not asserted.
88
+ const open = makeSurplusSelector({ maxBaseUnits: cap });
89
+ expect(open(2, [req({ payTo: "0x2222222222222222222222222222222222222222" })])).toBeTruthy();
90
+ });
91
+ it("reads the v1 `maxAmountRequired` field when `amount` is absent", () => {
92
+ const sel = makeSurplusSelector({ maxBaseUnits: cap });
93
+ const chosen = sel(2, [{ scheme: "exact", network: "eip155:8453", asset: BASE_USDC, payTo: req().payTo, maxAmountRequired: "4000" }]);
94
+ expect(chosen.maxAmountRequired).toBe("4000");
95
+ });
96
+ });
97
+ // ─────────────────────────────────────────────────────────────────────────
98
+ describe("makeSurplusSelector — per-session cap", () => {
99
+ const cap = usdcToBaseUnits(1);
100
+ it("accumulates authorized spend across calls and rejects once the session cap is exceeded", () => {
101
+ const tracker = createSurplusSpendTracker();
102
+ const sessionCap = usdcToBaseUnits(0.01); // 10_000 base units; quotes are 3306 each
103
+ const sel = makeSurplusSelector({ maxBaseUnits: cap, tracker, maxSessionBaseUnits: sessionCap });
104
+ sel(2, [req()]); // 3306
105
+ sel(2, [req()]); // 6612
106
+ sel(2, [req()]); // 9918 ≤ 10000 → ok
107
+ expect(tracker.spentBaseUnits).toBe(9918n);
108
+ // 4th would be 13224 > 10000 → reject with the typed code, and NOT counted.
109
+ expect(() => sel(2, [req()])).toThrow(/per-session cap/);
110
+ try {
111
+ sel(2, [req()]);
112
+ }
113
+ catch (e) {
114
+ expect(e.code).toBe("over_session_cap");
115
+ }
116
+ expect(tracker.spentBaseUnits).toBe(9918n);
117
+ });
118
+ it("does not track when no tracker / session cap is configured", () => {
119
+ const tracker = createSurplusSpendTracker();
120
+ const sel = makeSurplusSelector({ maxBaseUnits: cap, tracker }); // no maxSessionBaseUnits
121
+ sel(2, [req()]);
122
+ expect(tracker.spentBaseUnits).toBe(0n);
123
+ });
124
+ });
125
+ // ─────────────────────────────────────────────────────────────────────────
126
+ describe("DEFAULT_MAX_USDC_PER_SESSION — default-on backstop", () => {
127
+ it("is a $10 backstop the selector enforces at the boundary", () => {
128
+ expect(DEFAULT_MAX_USDC_PER_SESSION).toBe(10);
129
+ const tracker = createSurplusSpendTracker();
130
+ const sel = makeSurplusSelector({
131
+ maxBaseUnits: usdcToBaseUnits(5), // per-call high enough to let $4 quotes through
132
+ tracker,
133
+ maxSessionBaseUnits: usdcToBaseUnits(DEFAULT_MAX_USDC_PER_SESSION),
134
+ });
135
+ const four = req({ amount: usdcToBaseUnits(4).toString() });
136
+ sel(2, [four]); // $4
137
+ sel(2, [four]); // $8 ≤ $10
138
+ expect(() => sel(2, [four])).toThrow(/per-session cap/); // $12 > $10
139
+ });
140
+ });
141
+ // ─────────────────────────────────────────────────────────────────────────
142
+ describe("makeSurplusSelector — rolling 24h window", () => {
143
+ const cap = usdcToBaseUnits(1);
144
+ it("resets the accumulator once the window has elapsed (per-day budget, not lifetime)", () => {
145
+ const tracker = createSurplusSpendTracker();
146
+ const sessionCap = usdcToBaseUnits(0.005); // 5000 units; one 3306 quote fits, two don't
147
+ const sel = makeSurplusSelector({ maxBaseUnits: cap, tracker, maxSessionBaseUnits: sessionCap });
148
+ sel(2, [req()]); // 3306 ≤ 5000
149
+ expect(() => sel(2, [req()])).toThrow(/per-session cap/); // 6612 > 5000
150
+ // Backdate the window past 24h → the next call rolls it over and succeeds.
151
+ tracker.windowStartMs = Date.now() - (DAY_MS + 1000);
152
+ const chosen = sel(2, [req()]);
153
+ expect(chosen.amount).toBe("3306");
154
+ expect(tracker.spentBaseUnits).toBe(3306n); // reset, then this one call
155
+ });
156
+ });
157
+ // ─────────────────────────────────────────────────────────────────────────
158
+ describe("createSurplusSpendTracker — disk persistence", () => {
159
+ const cap = usdcToBaseUnits(1);
160
+ const sessionCap = usdcToBaseUnits(1);
161
+ it("persists authorized spend and resumes it across a restart (cap is not re-armed)", () => {
162
+ const dir = mkdtempSync(join(tmpdir(), "surplus-spend-"));
163
+ const path = join(dir, "spend.json");
164
+ try {
165
+ const t1 = createSurplusSpendTracker(path);
166
+ const sel1 = makeSurplusSelector({ maxBaseUnits: cap, tracker: t1, maxSessionBaseUnits: sessionCap });
167
+ sel1(2, [req()]); // 3306, persisted
168
+ expect(t1.spentBaseUnits).toBe(3306n);
169
+ expect(JSON.parse(readFileSync(path, "utf8")).spentBaseUnits).toBe("3306");
170
+ // A fresh tracker from the same path resumes the running total.
171
+ const t2 = createSurplusSpendTracker(path);
172
+ expect(t2.spentBaseUnits).toBe(3306n);
173
+ const sel2 = makeSurplusSelector({ maxBaseUnits: cap, tracker: t2, maxSessionBaseUnits: sessionCap });
174
+ sel2(2, [req()]);
175
+ expect(t2.spentBaseUnits).toBe(6612n);
176
+ }
177
+ finally {
178
+ rmSync(dir, { recursive: true, force: true });
179
+ }
180
+ });
181
+ it("rolls over a stale (>24h) persisted window on load", () => {
182
+ const dir = mkdtempSync(join(tmpdir(), "surplus-spend-"));
183
+ const path = join(dir, "spend.json");
184
+ try {
185
+ writeFileSync(path, JSON.stringify({ spentBaseUnits: "999999", windowStartMs: Date.now() - 25 * 60 * 60 * 1000 }), "utf8");
186
+ expect(createSurplusSpendTracker(path).spentBaseUnits).toBe(0n);
187
+ }
188
+ finally {
189
+ rmSync(dir, { recursive: true, force: true });
190
+ }
191
+ });
192
+ it("starts fresh (no throw) on a corrupt state file", () => {
193
+ const dir = mkdtempSync(join(tmpdir(), "surplus-spend-"));
194
+ const path = join(dir, "spend.json");
195
+ try {
196
+ writeFileSync(path, "{ not json", "utf8");
197
+ expect(createSurplusSpendTracker(path).spentBaseUnits).toBe(0n);
198
+ }
199
+ finally {
200
+ rmSync(dir, { recursive: true, force: true });
201
+ }
202
+ });
203
+ });
204
+ // ─────────────────────────────────────────────────────────────────────────
205
+ describe("resolveSurplusPayTo — default-on recipient assertion", () => {
206
+ it("defaults to the canonical Surplus payTo when unset", () => {
207
+ expect(resolveSurplusPayTo()).toBe(SURPLUS_PAYTO);
208
+ expect(resolveSurplusPayTo({})).toBe(SURPLUS_PAYTO);
209
+ expect(SURPLUS_PAYTO).toBe("0x8581784D3E598cCa3482375CFF2409Ac9DD8c402");
210
+ });
211
+ it("honors an explicit override", () => {
212
+ expect(resolveSurplusPayTo({ payTo: "0x9999999999999999999999999999999999999999" })).toBe("0x9999999999999999999999999999999999999999");
213
+ });
214
+ });
215
+ // ─────────────────────────────────────────────────────────────────────────
216
+ describe("buildSurplusBody", () => {
217
+ const msgs = [
218
+ { role: "user", content: "hi" },
219
+ { role: "assistant", content: "hello" },
220
+ ];
221
+ it("maps messages and forces non-streaming", () => {
222
+ const body = buildSurplusBody(msgs, undefined, "llama-3.3-70b");
223
+ expect(body).toMatchObject({
224
+ model: "llama-3.3-70b",
225
+ stream: false,
226
+ messages: [
227
+ { role: "user", content: "hi" },
228
+ { role: "assistant", content: "hello" },
229
+ ],
230
+ });
231
+ });
232
+ it("prepends systemPrompt as a system message", () => {
233
+ const body = buildSurplusBody(msgs, { systemPrompt: "be terse" }, "m");
234
+ expect(body.messages[0]).toEqual({ role: "system", content: "be terse" });
235
+ });
236
+ it("includes max_tokens / temperature only when set", () => {
237
+ const withOpts = buildSurplusBody(msgs, { maxTokens: 256, temperature: 0.2 }, "m");
238
+ expect(withOpts).toMatchObject({ max_tokens: 256, temperature: 0.2 });
239
+ const without = buildSurplusBody(msgs, {}, "m");
240
+ expect(without).not.toHaveProperty("max_tokens");
241
+ expect(without).not.toHaveProperty("temperature");
242
+ });
243
+ it("carries tool_call_id for tool messages", () => {
244
+ const body = buildSurplusBody([{ role: "tool", content: "result", toolCallId: "call_1" }], undefined, "m");
245
+ expect(body.messages[0]).toEqual({ role: "tool", content: "result", tool_call_id: "call_1" });
246
+ });
247
+ });
248
+ // ─────────────────────────────────────────────────────────────────────────
249
+ describe("parseSurplusResponse", () => {
250
+ it("maps a 200 OpenAI body to an InferenceResult (creditsCost = 0)", async () => {
251
+ const result = await parseSurplusResponse(openAIResponse(OK_BODY), "llama-3.3-70b");
252
+ expect(result).toEqual({
253
+ content: "hello from surplus",
254
+ model: "llama-3.3-70b",
255
+ provider: "surplus",
256
+ usage: { promptTokens: 12, completionTokens: 7, totalTokens: 19, creditsCost: 0 },
257
+ });
258
+ });
259
+ it("falls back to the requested model + zeroes missing usage", async () => {
260
+ const result = await parseSurplusResponse(openAIResponse({ choices: [{ message: { content: "x" } }] }), "claude-sonnet-4.6");
261
+ expect(result.model).toBe("claude-sonnet-4.6");
262
+ expect(result.usage).toEqual({ promptTokens: 0, completionTokens: 0, totalTokens: 0, creditsCost: 0 });
263
+ });
264
+ it("throws when content is missing", async () => {
265
+ await expect(parseSurplusResponse(openAIResponse({ choices: [] }), "m")).rejects.toMatchObject({
266
+ code: "bad_response",
267
+ });
268
+ });
269
+ it("throws on a non-OK status (and tags 402 distinctly)", async () => {
270
+ await expect(parseSurplusResponse(new Response("oops", { status: 500 }), "m")).rejects.toMatchObject({
271
+ code: "http_error",
272
+ });
273
+ await expect(parseSurplusResponse(new Response("pay", { status: 402 }), "m")).rejects.toMatchObject({
274
+ code: "payment_required",
275
+ });
276
+ });
277
+ it("throws on a non-JSON 200 body", async () => {
278
+ await expect(parseSurplusResponse(new Response("<html>", { status: 200 }), "m")).rejects.toMatchObject({ code: "bad_response" });
279
+ });
280
+ it("surfaces an explicit settlement failure from X-PAYMENT-RESPONSE", async () => {
281
+ const settle = Buffer.from(JSON.stringify({ success: false, errorReason: "insufficient_balance", transaction: "0x0", network: "eip155:8453" })).toString("base64");
282
+ await expect(parseSurplusResponse(openAIResponse(OK_BODY, { settleHeader: settle }), "m")).rejects.toMatchObject({ code: "settle_failed" });
283
+ });
284
+ it("ignores an undecodable or successful settlement header", async () => {
285
+ const ok = Buffer.from(JSON.stringify({ success: true, transaction: "0xabc", network: "eip155:8453" })).toString("base64");
286
+ await expect(parseSurplusResponse(openAIResponse(OK_BODY, { settleHeader: ok }), "m")).resolves.toBeTruthy();
287
+ await expect(parseSurplusResponse(openAIResponse(OK_BODY, { settleHeader: "!!not-base64!!" }), "m")).resolves.toBeTruthy();
288
+ });
289
+ });
290
+ // ─────────────────────────────────────────────────────────────────────────
291
+ describe("surplusInference — orchestration & gate (injected paymentFetch)", () => {
292
+ it("MANDATORY keyless gate: throws and makes NO call when privateKey is absent", async () => {
293
+ const spy = vi.fn();
294
+ for (const pk of [null, undefined, ""]) {
295
+ await expect(surplusInference({ privateKey: pk, messages: [{ role: "user", content: "hi" }], paymentFetch: spy })).rejects.toMatchObject({ code: "keyless" });
296
+ }
297
+ expect(spy).not.toHaveBeenCalled();
298
+ });
299
+ it("POSTs the OpenAI body to the Surplus endpoint and returns the parsed result", async () => {
300
+ const spy = vi.fn(async (_url, _init) => openAIResponse(OK_BODY));
301
+ const result = await surplusInference({
302
+ privateKey: TEST_PK,
303
+ messages: [{ role: "user", content: "hi" }],
304
+ options: { model: "llama-3.3-70b", maxTokens: 128 },
305
+ paymentFetch: spy,
306
+ });
307
+ expect(result.provider).toBe("surplus");
308
+ expect(spy).toHaveBeenCalledTimes(1);
309
+ const [url, init] = spy.mock.calls[0];
310
+ expect(url).toBe(SURPLUS_URL);
311
+ expect(init.method).toBe("POST");
312
+ const sent = JSON.parse(init.body);
313
+ expect(sent).toMatchObject({ model: "llama-3.3-70b", max_tokens: 128, stream: false });
314
+ });
315
+ it("honors model precedence (options.model > config.model > default) and a baseUrl override", async () => {
316
+ const spy = vi.fn(async (_url, _init) => openAIResponse(OK_BODY));
317
+ await surplusInference({
318
+ privateKey: TEST_PK,
319
+ messages: [{ role: "user", content: "hi" }],
320
+ config: { model: "claude-sonnet-4.6", baseUrl: "https://example.test/x" },
321
+ paymentFetch: spy,
322
+ });
323
+ const [url, init] = spy.mock.calls[0];
324
+ expect(url).toBe("https://example.test/x");
325
+ expect(JSON.parse(init.body).model).toBe("claude-sonnet-4.6");
326
+ });
327
+ it("wraps a Surplus 5xx as an http_error", async () => {
328
+ const spy = vi.fn(async () => new Response("down", { status: 503 }));
329
+ await expect(surplusInference({ privateKey: TEST_PK, messages: [{ role: "user", content: "hi" }], paymentFetch: spy })).rejects.toMatchObject({ code: "http_error" });
330
+ });
331
+ it("wraps a network/transport throw as a request_failed SurplusError", async () => {
332
+ const spy = vi.fn(async () => {
333
+ throw new Error("ECONNRESET");
334
+ });
335
+ await expect(surplusInference({ privateKey: TEST_PK, messages: [{ role: "user", content: "hi" }], paymentFetch: spy })).rejects.toMatchObject({ code: "request_failed" });
336
+ });
337
+ it("recovers a wrapped selector code from the error cause chain (not request_failed)", async () => {
338
+ // Mimic an x402 transport that re-raises the selector's SurplusError as its
339
+ // own error type — the typed code must survive via the cause chain.
340
+ const spy = vi.fn(async () => {
341
+ throw new Error("payment flow failed", { cause: new SurplusError("quote too dear", "over_cap") });
342
+ });
343
+ await expect(surplusInference({ privateKey: TEST_PK, messages: [{ role: "user", content: "hi" }], paymentFetch: spy })).rejects.toMatchObject({ code: "over_cap" });
344
+ });
345
+ });
346
+ //# sourceMappingURL=surplusInference.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surplusInference.test.js","sourceRoot":"","sources":["../../src/__tests__/surplusInference.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import type { ActionInfo } from "./actionCatalog.js";
2
- /** MCP-derived action catalog entries (480 tools). */
2
+ /** MCP-derived action catalog entries (482 tools). */
3
3
  export declare const GENERATED_CATALOG: Record<string, ActionInfo>;
4
4
  //# sourceMappingURL=actionCatalog.generated.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actionCatalog.generated.d.ts","sourceRoot":"","sources":["../src/actionCatalog.generated.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CA2zExD,CAAC"}
1
+ {"version":3,"file":"actionCatalog.generated.d.ts","sourceRoot":"","sources":["../src/actionCatalog.generated.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAq0ExD,CAAC"}
@@ -1,6 +1,6 @@
1
1
  // AUTO-GENERATED by mcp-server/scripts/generate-catalog.ts
2
2
  // DO NOT EDIT — run `npm run generate-catalog` in mcp-server to regenerate.
3
- /** MCP-derived action catalog entries (480 tools). */
3
+ /** MCP-derived action catalog entries (482 tools). */
4
4
  export const GENERATED_CATALOG = {
5
5
  get_credentials: {
6
6
  description: "Get your agent's API key, wallet address, and gateway URL. Use this when you need the API key to log into nookplot.com or connect from another tool.",
@@ -2364,5 +2364,15 @@ export const GENERATED_CATALOG = {
2364
2364
  params: "submissionId (string), sub_call_id (string), replay_response_text (string)",
2365
2365
  category: "coordination",
2366
2366
  },
2367
+ register_edge_hypothesis: {
2368
+ description: "Pre-register a trading edge-hypothesis (a machine-executable RULE) for certification by the edge gauntlet. Registration timestamps your claim BEFORE its forward window (the pre-registration control). The gauntlet screens the rule over market-data firings with strict controls (concurrency-collapse to independent market-days, deflation across all registered hypotheses, realistic costs, expectancy not win-rate) and publishes a VERIFIED-edge or a DIAGNOSED-null to the knowledge graph. Verified nulls are first-class — a rigorously diagnosed 'this does not work, and here is why' is valuable knowledge that saves the network the tuition.\nIdempotent on the rule (the same rule resolves to the same hypothesis). Currently supported ruleTemplate: 'bear_oversold_meanrev' (params: ma_days, rsi_max, drop_pct, drop_lb).",
2369
+ params: "ruleTemplate (string), universe (array), interval (string), horizon (number), params (object, optional), mechanism (string), target (string), data_dims (array, optional)",
2370
+ category: "research",
2371
+ },
2372
+ get_edge_hypothesis: {
2373
+ description: "Read an edge-hypothesis's lifecycle state + latest gauntlet verdict by id: status (HYPOTHESIZED/VERIFIED/LIVE/DECAYING/DEAD/BRANCHED/REOPENED), latest_verdict (REAL/NULL/INCONCLUSIVE/OPEN), and latest_diagnosis (NO_SIGNAL/COST_KILLED/WRONG_DATA/NON_STATIONARY/INSUFFICIENT_DATA/MISSING_DATA).",
2374
+ params: "id (number)",
2375
+ category: "research",
2376
+ },
2367
2377
  };
2368
2378
  //# sourceMappingURL=actionCatalog.generated.js.map