spl-pay-per-suite 1.1.3 → 1.1.4
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/README.md +3 -3
- package/package.json +6 -4
- package/src/mcp-server.mjs +5 -5
- package/src/quote.mjs +33 -88
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
| Tier | Rule |
|
|
8
8
|
|------|------|
|
|
9
9
|
| **Free** | First **1 GiB per job** — $0 (showcase) |
|
|
10
|
-
| **Usage** | Bytes over free:
|
|
11
|
-
| **Min paid** | $
|
|
10
|
+
| **Usage** | Bytes over free: **~ $0.03/GB** (2¢/GB after 50 GB over free) |
|
|
11
|
+
| **Min paid** | $2.00 once over free |
|
|
12
12
|
|
|
13
13
|
**Try Gate is retired.** Evaluate on free suite — not a $9 chip-in.
|
|
14
14
|
|
|
@@ -33,7 +33,7 @@ computeQuote({ product: "auto", op: "compress", bytes: 100e6 });
|
|
|
33
33
|
// → free: true, amount_cents: 0
|
|
34
34
|
|
|
35
35
|
computeQuote({ product: "auto", op: "compress", bytes: 9e9 });
|
|
36
|
-
// → free: false, ~$
|
|
36
|
+
// → free: false, ~$2.00 class
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
## MCP
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spl-pay-per-suite",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "SPL Pay Per Suite — freemium (free first 1 GB · then ~1.5¢/GB), Stripe + x402. Library, CLI, MCP. Try Gate retired.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.mjs",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"site": "https://www.slidphilabs.com",
|
|
85
85
|
"llms_txt": "https://www.slidphilabs.com/llms.txt",
|
|
86
86
|
"agents_json": "https://www.slidphilabs.com/agents.json",
|
|
87
|
-
"one_liner": "Free first 1 GB suite · then
|
|
87
|
+
"one_liner": "Free first 1 GB suite · then from $2 min · ~3¢/GB. GET https://www.slidphilabs.com/api/agent. Try Gate retired.",
|
|
88
88
|
"agent_platform": {
|
|
89
89
|
"cuni": "https://cuni-studio.fly.dev/",
|
|
90
90
|
"agent_rider": "https://agentrider.vercel.app/",
|
|
@@ -93,9 +93,11 @@
|
|
|
93
93
|
"suite": "https://www.slidphilabs.com/pps",
|
|
94
94
|
"suite_pricing": {
|
|
95
95
|
"free_cap_gb": 1,
|
|
96
|
-
"
|
|
96
|
+
"min_paid_usd": 2,
|
|
97
|
+
"usd_per_gb_after_free": 0.03,
|
|
98
|
+
"usd_per_gb_bulk": 0.02,
|
|
97
99
|
"try_gate": "retired",
|
|
98
|
-
"model": "
|
|
100
|
+
"model": "freemium_suite_v3_money"
|
|
99
101
|
},
|
|
100
102
|
"welcome": "https://www.slidphilabs.com/api/welcome",
|
|
101
103
|
"platform_json": "https://www.slidphilabs.com/platform.json"
|
package/src/mcp-server.mjs
CHANGED
|
@@ -44,7 +44,7 @@ const TOOLS = [
|
|
|
44
44
|
{
|
|
45
45
|
name: "spl_pps_info",
|
|
46
46
|
description:
|
|
47
|
-
"SPL Pay Per Suite overview: freemium suite (free first 1 GB then ~
|
|
47
|
+
"SPL Pay Per Suite overview: freemium suite (free first 1 GB then ~3¢/GB · min $2), Stripe (humans) + x402 (agents), products, data classes, ops. Try Gate retired.",
|
|
48
48
|
inputSchema: { type: "object", properties: {} },
|
|
49
49
|
},
|
|
50
50
|
{
|
|
@@ -82,7 +82,7 @@ const TOOLS = [
|
|
|
82
82
|
{
|
|
83
83
|
name: "spl_pps_x402_requirements",
|
|
84
84
|
description:
|
|
85
|
-
"Probe POST /api/x402-suite. Free under 1 GB (no pay). Over free → 402 accepts[] for usage pricing (~
|
|
85
|
+
"Probe POST /api/x402-suite. Free under 1 GB (no pay). Over free → 402 accepts[] for usage pricing (~3¢/GB · min $2).",
|
|
86
86
|
inputSchema: {
|
|
87
87
|
type: "object",
|
|
88
88
|
properties: {
|
|
@@ -117,7 +117,7 @@ const TOOLS = [
|
|
|
117
117
|
{
|
|
118
118
|
name: "spl_pps_quote",
|
|
119
119
|
description:
|
|
120
|
-
"Instant freemium quote: free first 1 GB ($0), then ~
|
|
120
|
+
"Instant freemium quote: free first 1 GB ($0), then ~3¢/GB · min $2. Inputs: product, dataClass, op, bytes. Returns free flag + USD amount.",
|
|
121
121
|
inputSchema: {
|
|
122
122
|
type: "object",
|
|
123
123
|
properties: {
|
|
@@ -204,8 +204,8 @@ async function callTool(name, args = {}) {
|
|
|
204
204
|
model: "freemium_suite_v2",
|
|
205
205
|
free_cap_bytes: FREE_BYTES,
|
|
206
206
|
free_cap_gb: 1,
|
|
207
|
-
usd_per_gb_after_free: 0.
|
|
208
|
-
usd_per_gb_bulk: 0.
|
|
207
|
+
usd_per_gb_after_free: 0.03,
|
|
208
|
+
usd_per_gb_bulk: 0.02,
|
|
209
209
|
min_paid_cents: MIN_PAID_CENTS,
|
|
210
210
|
try_gate: "retired",
|
|
211
211
|
},
|
package/src/quote.mjs
CHANGED
|
@@ -1,69 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SPL Pay Per Suite — local quote
|
|
3
|
-
* Free first 1 GiB
|
|
4
|
-
* Try Gate retired
|
|
2
|
+
* SPL Pay Per Suite — local quote (matches site freemium money model).
|
|
3
|
+
* Free first 1 GiB · over free: min $2 · ~3¢/GB (2¢ after 50 GB over free).
|
|
4
|
+
* Try Gate retired.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export const FREE_BYTES = 1 * 1024 * 1024 * 1024;
|
|
7
|
+
export const FREE_BYTES = 1 * 1024 * 1024 * 1024;
|
|
8
8
|
export const MAX_BYTES = 100 * 1024 * 1024 * 1024;
|
|
9
9
|
export const MAX_CENTS = 1_000_000;
|
|
10
|
-
export const MIN_PAID_CENTS =
|
|
11
|
-
/** @deprecated
|
|
10
|
+
export const MIN_PAID_CENTS = 200; // $2.00
|
|
11
|
+
/** @deprecated free tier can be $0 */
|
|
12
12
|
export const MIN_CENTS = 0;
|
|
13
13
|
|
|
14
|
-
/** Product adder (cents) only when billable — not on free tier */
|
|
15
14
|
export const PRODUCT_ADD_CENTS = {
|
|
16
15
|
auto: 0,
|
|
17
16
|
zrw: 0,
|
|
18
|
-
"cddg-split":
|
|
17
|
+
"cddg-split": 100,
|
|
19
18
|
blackjack: 0,
|
|
20
19
|
"shard-zip": 0,
|
|
21
20
|
"shard-tsdb": 0,
|
|
22
21
|
"slid-phi": 0,
|
|
23
22
|
};
|
|
24
|
-
|
|
25
|
-
/** Alias for MCP/tool listings */
|
|
26
23
|
export const PRODUCT_BASE = PRODUCT_ADD_CENTS;
|
|
27
24
|
|
|
28
25
|
export const DATA_MULT = {
|
|
29
|
-
zeros: 0.9,
|
|
30
|
-
|
|
31
|
-
walk: 1.0,
|
|
32
|
-
mixed_ints: 1.05,
|
|
33
|
-
timeseries: 1.05,
|
|
34
|
-
json_series: 1.0,
|
|
35
|
-
binary: 1.1,
|
|
36
|
-
unknown: 1.0,
|
|
26
|
+
zeros: 0.9, ramp: 0.95, walk: 1.0, mixed_ints: 1.05,
|
|
27
|
+
timeseries: 1.05, json_series: 1.0, binary: 1.1, unknown: 1.0,
|
|
37
28
|
};
|
|
38
|
-
|
|
39
29
|
export const OP_MULT = {
|
|
40
|
-
compress: 1.0,
|
|
41
|
-
decompress: 0.75,
|
|
42
|
-
roundtrip: 1.15,
|
|
30
|
+
compress: 1.0, decompress: 0.75, roundtrip: 1.15,
|
|
43
31
|
};
|
|
44
32
|
|
|
45
33
|
export const STRIPE_PAYMENT_LINK =
|
|
46
34
|
process.env.SPL_PPS_PAYMENT_LINK ||
|
|
47
35
|
"https://buy.stripe.com/aFa00k4B70OYetL0O46wE0g";
|
|
48
|
-
|
|
49
36
|
export const SITE_PPS = process.env.SPL_PPS_SITE || "https://www.slidphilabs.com/pps";
|
|
50
37
|
export const API_BASE = process.env.SPL_PPS_API || "https://www.slidphilabs.com";
|
|
51
38
|
|
|
52
|
-
/**
|
|
53
|
-
* Usage fee on billable bytes after free cap (USD cents).
|
|
54
|
-
* first 50 GiB over free: $0.015/GB · after: $0.008/GB
|
|
55
|
-
*/
|
|
56
39
|
export function usageFeeCents(billableBytes) {
|
|
57
40
|
const b = Math.max(0, Number(billableBytes) || 0);
|
|
58
41
|
if (b <= 0) return 0;
|
|
59
42
|
const gb = b / (1024 * 1024 * 1024);
|
|
60
|
-
if (gb <= 50) return Math.round(gb *
|
|
61
|
-
return Math.round(50 *
|
|
43
|
+
if (gb <= 50) return Math.round(gb * 3);
|
|
44
|
+
return Math.round(50 * 3 + (gb - 50) * 2);
|
|
62
45
|
}
|
|
63
46
|
|
|
64
|
-
/**
|
|
65
|
-
* @param {{ product?: string, dataClass?: string, op?: string, bytes?: number }} opts
|
|
66
|
-
*/
|
|
67
47
|
export function computeQuote({
|
|
68
48
|
product = "auto",
|
|
69
49
|
dataClass = "unknown",
|
|
@@ -74,10 +54,15 @@ export function computeQuote({
|
|
|
74
54
|
const cls = DATA_MULT[dataClass] != null ? dataClass : "unknown";
|
|
75
55
|
const operation = OP_MULT[op] != null ? op : "compress";
|
|
76
56
|
const b = Math.max(0, Math.min(Number(bytes) || 0, MAX_BYTES));
|
|
77
|
-
|
|
78
57
|
const free_bytes = FREE_BYTES;
|
|
79
58
|
const billable = Math.max(0, b - free_bytes);
|
|
80
59
|
const free = billable <= 0;
|
|
60
|
+
const rates = {
|
|
61
|
+
free_cap_gb: 1,
|
|
62
|
+
min_paid_usd: 2.0,
|
|
63
|
+
usd_per_gb_first_50: 0.03,
|
|
64
|
+
usd_per_gb_after_50: 0.02,
|
|
65
|
+
};
|
|
81
66
|
|
|
82
67
|
if (free) {
|
|
83
68
|
return {
|
|
@@ -88,32 +73,14 @@ export function computeQuote({
|
|
|
88
73
|
amount_display: "0.00",
|
|
89
74
|
free: true,
|
|
90
75
|
tier: "free_showcase",
|
|
91
|
-
message:
|
|
92
|
-
"Free showcase — first 1 GB per job is $0. Feel the platform; pay only for usage above the cap.",
|
|
76
|
+
message: "Free showcase — first 1 GB $0. Over free: from $2 min · ~3¢/GB.",
|
|
93
77
|
breakdown: {
|
|
94
|
-
product: prod,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
usage_cents: 0,
|
|
101
|
-
size_cents: 0,
|
|
102
|
-
data_class: cls,
|
|
103
|
-
data_multiplier: DATA_MULT[cls],
|
|
104
|
-
op: operation,
|
|
105
|
-
op_multiplier: OP_MULT[operation],
|
|
106
|
-
bytes: b,
|
|
107
|
-
mb: +(b / (1024 * 1024)).toFixed(4),
|
|
108
|
-
gb: +(b / (1024 * 1024 * 1024)).toFixed(6),
|
|
109
|
-
min_cents: 0,
|
|
110
|
-
min_paid_cents: MIN_PAID_CENTS,
|
|
111
|
-
max_cents: MAX_CENTS,
|
|
112
|
-
rates: {
|
|
113
|
-
free_cap_gb: 1,
|
|
114
|
-
usd_per_gb_first_50: 0.015,
|
|
115
|
-
usd_per_gb_after_50: 0.008,
|
|
116
|
-
},
|
|
78
|
+
product: prod, product_add_cents: 0, product_base_cents: 0,
|
|
79
|
+
free_bytes, free_gb: 1, billable_bytes: 0, usage_cents: 0, size_cents: 0,
|
|
80
|
+
data_class: cls, data_multiplier: DATA_MULT[cls],
|
|
81
|
+
op: operation, op_multiplier: OP_MULT[operation],
|
|
82
|
+
bytes: b, mb: +(b/1024/1024).toFixed(4), gb: +(b/1024/1024/1024).toFixed(6),
|
|
83
|
+
min_cents: 0, min_paid_cents: MIN_PAID_CENTS, max_cents: MAX_CENTS, rates,
|
|
117
84
|
},
|
|
118
85
|
pay_url: STRIPE_PAYMENT_LINK,
|
|
119
86
|
suite_url: SITE_PPS,
|
|
@@ -124,7 +91,6 @@ export function computeQuote({
|
|
|
124
91
|
const add = PRODUCT_ADD_CENTS[prod] || 0;
|
|
125
92
|
const raw = Math.round((usage + add) * DATA_MULT[cls] * OP_MULT[operation]);
|
|
126
93
|
const cents = Math.min(MAX_CENTS, Math.max(MIN_PAID_CENTS, raw));
|
|
127
|
-
|
|
128
94
|
return {
|
|
129
95
|
ok: true,
|
|
130
96
|
service: "SPL Pay Per Suite",
|
|
@@ -133,42 +99,21 @@ export function computeQuote({
|
|
|
133
99
|
amount_display: (cents / 100).toFixed(2),
|
|
134
100
|
free: false,
|
|
135
101
|
tier: "usage",
|
|
136
|
-
message:
|
|
137
|
-
"Usage pricing — first 1 GB free, then ~1.5¢/GB (0.8¢/GB after 50 GB over free). Far under typical cloud egress.",
|
|
102
|
+
message: "Usage — free 1 GB, then from $2 min · ~3¢/GB (2¢ after 50 GB over free).",
|
|
138
103
|
breakdown: {
|
|
139
|
-
product: prod,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
usage_cents: usage,
|
|
146
|
-
size_cents: usage,
|
|
147
|
-
data_class: cls,
|
|
148
|
-
data_multiplier: DATA_MULT[cls],
|
|
149
|
-
op: operation,
|
|
150
|
-
op_multiplier: OP_MULT[operation],
|
|
151
|
-
bytes: b,
|
|
152
|
-
mb: +(b / (1024 * 1024)).toFixed(4),
|
|
153
|
-
gb: +(b / (1024 * 1024 * 1024)).toFixed(6),
|
|
154
|
-
min_cents: MIN_PAID_CENTS,
|
|
155
|
-
min_paid_cents: MIN_PAID_CENTS,
|
|
156
|
-
max_cents: MAX_CENTS,
|
|
157
|
-
rates: {
|
|
158
|
-
free_cap_gb: 1,
|
|
159
|
-
usd_per_gb_first_50: 0.015,
|
|
160
|
-
usd_per_gb_after_50: 0.008,
|
|
161
|
-
},
|
|
104
|
+
product: prod, product_add_cents: add, product_base_cents: add,
|
|
105
|
+
free_bytes, free_gb: 1, billable_bytes: billable, usage_cents: usage, size_cents: usage,
|
|
106
|
+
data_class: cls, data_multiplier: DATA_MULT[cls],
|
|
107
|
+
op: operation, op_multiplier: OP_MULT[operation],
|
|
108
|
+
bytes: b, mb: +(b/1024/1024).toFixed(4), gb: +(b/1024/1024/1024).toFixed(6),
|
|
109
|
+
min_cents: MIN_PAID_CENTS, min_paid_cents: MIN_PAID_CENTS, max_cents: MAX_CENTS, rates,
|
|
162
110
|
},
|
|
163
111
|
pay_url: STRIPE_PAYMENT_LINK,
|
|
164
112
|
suite_url: SITE_PPS,
|
|
165
113
|
};
|
|
166
114
|
}
|
|
167
115
|
|
|
168
|
-
|
|
169
|
-
* Lightweight data-class heuristic from a Buffer / Uint8Array sample.
|
|
170
|
-
* Does not run proprietary codecs.
|
|
171
|
-
*/
|
|
116
|
+
|
|
172
117
|
export function classifyBytes(buf) {
|
|
173
118
|
if (!buf || !buf.length) return { dataClass: "unknown", tool: "auto", confidence: 0 };
|
|
174
119
|
const u8 = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|