@oxygen-agent/cli 1.739.1 → 1.766.0
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 +1 -1
- package/dist/command-manifest.js +17 -2
- package/dist/help.js +8 -0
- package/dist/index.js +562 -125
- package/node_modules/@oxygen/shared/dist/billing.d.ts +88 -46
- package/node_modules/@oxygen/shared/dist/billing.js +134 -74
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +12 -4
- package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
- package/node_modules/@oxygen/shared/dist/copilot-journeys.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/copilot-journeys.js +23 -5
- package/node_modules/@oxygen/shared/dist/future-signup-events.d.ts +13 -2
- package/node_modules/@oxygen/shared/dist/future-signup-events.js +17 -2
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.d.ts +106 -1
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.js +156 -45
- package/node_modules/@oxygen/shared/dist/index.d.ts +5 -1
- package/node_modules/@oxygen/shared/dist/index.js +5 -1
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +33 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +69 -4
- package/node_modules/@oxygen/shared/dist/person-name.d.ts +40 -0
- package/node_modules/@oxygen/shared/dist/person-name.js +23 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.d.ts +82 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.js +130 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/plan-limits.js +18 -2
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +50 -56
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +77 -90
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +62 -0
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +91 -0
- package/node_modules/@oxygen/shared/dist/provider-funding-errors.d.ts +44 -0
- package/node_modules/@oxygen/shared/dist/provider-funding-errors.js +81 -0
- package/node_modules/@oxygen/shared/dist/publishing-limits.d.ts +24 -0
- package/node_modules/@oxygen/shared/dist/publishing-limits.js +24 -0
- package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +27 -6
- package/node_modules/@oxygen/shared/dist/spend-safety.js +34 -6
- package/node_modules/@oxygen/shared/dist/version.d.ts +2 -1
- package/node_modules/@oxygen/shared/dist/version.js +14 -3
- package/node_modules/@oxygen/shared/package.json +10 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.d.ts +29 -1
- package/node_modules/@oxygen/workflows/dist/graph/expression.js +307 -42
- package/node_modules/@oxygen/workflows/dist/graph/index.d.ts +1 -0
- package/node_modules/@oxygen/workflows/dist/graph/index.js +1 -0
- package/node_modules/@oxygen/workflows/dist/graph/lint.js +153 -19
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.d.ts +92 -0
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.js +4 -0
- package/node_modules/@oxygen/workflows/dist/graph/mapping.d.ts +79 -0
- package/node_modules/@oxygen/workflows/dist/graph/mapping.js +436 -0
- package/node_modules/@oxygen/workflows/dist/graph/topology.d.ts +36 -0
- package/node_modules/@oxygen/workflows/dist/graph/topology.js +147 -0
- package/node_modules/@oxygen/workflows/dist/graph/types.d.ts +31 -0
- package/node_modules/@oxygen/workflows/dist/graph/types.js +16 -0
- package/package.json +1 -1
|
@@ -3,24 +3,52 @@
|
|
|
3
3
|
* page's "what credits buy" table, the pricing calculator, and docs.
|
|
4
4
|
*
|
|
5
5
|
* Pricing Model 2.0 (founder-ratified 2026-07-14): ONE credit pool pays for
|
|
6
|
-
* everything; 1 USD = 1,000 credits
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* everything; 1 USD = 1,000 credits.
|
|
7
|
+
*
|
|
8
|
+
* THIS FILE NO LONGER DECLARES PRICES. It used to carry hand-copied literals
|
|
9
|
+
* under a comment asking the next person to remember to update them — which is
|
|
10
|
+
* how it came to quote 25 credits for web-search grounding that actually
|
|
11
|
+
* reserved 115. Prices now arrive from exactly two places, and neither of them
|
|
12
|
+
* is a human retyping a number:
|
|
13
|
+
*
|
|
14
|
+
* ./pricing-snapshot.generated.ts platform prices, rendered from
|
|
15
|
+
* packages/control-db/src/pricing/seed.ts by
|
|
16
|
+
* `npm run pricing:snapshot` and CI-gated.
|
|
17
|
+
* To change one, edit the SEED.
|
|
18
|
+
*
|
|
19
|
+
* resolver-derived values below AI column tiers, web-search grounding and
|
|
20
|
+
* the representative enrichment prices come
|
|
21
|
+
* from provider_cost_config (seeded by
|
|
22
|
+
* cogs-rates.ts) — a different source of
|
|
23
|
+
* truth, pinned by
|
|
24
|
+
* pricing-sheet-conformance.test.ts in
|
|
25
|
+
* @oxygen/integrations, which can see both
|
|
26
|
+
* sides and fails when they diverge.
|
|
12
27
|
*
|
|
13
28
|
* Dependency-free on purpose: this module is imported by "use client"
|
|
14
29
|
* marketing components via the `@oxygen/shared/pricing-sheet` subpath, so it
|
|
15
30
|
* must never drag the shared barrel (async_hooks etc.) into a client bundle.
|
|
31
|
+
* The generated snapshot holds that property too — it is literals only.
|
|
32
|
+
*
|
|
33
|
+
* Anything that CAN await a query should read the control DB via
|
|
34
|
+
* loadPricingBook() instead of importing this file, so a staff re-price at
|
|
35
|
+
* /admin/costs takes effect without a deploy.
|
|
16
36
|
*/
|
|
37
|
+
export { creditsToUsd, usdToCredits } from "./pricing-snapshot.generated.js";
|
|
17
38
|
export declare const PRICING_SHEET_VERIFIED = "2026-07";
|
|
18
|
-
/** Mirror of CREDITS_PER_USD in ./billing.ts (kept literal: client-safe module). */
|
|
19
39
|
export declare const PRICING_CREDITS_PER_USD = 1000;
|
|
20
40
|
/** On-demand top-up price per 1,000 credits (USD); subscriptions pay $1.00. */
|
|
21
41
|
export declare const TOPUP_USD_PER_1K = 1.25;
|
|
22
42
|
export declare const SUBSCRIPTION_USD_PER_1K = 1;
|
|
23
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* AI column runs, honest 5× of modeled tier COGS.
|
|
45
|
+
*
|
|
46
|
+
* RESOLVER-DERIVED, not seed-derived: the canonical values live in
|
|
47
|
+
* packages/integrations/src/cogs-rates.ts and are served per-workspace from
|
|
48
|
+
* provider_cost_config. pricing-sheet-conformance.test.ts pins these literals
|
|
49
|
+
* against the live estimator, so a tier re-price fails a test rather than
|
|
50
|
+
* quietly mispricing the page.
|
|
51
|
+
*/
|
|
24
52
|
export declare const AI_COLUMN_CREDITS: {
|
|
25
53
|
readonly low: 15;
|
|
26
54
|
readonly medium: 75;
|
|
@@ -38,11 +66,7 @@ export declare const AI_COLUMN_CREDITS: {
|
|
|
38
66
|
* with parallel as its one fallback (WEB_SEARCH_ENGINES), so a row costs 35 when
|
|
39
67
|
* the primary answers and reserves 40 for the case where both lanes fire.
|
|
40
68
|
*
|
|
41
|
-
*
|
|
42
|
-
* marketing client bundle and cannot import @oxygen/integrations (which depends on
|
|
43
|
-
* @oxygen/shared). `pricing-sheet-conformance.test.ts` in @oxygen/integrations —
|
|
44
|
-
* which can see both — pins these numbers to the live resolver, so drift fails a
|
|
45
|
-
* test instead of quietly mispricing the page again.
|
|
69
|
+
* Resolver-derived like AI_COLUMN_CREDITS above, and pinned by the same test.
|
|
46
70
|
*/
|
|
47
71
|
export declare const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS = 35;
|
|
48
72
|
export declare const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 40;
|
|
@@ -50,12 +74,9 @@ export declare const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 40;
|
|
|
50
74
|
export declare const AUTOMATION_ACTION_CREDITS = 0.01;
|
|
51
75
|
/**
|
|
52
76
|
* Managed email inboxes: founder-ratified flat price (2026-07-25), superseding
|
|
53
|
-
* the earlier dynamic vendor-COGS × 1.25 range
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* tier. Kept as an object (min/typical/max all equal) rather than a bare number
|
|
57
|
-
* so existing callers that destructure any of the three fields need no shape
|
|
58
|
-
* change.
|
|
77
|
+
* the earlier dynamic vendor-COGS × 1.25 range. Kept as an object (min/typical/max
|
|
78
|
+
* all equal) rather than a bare number so existing callers that destructure any
|
|
79
|
+
* of the three fields need no shape change.
|
|
59
80
|
*/
|
|
60
81
|
export declare const MANAGED_INBOX_MARKUP = 1.25;
|
|
61
82
|
export declare const MANAGED_INBOX_CREDITS_PER_MONTH: {
|
|
@@ -77,15 +98,8 @@ export declare const MANAGED_INBOX_CREDITS_PER_MONTH: {
|
|
|
77
98
|
* Costing only the outbound leg undercharges every call by 29%.
|
|
78
99
|
*/
|
|
79
100
|
export declare const VOICE_MARKUP = 5;
|
|
80
|
-
/**
|
|
81
|
-
* Flat $5.00/mo per number (founder decision 2026-07-26). Twilio's US/CA local
|
|
82
|
-
* DID costs $1.15, so this is ~4.3× — priced as a round number rather than a
|
|
83
|
-
* computed markup, the way a customer actually reads a price.
|
|
84
|
-
*/
|
|
85
101
|
export declare const VOICE_NUMBER_CREDITS_PER_MONTH = 5000;
|
|
86
|
-
/** Both legs, $0.018/min × 5 → $0.09/min. */
|
|
87
102
|
export declare const VOICE_CREDITS_PER_MINUTE = 90;
|
|
88
|
-
/** Answering-machine detection is per CALL, not per minute — it bills on no-answers too. */
|
|
89
103
|
export declare const VOICE_CREDITS_PER_AMD_CALL = 38;
|
|
90
104
|
/** Managed domains: registrar at-cost × 1.25 (≈ a $10.44 .com → ~13,050 credits/yr). */
|
|
91
105
|
export declare const MANAGED_DOMAIN_MARKUP = 1.25;
|
|
@@ -97,18 +111,6 @@ export declare const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13050;
|
|
|
97
111
|
* inbox-placement (spam) tests; tests beyond the allowance bill the per-test
|
|
98
112
|
* price.
|
|
99
113
|
*
|
|
100
|
-
* All three are DISPLAY mirrors, per this file's contract. The canonical values
|
|
101
|
-
* live where they are enforced, and seed-parity.test.ts binds them so a mirror
|
|
102
|
-
* can never quietly drift from the number actually billed:
|
|
103
|
-
* seat DELIVERABILITY_UNIT_MONTHLY_CREDITS (@oxygen/control-db,
|
|
104
|
-
* also PRICING_SEED commitment.deliverability_unit) — 1,000 credits
|
|
105
|
-
* ($1.00), restored by the founder on 2026-07-30 after reviewing the
|
|
106
|
-
* Agency-plan unit economics, superseding the 2026-07-26 signature
|
|
107
|
-
* of 2,000.
|
|
108
|
-
* allowance DELIVERABILITY_INCLUDED_TESTS_PER_INBOX (@oxygen/control-db)
|
|
109
|
-
* overage EMAILGUARD_MANAGED_PLACEMENT_CREDITS (@oxygen/providers,
|
|
110
|
-
* derived from the Agency plan rather than typed in)
|
|
111
|
-
*
|
|
112
114
|
* THE ALLOWANCE IS LOAD-BEARING, not a perk. Placement COGS is per TEST
|
|
113
115
|
* ($0.1327 on EmailGuard's Agency plan), not per inbox, so an unbounded seat
|
|
114
116
|
* inverts its own margin: at $1.00/inbox-month the EIGHTH test in a cycle is
|
|
@@ -118,14 +120,12 @@ export declare const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13050;
|
|
|
118
120
|
*/
|
|
119
121
|
export declare const DELIVERABILITY_SEAT_CREDITS_PER_MONTH = 1000;
|
|
120
122
|
export declare const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX = 2;
|
|
121
|
-
/** Overage placement test: $0.1327 EmailGuard COGS × 1.25, rounded up. */
|
|
122
123
|
export declare const PLACEMENT_TEST_OVERAGE_CREDITS = 166;
|
|
123
124
|
/**
|
|
124
125
|
* LinkedIn accounts: founder decision (2026-07-25) — a PURE seat model. The
|
|
125
|
-
* flat monthly connection fee per connected account is
|
|
126
|
-
* price
|
|
127
|
-
*
|
|
128
|
-
* WhatsApp stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
|
|
126
|
+
* flat monthly connection fee per connected account is the WHOLE LinkedIn
|
|
127
|
+
* price; every per-action charge is 0. Per-MESSAGE sends on email and WhatsApp
|
|
128
|
+
* stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
|
|
129
129
|
* connection fee, see WHATSAPP_ACCOUNT_CREDITS_PER_MONTH.
|
|
130
130
|
*/
|
|
131
131
|
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 10000;
|
|
@@ -138,23 +138,16 @@ export declare const LINKEDIN_ACTION_CREDITS: {
|
|
|
138
138
|
readonly like_post: 0;
|
|
139
139
|
readonly comment_post: 0;
|
|
140
140
|
};
|
|
141
|
-
/**
|
|
142
|
-
* Editable calculator default: a warmed account's typical monthly action mix.
|
|
143
|
-
* 0 under the pure seat model (2026-07-25) — actions no longer add to the
|
|
144
|
-
* LinkedIn line regardless of volume, so this default carries no credits.
|
|
145
|
-
* Kept (not deleted) because PRICING_CALCULATOR_DEFAULTS.linkedinActionCreditsPerAccount
|
|
146
|
-
* still reads it as its default value.
|
|
147
|
-
*/
|
|
148
141
|
export declare const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
|
|
149
142
|
/**
|
|
150
143
|
* WhatsApp numbers: flat monthly connection fee per connected number, the same
|
|
151
|
-
* seat shape as LinkedIn
|
|
152
|
-
*
|
|
153
|
-
*
|
|
144
|
+
* seat shape as LinkedIn. Billed off the rolling-30d peak, so a number connected
|
|
145
|
+
* part-way through a month still bills the full cycle. WhatsApp message sends
|
|
146
|
+
* themselves remain 0 credits.
|
|
154
147
|
*/
|
|
155
148
|
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 10000;
|
|
156
149
|
/** Dedicated egress IP add-on. */
|
|
157
|
-
export declare const EGRESS_IP_CREDITS_PER_MONTH =
|
|
150
|
+
export declare const EGRESS_IP_CREDITS_PER_MONTH = 25000;
|
|
158
151
|
/**
|
|
159
152
|
* Email + WhatsApp sends cost nothing per message — the pool pays for inboxes and
|
|
160
153
|
* connected accounts, not for sends.
|
|
@@ -164,6 +157,9 @@ export declare const SEND_CREDITS = 0;
|
|
|
164
157
|
* Representative enrichment prices (5× provider COGS via the resolver; the
|
|
165
158
|
* live per-operation table is served by /api/pricing/customer-credit-prices).
|
|
166
159
|
* "typical" = the cheap-first waterfall's common case, used by the calculator.
|
|
160
|
+
*
|
|
161
|
+
* Resolver-derived, like AI_COLUMN_CREDITS: these mirror cogs-rates.ts, not the
|
|
162
|
+
* pricing seed.
|
|
167
163
|
*/
|
|
168
164
|
export declare const ENRICHMENT_CREDITS: {
|
|
169
165
|
readonly email_verify: 2.245;
|
|
@@ -176,5 +172,3 @@ export declare const ENRICHMENT_CREDITS: {
|
|
|
176
172
|
};
|
|
177
173
|
/** Editable calculator default: blended credits per fully-enriched row. */
|
|
178
174
|
export declare const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = 100;
|
|
179
|
-
export declare function creditsToUsd(credits: number): number;
|
|
180
|
-
export declare function usdToCredits(usd: number): number;
|
|
@@ -3,24 +3,53 @@
|
|
|
3
3
|
* page's "what credits buy" table, the pricing calculator, and docs.
|
|
4
4
|
*
|
|
5
5
|
* Pricing Model 2.0 (founder-ratified 2026-07-14): ONE credit pool pays for
|
|
6
|
-
* everything; 1 USD = 1,000 credits
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* everything; 1 USD = 1,000 credits.
|
|
7
|
+
*
|
|
8
|
+
* THIS FILE NO LONGER DECLARES PRICES. It used to carry hand-copied literals
|
|
9
|
+
* under a comment asking the next person to remember to update them — which is
|
|
10
|
+
* how it came to quote 25 credits for web-search grounding that actually
|
|
11
|
+
* reserved 115. Prices now arrive from exactly two places, and neither of them
|
|
12
|
+
* is a human retyping a number:
|
|
13
|
+
*
|
|
14
|
+
* ./pricing-snapshot.generated.ts platform prices, rendered from
|
|
15
|
+
* packages/control-db/src/pricing/seed.ts by
|
|
16
|
+
* `npm run pricing:snapshot` and CI-gated.
|
|
17
|
+
* To change one, edit the SEED.
|
|
18
|
+
*
|
|
19
|
+
* resolver-derived values below AI column tiers, web-search grounding and
|
|
20
|
+
* the representative enrichment prices come
|
|
21
|
+
* from provider_cost_config (seeded by
|
|
22
|
+
* cogs-rates.ts) — a different source of
|
|
23
|
+
* truth, pinned by
|
|
24
|
+
* pricing-sheet-conformance.test.ts in
|
|
25
|
+
* @oxygen/integrations, which can see both
|
|
26
|
+
* sides and fails when they diverge.
|
|
12
27
|
*
|
|
13
28
|
* Dependency-free on purpose: this module is imported by "use client"
|
|
14
29
|
* marketing components via the `@oxygen/shared/pricing-sheet` subpath, so it
|
|
15
30
|
* must never drag the shared barrel (async_hooks etc.) into a client bundle.
|
|
31
|
+
* The generated snapshot holds that property too — it is literals only.
|
|
32
|
+
*
|
|
33
|
+
* Anything that CAN await a query should read the control DB via
|
|
34
|
+
* loadPricingBook() instead of importing this file, so a staff re-price at
|
|
35
|
+
* /admin/costs takes effect without a deploy.
|
|
16
36
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export const
|
|
37
|
+
import { AUTOMATION_ACTION_CREDITS as SNAPSHOT_AUTOMATION_ACTION_CREDITS, CREDITS_PER_USD as SNAPSHOT_CREDITS_PER_USD, DELIVERABILITY_INCLUDED_TESTS_PER_INBOX as SNAPSHOT_DELIVERABILITY_INCLUDED_TESTS_PER_INBOX, DELIVERABILITY_SEAT_CREDITS_PER_MONTH as SNAPSHOT_DELIVERABILITY_SEAT_CREDITS_PER_MONTH, EGRESS_IP_CREDITS_PER_MONTH as SNAPSHOT_EGRESS_IP_CREDITS_PER_MONTH, ENRICHMENT_CREDITS_PER_ROW_TYPICAL as SNAPSHOT_ENRICHMENT_CREDITS_PER_ROW_TYPICAL, LINKEDIN_ACCOUNT_CREDITS_PER_MONTH as SNAPSHOT_LINKEDIN_ACCOUNT_CREDITS_PER_MONTH, LINKEDIN_ACTION_CREDITS as SNAPSHOT_LINKEDIN_ACTION_CREDITS, LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH as SNAPSHOT_LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH, MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL as SNAPSHOT_MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL, MANAGED_DOMAIN_MARKUP as SNAPSHOT_MANAGED_DOMAIN_MARKUP, MANAGED_INBOX_CREDITS_PER_MONTH as SNAPSHOT_MANAGED_INBOX_CREDITS_PER_MONTH, MANAGED_INBOX_MARKUP as SNAPSHOT_MANAGED_INBOX_MARKUP, PLACEMENT_TEST_OVERAGE_CREDITS as SNAPSHOT_PLACEMENT_TEST_OVERAGE_CREDITS, PRICE_SHEET_VERIFIED as SNAPSHOT_PRICE_SHEET_VERIFIED, SEND_CREDITS as SNAPSHOT_SEND_CREDITS, SUBSCRIPTION_USD_PER_1K as SNAPSHOT_SUBSCRIPTION_USD_PER_1K, TOPUP_USD_PER_1K as SNAPSHOT_TOPUP_USD_PER_1K, VOICE_CREDITS_PER_AMD_CALL as SNAPSHOT_VOICE_CREDITS_PER_AMD_CALL, VOICE_CREDITS_PER_MINUTE as SNAPSHOT_VOICE_CREDITS_PER_MINUTE, VOICE_MARKUP as SNAPSHOT_VOICE_MARKUP, VOICE_NUMBER_CREDITS_PER_MONTH as SNAPSHOT_VOICE_NUMBER_CREDITS_PER_MONTH, WHATSAPP_ACCOUNT_CREDITS_PER_MONTH as SNAPSHOT_WHATSAPP_ACCOUNT_CREDITS_PER_MONTH, } from "./pricing-snapshot.generated.js";
|
|
38
|
+
export { creditsToUsd, usdToCredits } from "./pricing-snapshot.generated.js";
|
|
39
|
+
export const PRICING_SHEET_VERIFIED = SNAPSHOT_PRICE_SHEET_VERIFIED;
|
|
40
|
+
export const PRICING_CREDITS_PER_USD = SNAPSHOT_CREDITS_PER_USD;
|
|
20
41
|
/** On-demand top-up price per 1,000 credits (USD); subscriptions pay $1.00. */
|
|
21
|
-
export const TOPUP_USD_PER_1K =
|
|
22
|
-
export const SUBSCRIPTION_USD_PER_1K =
|
|
23
|
-
/**
|
|
42
|
+
export const TOPUP_USD_PER_1K = SNAPSHOT_TOPUP_USD_PER_1K;
|
|
43
|
+
export const SUBSCRIPTION_USD_PER_1K = SNAPSHOT_SUBSCRIPTION_USD_PER_1K;
|
|
44
|
+
/**
|
|
45
|
+
* AI column runs, honest 5× of modeled tier COGS.
|
|
46
|
+
*
|
|
47
|
+
* RESOLVER-DERIVED, not seed-derived: the canonical values live in
|
|
48
|
+
* packages/integrations/src/cogs-rates.ts and are served per-workspace from
|
|
49
|
+
* provider_cost_config. pricing-sheet-conformance.test.ts pins these literals
|
|
50
|
+
* against the live estimator, so a tier re-price fails a test rather than
|
|
51
|
+
* quietly mispricing the page.
|
|
52
|
+
*/
|
|
24
53
|
export const AI_COLUMN_CREDITS = { low: 15, medium: 75, high: 250 };
|
|
25
54
|
/**
|
|
26
55
|
* Web-search grounding, billed per SEARCH on top of the model — not a flat adder.
|
|
@@ -34,27 +63,24 @@ export const AI_COLUMN_CREDITS = { low: 15, medium: 75, high: 250 };
|
|
|
34
63
|
* with parallel as its one fallback (WEB_SEARCH_ENGINES), so a row costs 35 when
|
|
35
64
|
* the primary answers and reserves 40 for the case where both lanes fire.
|
|
36
65
|
*
|
|
37
|
-
*
|
|
38
|
-
* marketing client bundle and cannot import @oxygen/integrations (which depends on
|
|
39
|
-
* @oxygen/shared). `pricing-sheet-conformance.test.ts` in @oxygen/integrations —
|
|
40
|
-
* which can see both — pins these numbers to the live resolver, so drift fails a
|
|
41
|
-
* test instead of quietly mispricing the page again.
|
|
66
|
+
* Resolver-derived like AI_COLUMN_CREDITS above, and pinned by the same test.
|
|
42
67
|
*/
|
|
43
68
|
export const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS = 35;
|
|
44
69
|
export const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 40;
|
|
45
70
|
/** Workflow/automation actions (steps, tool calls, row writes) — capacity guard. */
|
|
46
|
-
export const AUTOMATION_ACTION_CREDITS =
|
|
71
|
+
export const AUTOMATION_ACTION_CREDITS = SNAPSHOT_AUTOMATION_ACTION_CREDITS;
|
|
47
72
|
/**
|
|
48
73
|
* Managed email inboxes: founder-ratified flat price (2026-07-25), superseding
|
|
49
|
-
* the earlier dynamic vendor-COGS × 1.25 range
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* tier. Kept as an object (min/typical/max all equal) rather than a bare number
|
|
53
|
-
* so existing callers that destructure any of the three fields need no shape
|
|
54
|
-
* change.
|
|
74
|
+
* the earlier dynamic vendor-COGS × 1.25 range. Kept as an object (min/typical/max
|
|
75
|
+
* all equal) rather than a bare number so existing callers that destructure any
|
|
76
|
+
* of the three fields need no shape change.
|
|
55
77
|
*/
|
|
56
|
-
export const MANAGED_INBOX_MARKUP =
|
|
57
|
-
export const MANAGED_INBOX_CREDITS_PER_MONTH = {
|
|
78
|
+
export const MANAGED_INBOX_MARKUP = SNAPSHOT_MANAGED_INBOX_MARKUP;
|
|
79
|
+
export const MANAGED_INBOX_CREDITS_PER_MONTH = {
|
|
80
|
+
min: SNAPSHOT_MANAGED_INBOX_CREDITS_PER_MONTH,
|
|
81
|
+
typical: SNAPSHOT_MANAGED_INBOX_CREDITS_PER_MONTH,
|
|
82
|
+
max: SNAPSHOT_MANAGED_INBOX_CREDITS_PER_MONTH,
|
|
83
|
+
};
|
|
58
84
|
/**
|
|
59
85
|
* VOICE (the call channel). Marked up 5×, not the 1.25× infra rule the inbox and
|
|
60
86
|
* domain rails use: a phone number carries ongoing reputation work (warm-up,
|
|
@@ -68,20 +94,13 @@ export const MANAGED_INBOX_CREDITS_PER_MONTH = { min: 3_000, typical: 3_000, max
|
|
|
68
94
|
* $0.0180 / min
|
|
69
95
|
* Costing only the outbound leg undercharges every call by 29%.
|
|
70
96
|
*/
|
|
71
|
-
export const VOICE_MARKUP =
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
* computed markup, the way a customer actually reads a price.
|
|
76
|
-
*/
|
|
77
|
-
export const VOICE_NUMBER_CREDITS_PER_MONTH = 5_000;
|
|
78
|
-
/** Both legs, $0.018/min × 5 → $0.09/min. */
|
|
79
|
-
export const VOICE_CREDITS_PER_MINUTE = 90;
|
|
80
|
-
/** Answering-machine detection is per CALL, not per minute — it bills on no-answers too. */
|
|
81
|
-
export const VOICE_CREDITS_PER_AMD_CALL = 38;
|
|
97
|
+
export const VOICE_MARKUP = SNAPSHOT_VOICE_MARKUP;
|
|
98
|
+
export const VOICE_NUMBER_CREDITS_PER_MONTH = SNAPSHOT_VOICE_NUMBER_CREDITS_PER_MONTH;
|
|
99
|
+
export const VOICE_CREDITS_PER_MINUTE = SNAPSHOT_VOICE_CREDITS_PER_MINUTE;
|
|
100
|
+
export const VOICE_CREDITS_PER_AMD_CALL = SNAPSHOT_VOICE_CREDITS_PER_AMD_CALL;
|
|
82
101
|
/** Managed domains: registrar at-cost × 1.25 (≈ a $10.44 .com → ~13,050 credits/yr). */
|
|
83
|
-
export const MANAGED_DOMAIN_MARKUP =
|
|
84
|
-
export const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL =
|
|
102
|
+
export const MANAGED_DOMAIN_MARKUP = SNAPSHOT_MANAGED_DOMAIN_MARKUP;
|
|
103
|
+
export const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = SNAPSHOT_MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL;
|
|
85
104
|
/**
|
|
86
105
|
* Inbox deliverability (EmailGuard placement seat). A flat monthly price per
|
|
87
106
|
* SUBSCRIBED inbox covering continuous deliverability monitoring (blacklist,
|
|
@@ -89,18 +108,6 @@ export const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13_050;
|
|
|
89
108
|
* inbox-placement (spam) tests; tests beyond the allowance bill the per-test
|
|
90
109
|
* price.
|
|
91
110
|
*
|
|
92
|
-
* All three are DISPLAY mirrors, per this file's contract. The canonical values
|
|
93
|
-
* live where they are enforced, and seed-parity.test.ts binds them so a mirror
|
|
94
|
-
* can never quietly drift from the number actually billed:
|
|
95
|
-
* seat DELIVERABILITY_UNIT_MONTHLY_CREDITS (@oxygen/control-db,
|
|
96
|
-
* also PRICING_SEED commitment.deliverability_unit) — 1,000 credits
|
|
97
|
-
* ($1.00), restored by the founder on 2026-07-30 after reviewing the
|
|
98
|
-
* Agency-plan unit economics, superseding the 2026-07-26 signature
|
|
99
|
-
* of 2,000.
|
|
100
|
-
* allowance DELIVERABILITY_INCLUDED_TESTS_PER_INBOX (@oxygen/control-db)
|
|
101
|
-
* overage EMAILGUARD_MANAGED_PLACEMENT_CREDITS (@oxygen/providers,
|
|
102
|
-
* derived from the Agency plan rather than typed in)
|
|
103
|
-
*
|
|
104
111
|
* THE ALLOWANCE IS LOAD-BEARING, not a perk. Placement COGS is per TEST
|
|
105
112
|
* ($0.1327 on EmailGuard's Agency plan), not per inbox, so an unbounded seat
|
|
106
113
|
* inverts its own margin: at $1.00/inbox-month the EIGHTH test in a cycle is
|
|
@@ -108,54 +115,40 @@ export const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13_050;
|
|
|
108
115
|
* revenue — a ~73% margin — and everything past them bills
|
|
109
116
|
* PLACEMENT_TEST_OVERAGE_CREDITS. Orgs on their own EmailGuard key (BYOK) pay 0.
|
|
110
117
|
*/
|
|
111
|
-
export const DELIVERABILITY_SEAT_CREDITS_PER_MONTH =
|
|
112
|
-
export const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX =
|
|
113
|
-
|
|
114
|
-
export const PLACEMENT_TEST_OVERAGE_CREDITS = 166;
|
|
118
|
+
export const DELIVERABILITY_SEAT_CREDITS_PER_MONTH = SNAPSHOT_DELIVERABILITY_SEAT_CREDITS_PER_MONTH;
|
|
119
|
+
export const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX = SNAPSHOT_DELIVERABILITY_INCLUDED_TESTS_PER_INBOX;
|
|
120
|
+
export const PLACEMENT_TEST_OVERAGE_CREDITS = SNAPSHOT_PLACEMENT_TEST_OVERAGE_CREDITS;
|
|
115
121
|
/**
|
|
116
122
|
* LinkedIn accounts: founder decision (2026-07-25) — a PURE seat model. The
|
|
117
|
-
* flat monthly connection fee per connected account is
|
|
118
|
-
* price
|
|
119
|
-
*
|
|
120
|
-
* WhatsApp stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
|
|
123
|
+
* flat monthly connection fee per connected account is the WHOLE LinkedIn
|
|
124
|
+
* price; every per-action charge is 0. Per-MESSAGE sends on email and WhatsApp
|
|
125
|
+
* stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
|
|
121
126
|
* connection fee, see WHATSAPP_ACCOUNT_CREDITS_PER_MONTH.
|
|
122
127
|
*/
|
|
123
|
-
export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH =
|
|
124
|
-
export const LINKEDIN_ACTION_CREDITS =
|
|
125
|
-
|
|
126
|
-
invite: 0,
|
|
127
|
-
message: 0,
|
|
128
|
-
inmail: 0,
|
|
129
|
-
follow: 0,
|
|
130
|
-
like_post: 0,
|
|
131
|
-
comment_post: 0,
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* Editable calculator default: a warmed account's typical monthly action mix.
|
|
135
|
-
* 0 under the pure seat model (2026-07-25) — actions no longer add to the
|
|
136
|
-
* LinkedIn line regardless of volume, so this default carries no credits.
|
|
137
|
-
* Kept (not deleted) because PRICING_CALCULATOR_DEFAULTS.linkedinActionCreditsPerAccount
|
|
138
|
-
* still reads it as its default value.
|
|
139
|
-
*/
|
|
140
|
-
export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
|
|
128
|
+
export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = SNAPSHOT_LINKEDIN_ACCOUNT_CREDITS_PER_MONTH;
|
|
129
|
+
export const LINKEDIN_ACTION_CREDITS = SNAPSHOT_LINKEDIN_ACTION_CREDITS;
|
|
130
|
+
export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = SNAPSHOT_LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH;
|
|
141
131
|
/**
|
|
142
132
|
* WhatsApp numbers: flat monthly connection fee per connected number, the same
|
|
143
|
-
* seat shape as LinkedIn
|
|
144
|
-
*
|
|
145
|
-
*
|
|
133
|
+
* seat shape as LinkedIn. Billed off the rolling-30d peak, so a number connected
|
|
134
|
+
* part-way through a month still bills the full cycle. WhatsApp message sends
|
|
135
|
+
* themselves remain 0 credits.
|
|
146
136
|
*/
|
|
147
|
-
export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH =
|
|
137
|
+
export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = SNAPSHOT_WHATSAPP_ACCOUNT_CREDITS_PER_MONTH;
|
|
148
138
|
/** Dedicated egress IP add-on. */
|
|
149
|
-
export const EGRESS_IP_CREDITS_PER_MONTH =
|
|
139
|
+
export const EGRESS_IP_CREDITS_PER_MONTH = SNAPSHOT_EGRESS_IP_CREDITS_PER_MONTH;
|
|
150
140
|
/**
|
|
151
141
|
* Email + WhatsApp sends cost nothing per message — the pool pays for inboxes and
|
|
152
142
|
* connected accounts, not for sends.
|
|
153
143
|
*/
|
|
154
|
-
export const SEND_CREDITS =
|
|
144
|
+
export const SEND_CREDITS = SNAPSHOT_SEND_CREDITS;
|
|
155
145
|
/**
|
|
156
146
|
* Representative enrichment prices (5× provider COGS via the resolver; the
|
|
157
147
|
* live per-operation table is served by /api/pricing/customer-credit-prices).
|
|
158
148
|
* "typical" = the cheap-first waterfall's common case, used by the calculator.
|
|
149
|
+
*
|
|
150
|
+
* Resolver-derived, like AI_COLUMN_CREDITS: these mirror cogs-rates.ts, not the
|
|
151
|
+
* pricing seed.
|
|
159
152
|
*/
|
|
160
153
|
export const ENRICHMENT_CREDITS = {
|
|
161
154
|
email_verify: 2.245, // MillionVerifier first pass (exactly 5x COGS)
|
|
@@ -167,10 +160,4 @@ export const ENRICHMENT_CREDITS = {
|
|
|
167
160
|
linkedin_profile_scrape: 25.5, // HarvestAPI Basic full-profile job, exactly 5x COGS
|
|
168
161
|
};
|
|
169
162
|
/** Editable calculator default: blended credits per fully-enriched row. */
|
|
170
|
-
export const ENRICHMENT_CREDITS_PER_ROW_TYPICAL =
|
|
171
|
-
export function creditsToUsd(credits) {
|
|
172
|
-
return credits / PRICING_CREDITS_PER_USD;
|
|
173
|
-
}
|
|
174
|
-
export function usdToCredits(usd) {
|
|
175
|
-
return usd * PRICING_CREDITS_PER_USD;
|
|
176
|
-
}
|
|
163
|
+
export const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = SNAPSHOT_ENRICHMENT_CREDITS_PER_ROW_TYPICAL;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** Period the customer-facing price sheet was last reconciled end to end. */
|
|
2
|
+
export declare const PRICE_SHEET_VERIFIED = "2026-07";
|
|
3
|
+
/** $1 = 1_000 credits (Pricing Model 2.0). */
|
|
4
|
+
export declare const CREDITS_PER_USD = 1000;
|
|
5
|
+
/** The divisor in the markup formula; exact inverse of CREDITS_PER_USD. */
|
|
6
|
+
export declare const CREDIT_USD_VALUE = 0.001;
|
|
7
|
+
/** On-demand top-up, in USD cents per 1,000 credits. */
|
|
8
|
+
export declare const TOPUP_USD_CENTS_PER_1K_CREDITS = 125;
|
|
9
|
+
/** On-demand top-up price per 1,000 credits, in USD. */
|
|
10
|
+
export declare const TOPUP_USD_PER_1K = 1.25;
|
|
11
|
+
/** Subscription credits convert at face value, making them exactly 20% cheaper. */
|
|
12
|
+
export declare const SUBSCRIPTION_USD_PER_1K = 1;
|
|
13
|
+
export declare const MANAGED_INBOX_MARKUP = 1.25;
|
|
14
|
+
export declare const MANAGED_DOMAIN_MARKUP = 1.25;
|
|
15
|
+
export declare const VOICE_MARKUP = 5;
|
|
16
|
+
/** Applied to actual provider inference cost at settle time. */
|
|
17
|
+
export declare const COPILOT_CREDIT_MARKUP_MULTIPLIER = 5;
|
|
18
|
+
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 10000;
|
|
19
|
+
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 10000;
|
|
20
|
+
export declare const EGRESS_IP_CREDITS_PER_MONTH = 25000;
|
|
21
|
+
export declare const SENDING_MAILBOX_CREDITS_PER_MONTH = 1000;
|
|
22
|
+
export declare const MANAGED_INBOX_CREDITS_PER_MONTH = 3000;
|
|
23
|
+
export declare const MAILBOX_WARMUP_CREDITS_PER_MONTH = 3000;
|
|
24
|
+
export declare const DELIVERABILITY_SEAT_CREDITS_PER_MONTH = 1000;
|
|
25
|
+
/** Included inbox-placement tests per subscribed inbox per cycle. */
|
|
26
|
+
export declare const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX = 2;
|
|
27
|
+
/** A placement test beyond the included allowance. */
|
|
28
|
+
export declare const PLACEMENT_TEST_OVERAGE_CREDITS = 166;
|
|
29
|
+
/** Representative, not billed: a typical .com at MANAGED_DOMAIN_MARKUP. */
|
|
30
|
+
export declare const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13050;
|
|
31
|
+
export declare const VOICE_NUMBER_CREDITS_PER_MONTH = 5000;
|
|
32
|
+
export declare const VOICE_CREDITS_PER_MINUTE = 90;
|
|
33
|
+
export declare const VOICE_CREDITS_PER_AMD_CALL = 38;
|
|
34
|
+
/** Workflow steps, tool calls and row writes — a capacity guard, not a margin line. */
|
|
35
|
+
export declare const AUTOMATION_ACTION_CREDITS = 0.01;
|
|
36
|
+
/** Email, LinkedIn and WhatsApp sends are free; the pool pays for seats and inboxes. */
|
|
37
|
+
export declare const SEND_CREDITS = 0;
|
|
38
|
+
/** Every LinkedIn action is 0 under the pure seat model. */
|
|
39
|
+
export declare const LINKEDIN_ACTION_CREDITS: {
|
|
40
|
+
readonly visit_profile: 0;
|
|
41
|
+
readonly invite: 0;
|
|
42
|
+
readonly message: 0;
|
|
43
|
+
readonly inmail: 0;
|
|
44
|
+
readonly follow: 0;
|
|
45
|
+
readonly like_post: 0;
|
|
46
|
+
readonly comment_post: 0;
|
|
47
|
+
};
|
|
48
|
+
export declare const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = 100;
|
|
49
|
+
export declare const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
|
|
50
|
+
export type PricingPlanSnapshot = {
|
|
51
|
+
readonly planKey: string;
|
|
52
|
+
readonly tier: string;
|
|
53
|
+
readonly isLegacy: boolean;
|
|
54
|
+
readonly monthlyPriceCents: number | null;
|
|
55
|
+
readonly monthlyCredits: number | null;
|
|
56
|
+
readonly weeklyCreditsLimit: number | null;
|
|
57
|
+
readonly rolloverCap: number | null;
|
|
58
|
+
readonly byokEnabled: boolean;
|
|
59
|
+
};
|
|
60
|
+
export declare const PRICING_PLAN_SNAPSHOT: readonly PricingPlanSnapshot[];
|
|
61
|
+
export declare function creditsToUsd(credits: number): number;
|
|
62
|
+
export declare function usdToCredits(usd: number): number;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// GENERATED FROM packages/control-db/src/pricing/seed.ts — DO NOT HAND-EDIT.
|
|
2
|
+
//
|
|
3
|
+
// Regenerate with `npm run pricing:snapshot`. CI runs
|
|
4
|
+
// `npm run pricing:snapshot -- --check` and fails when this file and the seed
|
|
5
|
+
// disagree, so a hand-edit here is reverted rather than shipped.
|
|
6
|
+
//
|
|
7
|
+
// To change a price, edit the SEED. This file is a rendering of it, kept for the
|
|
8
|
+
// consumers that cannot query the control DB: @oxygen/shared (no @oxygen/*
|
|
9
|
+
// dependencies by design), the "use client" marketing and in-product components,
|
|
10
|
+
// and module-level catalogs built at import time.
|
|
11
|
+
//
|
|
12
|
+
// Everything that CAN await a query reads the database instead, via
|
|
13
|
+
// loadPricingBook() — a staff re-price at /admin/costs moves those with no deploy
|
|
14
|
+
// and does NOT move this file.
|
|
15
|
+
/** Period the customer-facing price sheet was last reconciled end to end. */
|
|
16
|
+
export const PRICE_SHEET_VERIFIED = "2026-07";
|
|
17
|
+
// --- conversion -------------------------------------------------------------
|
|
18
|
+
/** $1 = 1_000 credits (Pricing Model 2.0). */
|
|
19
|
+
export const CREDITS_PER_USD = 1_000;
|
|
20
|
+
/** The divisor in the markup formula; exact inverse of CREDITS_PER_USD. */
|
|
21
|
+
export const CREDIT_USD_VALUE = 0.001;
|
|
22
|
+
/** On-demand top-up, in USD cents per 1,000 credits. */
|
|
23
|
+
export const TOPUP_USD_CENTS_PER_1K_CREDITS = 125;
|
|
24
|
+
/** On-demand top-up price per 1,000 credits, in USD. */
|
|
25
|
+
export const TOPUP_USD_PER_1K = 1.25;
|
|
26
|
+
/** Subscription credits convert at face value, making them exactly 20% cheaper. */
|
|
27
|
+
export const SUBSCRIPTION_USD_PER_1K = 1;
|
|
28
|
+
// --- markups ----------------------------------------------------------------
|
|
29
|
+
export const MANAGED_INBOX_MARKUP = 1.25;
|
|
30
|
+
export const MANAGED_DOMAIN_MARKUP = 1.25;
|
|
31
|
+
export const VOICE_MARKUP = 5;
|
|
32
|
+
/** Applied to actual provider inference cost at settle time. */
|
|
33
|
+
export const COPILOT_CREDIT_MARKUP_MULTIPLIER = 5;
|
|
34
|
+
// --- seats and recurring charges --------------------------------------------
|
|
35
|
+
export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 10_000;
|
|
36
|
+
export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 10_000;
|
|
37
|
+
export const EGRESS_IP_CREDITS_PER_MONTH = 25_000;
|
|
38
|
+
export const SENDING_MAILBOX_CREDITS_PER_MONTH = 1_000;
|
|
39
|
+
export const MANAGED_INBOX_CREDITS_PER_MONTH = 3_000;
|
|
40
|
+
export const MAILBOX_WARMUP_CREDITS_PER_MONTH = 3_000;
|
|
41
|
+
export const DELIVERABILITY_SEAT_CREDITS_PER_MONTH = 1_000;
|
|
42
|
+
/** Included inbox-placement tests per subscribed inbox per cycle. */
|
|
43
|
+
export const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX = 2;
|
|
44
|
+
/** A placement test beyond the included allowance. */
|
|
45
|
+
export const PLACEMENT_TEST_OVERAGE_CREDITS = 166;
|
|
46
|
+
/** Representative, not billed: a typical .com at MANAGED_DOMAIN_MARKUP. */
|
|
47
|
+
export const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13_050;
|
|
48
|
+
// --- voice ------------------------------------------------------------------
|
|
49
|
+
export const VOICE_NUMBER_CREDITS_PER_MONTH = 5_000;
|
|
50
|
+
export const VOICE_CREDITS_PER_MINUTE = 90;
|
|
51
|
+
export const VOICE_CREDITS_PER_AMD_CALL = 38;
|
|
52
|
+
// --- per-action -------------------------------------------------------------
|
|
53
|
+
/** Workflow steps, tool calls and row writes — a capacity guard, not a margin line. */
|
|
54
|
+
export const AUTOMATION_ACTION_CREDITS = 0.01;
|
|
55
|
+
/** Email, LinkedIn and WhatsApp sends are free; the pool pays for seats and inboxes. */
|
|
56
|
+
export const SEND_CREDITS = 0;
|
|
57
|
+
/** Every LinkedIn action is 0 under the pure seat model. */
|
|
58
|
+
export const LINKEDIN_ACTION_CREDITS = {
|
|
59
|
+
visit_profile: 0,
|
|
60
|
+
invite: 0,
|
|
61
|
+
message: 0,
|
|
62
|
+
inmail: 0,
|
|
63
|
+
follow: 0,
|
|
64
|
+
like_post: 0,
|
|
65
|
+
comment_post: 0,
|
|
66
|
+
};
|
|
67
|
+
// --- pricing-calculator defaults (not prices) -------------------------------
|
|
68
|
+
export const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = 100;
|
|
69
|
+
export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
|
|
70
|
+
export const PRICING_PLAN_SNAPSHOT = [
|
|
71
|
+
{ planKey: "free", tier: "free", isLegacy: false, monthlyPriceCents: 0, monthlyCredits: 0, weeklyCreditsLimit: null, rolloverCap: null, byokEnabled: false },
|
|
72
|
+
{ planKey: "starter", tier: "starter", isLegacy: false, monthlyPriceCents: 9_900, monthlyCredits: 99_000, weeklyCreditsLimit: null, rolloverCap: 99_000, byokEnabled: true },
|
|
73
|
+
{ planKey: "pro", tier: "pro", isLegacy: false, monthlyPriceCents: 24_900, monthlyCredits: 249_000, weeklyCreditsLimit: null, rolloverCap: 249_000, byokEnabled: true },
|
|
74
|
+
{ planKey: "team", tier: "team", isLegacy: false, monthlyPriceCents: 74_900, monthlyCredits: 749_000, weeklyCreditsLimit: null, rolloverCap: 749_000, byokEnabled: true },
|
|
75
|
+
{ planKey: "scale", tier: "scale", isLegacy: false, monthlyPriceCents: null, monthlyCredits: 10_000_000, weeklyCreditsLimit: null, rolloverCap: 10_000_000, byokEnabled: true },
|
|
76
|
+
{ planKey: "enterprise", tier: "enterprise", isLegacy: false, monthlyPriceCents: null, monthlyCredits: null, weeklyCreditsLimit: null, rolloverCap: null, byokEnabled: true },
|
|
77
|
+
{ planKey: "launch_50", tier: "starter", isLegacy: true, monthlyPriceCents: 5_000, monthlyCredits: 200_000, weeklyCreditsLimit: 200_000, rolloverCap: 200_000, byokEnabled: true },
|
|
78
|
+
{ planKey: "starter_50", tier: "starter", isLegacy: true, monthlyPriceCents: 5_000, monthlyCredits: 200_000, weeklyCreditsLimit: 200_000, rolloverCap: 200_000, byokEnabled: true },
|
|
79
|
+
{ planKey: "pro_149", tier: "pro", isLegacy: true, monthlyPriceCents: 14_900, monthlyCredits: 1_000_000, weeklyCreditsLimit: 1_000_000, rolloverCap: 1_000_000, byokEnabled: true },
|
|
80
|
+
{ planKey: "team_399", tier: "team", isLegacy: true, monthlyPriceCents: 39_900, monthlyCredits: 3_000_000, weeklyCreditsLimit: 3_000_000, rolloverCap: 3_000_000, byokEnabled: true },
|
|
81
|
+
{ planKey: "growth_250", tier: "pro", isLegacy: true, monthlyPriceCents: 25_000, monthlyCredits: 250_000, weeklyCreditsLimit: 100_000, rolloverCap: 250_000, byokEnabled: true },
|
|
82
|
+
{ planKey: "scale_750", tier: "team", isLegacy: true, monthlyPriceCents: 75_000, monthlyCredits: 750_000, weeklyCreditsLimit: 300_000, rolloverCap: 750_000, byokEnabled: true },
|
|
83
|
+
{ planKey: "starter_legacy", tier: "starter", isLegacy: true, monthlyPriceCents: null, monthlyCredits: 200_000, weeklyCreditsLimit: null, rolloverCap: 200_000, byokEnabled: true },
|
|
84
|
+
{ planKey: "scale_legacy", tier: "scale", isLegacy: true, monthlyPriceCents: null, monthlyCredits: 1_200_000, weeklyCreditsLimit: null, rolloverCap: 2_400_000, byokEnabled: true },
|
|
85
|
+
];
|
|
86
|
+
export function creditsToUsd(credits) {
|
|
87
|
+
return credits / CREDITS_PER_USD;
|
|
88
|
+
}
|
|
89
|
+
export function usdToCredits(usd) {
|
|
90
|
+
return usd * CREDITS_PER_USD;
|
|
91
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One vocabulary for "the provider refused because of money".
|
|
3
|
+
*
|
|
4
|
+
* A provider 402 has reached customers wearing four different costumes:
|
|
5
|
+
* - `provider_credits_exhausted` (tool runner, managed pool)
|
|
6
|
+
* - `connection_credits_exhausted` (tool runner, BYOK connection)
|
|
7
|
+
* - `provider_insufficient_credits` (enrichment column runner + waterfall)
|
|
8
|
+
* - `provider_credit_exhausted` (worker lane exclusion, singular)
|
|
9
|
+
* plus `provider_plan_limit` for the adjacent "your plan does not include this"
|
|
10
|
+
* refusal, which is also a money problem and also not retryable.
|
|
11
|
+
*
|
|
12
|
+
* Only the first two were known to the run-bottleneck classifier. The others
|
|
13
|
+
* fell through to a `/rate|limit|429/` test — which `provider_plan_limit`
|
|
14
|
+
* matches on the substring "limit" — or to the deferral branch, so a hard 402
|
|
15
|
+
* surfaced to the customer as `bottlenecks: [provider_rate_limit]`. That reads
|
|
16
|
+
* as "wait and retry": a partner agency spent hours lowering concurrency against
|
|
17
|
+
* an account that was simply out of credits, and the real 402 was only visible
|
|
18
|
+
* through a different command.
|
|
19
|
+
*
|
|
20
|
+
* The distinction that matters operationally: a rate limit clears by waiting, a
|
|
21
|
+
* funding failure never does. Anything that decides "should the customer wait?"
|
|
22
|
+
* must ask this predicate, not a regex over the code string.
|
|
23
|
+
*/
|
|
24
|
+
/** Codes meaning the provider refused for funding/entitlement reasons. Never retryable by waiting. */
|
|
25
|
+
export declare const PROVIDER_FUNDING_ERROR_CODES: readonly ["provider_credits_exhausted", "provider_credits_exhausted_deferred", "connection_credits_exhausted", "provider_insufficient_credits", "provider_credit_exhausted", "provider_plan_limit", "blocked_provider_funding"];
|
|
26
|
+
export type ProviderFundingErrorCode = (typeof PROVIDER_FUNDING_ERROR_CODES)[number];
|
|
27
|
+
/**
|
|
28
|
+
* True when the code means "this failed over money", in any of its spellings.
|
|
29
|
+
*
|
|
30
|
+
* Matches on the exact code first, then falls back to a narrow shape test so a
|
|
31
|
+
* provider-specific variant (`peopledatalabs_credits_exhausted`) is still
|
|
32
|
+
* classified as funding rather than silently treated as retryable. Deliberately
|
|
33
|
+
* does NOT match on "limit" alone — `rate_limit_exceeded` is a real rate limit.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isProviderFundingErrorCode(code: string | null | undefined): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* True for a genuine rate limit — one that clears by waiting.
|
|
38
|
+
*
|
|
39
|
+
* A funding failure always wins: `provider_plan_limit` contains "limit" and
|
|
40
|
+
* would otherwise read as retryable.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isProviderRateLimitErrorCode(code: string | null | undefined): boolean;
|
|
43
|
+
/** The customer-facing next step for a funding refusal, by credential ownership. */
|
|
44
|
+
export declare function providerFundingNextStep(credentialMode: "managed" | "byok" | null | undefined): string;
|