marginfuse 0.2.1 → 0.2.2
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/CHANGELOG.md +17 -0
- package/dist/index.cjs +16 -6
- package/dist/index.d.cts +23 -8
- package/dist/index.d.ts +23 -8
- package/dist/index.js +15 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
|
|
5
5
|
follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.2.2]
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- The user-agent reported `marginfuse-node/0.1.0` on every request, two
|
|
12
|
+
releases after 0.1.0. The version was a literal that nothing compared to
|
|
13
|
+
`package.json`, so support questions about which version sent a request got
|
|
14
|
+
a wrong answer. It is now derived from a single constant and a test asserts
|
|
15
|
+
the two agree.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Public documentation comments no longer cite internal specification section
|
|
20
|
+
numbers. They shipped in `dist/index.d.ts`, so hovering `decide()` in an
|
|
21
|
+
editor showed a reference to a document nobody outside can read. The
|
|
22
|
+
comments now say what the methods do.
|
|
23
|
+
|
|
7
24
|
## [0.2.1]
|
|
8
25
|
|
|
9
26
|
No code changes. This is the first release published by the release workflow
|
package/dist/index.cjs
CHANGED
|
@@ -20,11 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
CONTRACT_VERSION: () => CONTRACT_VERSION,
|
|
23
24
|
MarginFuse: () => MarginFuse,
|
|
24
25
|
fromOpenRouter: () => fromOpenRouter
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(index_exports);
|
|
27
28
|
|
|
29
|
+
// src/version.ts
|
|
30
|
+
var VERSION = "0.2.2";
|
|
31
|
+
|
|
28
32
|
// src/client.ts
|
|
29
33
|
var DEFAULT_BASE_URL = "https://api.marginfuse.com";
|
|
30
34
|
var DEFAULT_TIMEOUT_MS = 1500;
|
|
@@ -46,8 +50,9 @@ var MarginFuse = class {
|
|
|
46
50
|
this.fetchImpl = options.fetch ?? fetch;
|
|
47
51
|
}
|
|
48
52
|
/**
|
|
49
|
-
*
|
|
50
|
-
* Always resolves. On any failure resolves {action:"allow", degraded:true}
|
|
53
|
+
* Asks whether the next provider call should run.
|
|
54
|
+
* Always resolves. On any failure resolves {action:"allow", degraded:true},
|
|
55
|
+
* because MarginFuse being unreachable must never become your outage.
|
|
51
56
|
*/
|
|
52
57
|
async decide(params) {
|
|
53
58
|
const failOpen = (reason) => ({
|
|
@@ -79,8 +84,9 @@ var MarginFuse = class {
|
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
87
|
+
* Reports what a provider call actually consumed, after it happened.
|
|
88
|
+
* Returns immediately and retries in the background. Call flush() before
|
|
89
|
+
* the process exits, or the last events go with it.
|
|
84
90
|
*/
|
|
85
91
|
track(params) {
|
|
86
92
|
const event = {
|
|
@@ -113,7 +119,7 @@ var MarginFuse = class {
|
|
|
113
119
|
this.track(params);
|
|
114
120
|
await this.flush();
|
|
115
121
|
}
|
|
116
|
-
/**
|
|
122
|
+
/** Tells MarginFuse what your application did with a decision. */
|
|
117
123
|
acknowledge(decisionId, acknowledgment) {
|
|
118
124
|
this.background(async () => {
|
|
119
125
|
try {
|
|
@@ -200,7 +206,7 @@ var MarginFuse = class {
|
|
|
200
206
|
headers: {
|
|
201
207
|
authorization: `Bearer ${this.apiKey}`,
|
|
202
208
|
"content-type": "application/json",
|
|
203
|
-
"user-agent":
|
|
209
|
+
"user-agent": `marginfuse-node/${VERSION}`
|
|
204
210
|
},
|
|
205
211
|
body: JSON.stringify(body),
|
|
206
212
|
signal: AbortSignal.timeout(timeoutMs)
|
|
@@ -257,8 +263,12 @@ function fromOpenRouter(usage) {
|
|
|
257
263
|
const hasCost = typeof cost === "number" && Number.isFinite(cost) && cost >= 0;
|
|
258
264
|
return { usage: out, ...hasCost ? { costUsd: creditsToUsd(cost) } : {} };
|
|
259
265
|
}
|
|
266
|
+
|
|
267
|
+
// src/index.ts
|
|
268
|
+
var CONTRACT_VERSION = 1;
|
|
260
269
|
// Annotate the CommonJS export names for ESM import in node:
|
|
261
270
|
0 && (module.exports = {
|
|
271
|
+
CONTRACT_VERSION,
|
|
262
272
|
MarginFuse,
|
|
263
273
|
fromOpenRouter
|
|
264
274
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Wire types for the MarginFuse SDK. Deliberately: there is NO field for
|
|
3
3
|
* prompt text, responses, or documents - the SDK cannot leak what it cannot
|
|
4
|
-
* carry
|
|
4
|
+
* carry.
|
|
5
5
|
*/
|
|
6
6
|
interface Usage {
|
|
7
7
|
inputTokens?: number;
|
|
@@ -69,7 +69,7 @@ interface MarginFuseOptions {
|
|
|
69
69
|
/**
|
|
70
70
|
* MarginFuse Node SDK.
|
|
71
71
|
*
|
|
72
|
-
* Reliability contract
|
|
72
|
+
* Reliability contract: this SDK NEVER throws into
|
|
73
73
|
* application code and NEVER blocks a request on MarginFuse availability.
|
|
74
74
|
* decide() fails open to "allow" on any timeout or error; track()/report()
|
|
75
75
|
* retry in the background and surface problems only via options.onError.
|
|
@@ -84,18 +84,20 @@ declare class MarginFuse {
|
|
|
84
84
|
private readonly pending;
|
|
85
85
|
constructor(options: MarginFuseOptions);
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
* Always resolves. On any failure resolves {action:"allow", degraded:true}
|
|
87
|
+
* Asks whether the next provider call should run.
|
|
88
|
+
* Always resolves. On any failure resolves {action:"allow", degraded:true},
|
|
89
|
+
* because MarginFuse being unreachable must never become your outage.
|
|
89
90
|
*/
|
|
90
91
|
decide(params: DecideParams): Promise<Decision>;
|
|
91
92
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
93
|
+
* Reports what a provider call actually consumed, after it happened.
|
|
94
|
+
* Returns immediately and retries in the background. Call flush() before
|
|
95
|
+
* the process exits, or the last events go with it.
|
|
94
96
|
*/
|
|
95
97
|
track(params: TrackParams): void;
|
|
96
98
|
/** Awaitable variant of track for jobs/scripts that must not exit early. */
|
|
97
99
|
trackAndWait(params: TrackParams): Promise<void>;
|
|
98
|
-
/**
|
|
100
|
+
/** Tells MarginFuse what your application did with a decision. */
|
|
99
101
|
acknowledge(decisionId: string, acknowledgment: Acknowledgment): void;
|
|
100
102
|
/**
|
|
101
103
|
* Full protection loop in one wrapper: decide → run your provider call with
|
|
@@ -188,4 +190,17 @@ declare function fromOpenRouter(usage: OpenRouterUsage | null | undefined): Pick
|
|
|
188
190
|
costUsd?: string;
|
|
189
191
|
};
|
|
190
192
|
|
|
191
|
-
|
|
193
|
+
/**
|
|
194
|
+
* The version of the shared SDK contract this build was verified against.
|
|
195
|
+
*
|
|
196
|
+
* Package versions differ per language, because each tracks its own breaking
|
|
197
|
+
* changes: a rename in Python must not tell Node users something broke. What
|
|
198
|
+
* makes the SDKs interchangeable is this, not the package version. Two SDKs
|
|
199
|
+
* reporting the same contract version have passed the same scenarios and the
|
|
200
|
+
* same vectors.
|
|
201
|
+
*
|
|
202
|
+
* See github.com/marginfuse/sdk-contract.
|
|
203
|
+
*/
|
|
204
|
+
declare const CONTRACT_VERSION = 1;
|
|
205
|
+
|
|
206
|
+
export { type Acknowledgment, CONTRACT_VERSION, type DecideParams, type Decision, type DecisionAction, MarginFuse, type MarginFuseOptions, type OpenRouterUsage, type Outcome, type TrackParams, type Usage, fromOpenRouter };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Wire types for the MarginFuse SDK. Deliberately: there is NO field for
|
|
3
3
|
* prompt text, responses, or documents - the SDK cannot leak what it cannot
|
|
4
|
-
* carry
|
|
4
|
+
* carry.
|
|
5
5
|
*/
|
|
6
6
|
interface Usage {
|
|
7
7
|
inputTokens?: number;
|
|
@@ -69,7 +69,7 @@ interface MarginFuseOptions {
|
|
|
69
69
|
/**
|
|
70
70
|
* MarginFuse Node SDK.
|
|
71
71
|
*
|
|
72
|
-
* Reliability contract
|
|
72
|
+
* Reliability contract: this SDK NEVER throws into
|
|
73
73
|
* application code and NEVER blocks a request on MarginFuse availability.
|
|
74
74
|
* decide() fails open to "allow" on any timeout or error; track()/report()
|
|
75
75
|
* retry in the background and surface problems only via options.onError.
|
|
@@ -84,18 +84,20 @@ declare class MarginFuse {
|
|
|
84
84
|
private readonly pending;
|
|
85
85
|
constructor(options: MarginFuseOptions);
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
* Always resolves. On any failure resolves {action:"allow", degraded:true}
|
|
87
|
+
* Asks whether the next provider call should run.
|
|
88
|
+
* Always resolves. On any failure resolves {action:"allow", degraded:true},
|
|
89
|
+
* because MarginFuse being unreachable must never become your outage.
|
|
89
90
|
*/
|
|
90
91
|
decide(params: DecideParams): Promise<Decision>;
|
|
91
92
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
93
|
+
* Reports what a provider call actually consumed, after it happened.
|
|
94
|
+
* Returns immediately and retries in the background. Call flush() before
|
|
95
|
+
* the process exits, or the last events go with it.
|
|
94
96
|
*/
|
|
95
97
|
track(params: TrackParams): void;
|
|
96
98
|
/** Awaitable variant of track for jobs/scripts that must not exit early. */
|
|
97
99
|
trackAndWait(params: TrackParams): Promise<void>;
|
|
98
|
-
/**
|
|
100
|
+
/** Tells MarginFuse what your application did with a decision. */
|
|
99
101
|
acknowledge(decisionId: string, acknowledgment: Acknowledgment): void;
|
|
100
102
|
/**
|
|
101
103
|
* Full protection loop in one wrapper: decide → run your provider call with
|
|
@@ -188,4 +190,17 @@ declare function fromOpenRouter(usage: OpenRouterUsage | null | undefined): Pick
|
|
|
188
190
|
costUsd?: string;
|
|
189
191
|
};
|
|
190
192
|
|
|
191
|
-
|
|
193
|
+
/**
|
|
194
|
+
* The version of the shared SDK contract this build was verified against.
|
|
195
|
+
*
|
|
196
|
+
* Package versions differ per language, because each tracks its own breaking
|
|
197
|
+
* changes: a rename in Python must not tell Node users something broke. What
|
|
198
|
+
* makes the SDKs interchangeable is this, not the package version. Two SDKs
|
|
199
|
+
* reporting the same contract version have passed the same scenarios and the
|
|
200
|
+
* same vectors.
|
|
201
|
+
*
|
|
202
|
+
* See github.com/marginfuse/sdk-contract.
|
|
203
|
+
*/
|
|
204
|
+
declare const CONTRACT_VERSION = 1;
|
|
205
|
+
|
|
206
|
+
export { type Acknowledgment, CONTRACT_VERSION, type DecideParams, type Decision, type DecisionAction, MarginFuse, type MarginFuseOptions, type OpenRouterUsage, type Outcome, type TrackParams, type Usage, fromOpenRouter };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/version.ts
|
|
2
|
+
var VERSION = "0.2.2";
|
|
3
|
+
|
|
1
4
|
// src/client.ts
|
|
2
5
|
var DEFAULT_BASE_URL = "https://api.marginfuse.com";
|
|
3
6
|
var DEFAULT_TIMEOUT_MS = 1500;
|
|
@@ -19,8 +22,9 @@ var MarginFuse = class {
|
|
|
19
22
|
this.fetchImpl = options.fetch ?? fetch;
|
|
20
23
|
}
|
|
21
24
|
/**
|
|
22
|
-
*
|
|
23
|
-
* Always resolves. On any failure resolves {action:"allow", degraded:true}
|
|
25
|
+
* Asks whether the next provider call should run.
|
|
26
|
+
* Always resolves. On any failure resolves {action:"allow", degraded:true},
|
|
27
|
+
* because MarginFuse being unreachable must never become your outage.
|
|
24
28
|
*/
|
|
25
29
|
async decide(params) {
|
|
26
30
|
const failOpen = (reason) => ({
|
|
@@ -52,8 +56,9 @@ var MarginFuse = class {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
59
|
+
* Reports what a provider call actually consumed, after it happened.
|
|
60
|
+
* Returns immediately and retries in the background. Call flush() before
|
|
61
|
+
* the process exits, or the last events go with it.
|
|
57
62
|
*/
|
|
58
63
|
track(params) {
|
|
59
64
|
const event = {
|
|
@@ -86,7 +91,7 @@ var MarginFuse = class {
|
|
|
86
91
|
this.track(params);
|
|
87
92
|
await this.flush();
|
|
88
93
|
}
|
|
89
|
-
/**
|
|
94
|
+
/** Tells MarginFuse what your application did with a decision. */
|
|
90
95
|
acknowledge(decisionId, acknowledgment) {
|
|
91
96
|
this.background(async () => {
|
|
92
97
|
try {
|
|
@@ -173,7 +178,7 @@ var MarginFuse = class {
|
|
|
173
178
|
headers: {
|
|
174
179
|
authorization: `Bearer ${this.apiKey}`,
|
|
175
180
|
"content-type": "application/json",
|
|
176
|
-
"user-agent":
|
|
181
|
+
"user-agent": `marginfuse-node/${VERSION}`
|
|
177
182
|
},
|
|
178
183
|
body: JSON.stringify(body),
|
|
179
184
|
signal: AbortSignal.timeout(timeoutMs)
|
|
@@ -230,7 +235,11 @@ function fromOpenRouter(usage) {
|
|
|
230
235
|
const hasCost = typeof cost === "number" && Number.isFinite(cost) && cost >= 0;
|
|
231
236
|
return { usage: out, ...hasCost ? { costUsd: creditsToUsd(cost) } : {} };
|
|
232
237
|
}
|
|
238
|
+
|
|
239
|
+
// src/index.ts
|
|
240
|
+
var CONTRACT_VERSION = 1;
|
|
233
241
|
export {
|
|
242
|
+
CONTRACT_VERSION,
|
|
234
243
|
MarginFuse,
|
|
235
244
|
fromOpenRouter
|
|
236
245
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "marginfuse",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "MarginFuse server-side SDK. AI profitability guardrails: connect revenue to per-request AI cost and stop loss-making requests before they run. Sends usage metadata only, never prompts or responses.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pemira Labs",
|