@oxygen-agent/cli 1.365.3 → 1.575.19

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.
Files changed (99) hide show
  1. package/README.md +1 -1
  2. package/dist/column-run-notices.d.ts +11 -0
  3. package/dist/column-run-notices.js +37 -0
  4. package/dist/command-manifest.js +13 -8
  5. package/dist/help.js +78 -16
  6. package/dist/index.js +3873 -514
  7. package/dist/skills.js +106 -1
  8. package/node_modules/@oxygen/formula/dist/coerce.d.ts +8 -0
  9. package/node_modules/@oxygen/formula/dist/coerce.js +10 -0
  10. package/node_modules/@oxygen/formula/dist/evaluate.d.ts +31 -0
  11. package/node_modules/@oxygen/formula/dist/evaluate.js +248 -0
  12. package/node_modules/@oxygen/formula/dist/expression.d.ts +64 -0
  13. package/node_modules/@oxygen/formula/dist/expression.js +428 -0
  14. package/node_modules/@oxygen/formula/dist/formula-functions.d.ts +71 -0
  15. package/node_modules/@oxygen/formula/dist/formula-functions.js +1100 -0
  16. package/node_modules/@oxygen/formula/dist/index.d.ts +17 -0
  17. package/node_modules/@oxygen/formula/dist/index.js +17 -0
  18. package/node_modules/@oxygen/formula/dist/value-normalizers.d.ts +30 -0
  19. package/node_modules/@oxygen/formula/dist/value-normalizers.js +80 -0
  20. package/node_modules/@oxygen/formula/package.json +26 -0
  21. package/node_modules/@oxygen/recipe-sdk/dist/index.d.ts +30 -0
  22. package/node_modules/@oxygen/recipe-sdk/dist/index.js +2 -2
  23. package/node_modules/@oxygen/shared/dist/billing-anchors.d.ts +60 -0
  24. package/node_modules/@oxygen/shared/dist/billing-anchors.js +135 -0
  25. package/node_modules/@oxygen/shared/dist/billing.d.ts +101 -5
  26. package/node_modules/@oxygen/shared/dist/billing.js +192 -8
  27. package/node_modules/@oxygen/shared/dist/call-outcomes.d.ts +59 -0
  28. package/node_modules/@oxygen/shared/dist/call-outcomes.js +73 -0
  29. package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
  30. package/node_modules/@oxygen/shared/dist/credit-guidance.js +3 -1
  31. package/node_modules/@oxygen/shared/dist/crm-reply-events.d.ts +35 -0
  32. package/node_modules/@oxygen/shared/dist/crm-reply-events.js +31 -0
  33. package/node_modules/@oxygen/shared/dist/dial-guardrail-overrides.d.ts +50 -0
  34. package/node_modules/@oxygen/shared/dist/dial-guardrail-overrides.js +65 -0
  35. package/node_modules/@oxygen/shared/dist/directory.d.ts +1 -1
  36. package/node_modules/@oxygen/shared/dist/directory.js +1 -0
  37. package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +17 -1
  38. package/node_modules/@oxygen/shared/dist/hosted-ai.js +52 -3
  39. package/node_modules/@oxygen/shared/dist/index.d.ts +11 -0
  40. package/node_modules/@oxygen/shared/dist/index.js +15 -0
  41. package/node_modules/@oxygen/shared/dist/langfuse.d.ts +77 -0
  42. package/node_modules/@oxygen/shared/dist/langfuse.js +231 -0
  43. package/node_modules/@oxygen/shared/dist/linkedin-quota-denial.d.ts +31 -0
  44. package/node_modules/@oxygen/shared/dist/linkedin-quota-denial.js +56 -0
  45. package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +5 -4
  46. package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +5 -4
  47. package/node_modules/@oxygen/shared/dist/linkedin-url.d.ts +22 -0
  48. package/node_modules/@oxygen/shared/dist/linkedin-url.js +7 -4
  49. package/node_modules/@oxygen/shared/dist/log.js +56 -4
  50. package/node_modules/@oxygen/shared/dist/microsoft-consent-url.d.ts +7 -0
  51. package/node_modules/@oxygen/shared/dist/microsoft-consent-url.js +29 -0
  52. package/node_modules/@oxygen/shared/dist/object-storage.d.ts +31 -0
  53. package/node_modules/@oxygen/shared/dist/object-storage.js +61 -0
  54. package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +636 -0
  55. package/node_modules/@oxygen/shared/dist/plan-limits.js +199 -0
  56. package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +89 -23
  57. package/node_modules/@oxygen/shared/dist/pricing-sheet.js +88 -24
  58. package/node_modules/@oxygen/shared/dist/sequence-crm-events.d.ts +291 -0
  59. package/node_modules/@oxygen/shared/dist/sequence-crm-events.js +224 -0
  60. package/node_modules/@oxygen/shared/dist/sequence-template.d.ts +42 -1
  61. package/node_modules/@oxygen/shared/dist/sequence-template.js +0 -0
  62. package/node_modules/@oxygen/shared/dist/sequences.d.ts +287 -24
  63. package/node_modules/@oxygen/shared/dist/sequences.js +940 -60
  64. package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +70 -0
  65. package/node_modules/@oxygen/shared/dist/spend-safety.js +106 -0
  66. package/node_modules/@oxygen/shared/dist/tags.d.ts +90 -1
  67. package/node_modules/@oxygen/shared/dist/tags.js +126 -6
  68. package/node_modules/@oxygen/shared/dist/version.d.ts +1 -1
  69. package/node_modules/@oxygen/shared/dist/version.js +1 -1
  70. package/node_modules/@oxygen/shared/dist/workflow-trigger-metadata.d.ts +1 -1
  71. package/node_modules/@oxygen/shared/dist/workflow-trigger-metadata.js +4 -0
  72. package/node_modules/@oxygen/shared/dist/workspace-agents.d.ts +8 -7
  73. package/node_modules/@oxygen/shared/dist/workspace-agents.js +34 -7
  74. package/node_modules/@oxygen/shared/package.json +95 -0
  75. package/node_modules/@oxygen/workflows/dist/event-dispatch.d.ts +126 -0
  76. package/node_modules/@oxygen/workflows/dist/event-dispatch.js +173 -0
  77. package/node_modules/@oxygen/workflows/dist/graph/expression.d.ts +78 -0
  78. package/node_modules/@oxygen/workflows/dist/graph/expression.js +700 -0
  79. package/node_modules/@oxygen/workflows/dist/graph/index.d.ts +20 -0
  80. package/node_modules/@oxygen/workflows/dist/graph/index.js +20 -0
  81. package/node_modules/@oxygen/workflows/dist/graph/lint.d.ts +4 -0
  82. package/node_modules/@oxygen/workflows/dist/graph/lint.js +812 -0
  83. package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.d.ts +501 -0
  84. package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.js +200 -0
  85. package/node_modules/@oxygen/workflows/dist/graph/params.d.ts +86 -0
  86. package/node_modules/@oxygen/workflows/dist/graph/params.js +173 -0
  87. package/node_modules/@oxygen/workflows/dist/graph/remap.d.ts +48 -0
  88. package/node_modules/@oxygen/workflows/dist/graph/remap.js +213 -0
  89. package/node_modules/@oxygen/workflows/dist/graph/topology.d.ts +46 -0
  90. package/node_modules/@oxygen/workflows/dist/graph/topology.js +280 -0
  91. package/node_modules/@oxygen/workflows/dist/graph/types.d.ts +270 -0
  92. package/node_modules/@oxygen/workflows/dist/graph/types.js +93 -0
  93. package/node_modules/@oxygen/workflows/dist/index.d.ts +113 -1
  94. package/node_modules/@oxygen/workflows/dist/index.js +179 -13
  95. package/node_modules/@oxygen/workflows/dist/tool-effects.d.ts +1 -0
  96. package/node_modules/@oxygen/workflows/dist/tool-effects.js +19 -0
  97. package/node_modules/@oxygen/workflows/dist/usage-estimate.js +135 -4
  98. package/node_modules/@oxygen/workflows/package.json +4 -0
  99. package/package.json +10 -5
@@ -0,0 +1,199 @@
1
+ import { resolveBasePricingPlan } from "./billing.js";
2
+ export const LIMITS_TIER_ORDER = [
3
+ "free",
4
+ "starter",
5
+ "pro",
6
+ "team",
7
+ "scale",
8
+ ];
9
+ const HOUR = 60 * 60;
10
+ const DAY = 24 * HOUR;
11
+ const MIB = 1024 * 1024;
12
+ /**
13
+ * The per-rung limit matrix. `ai_live` deliberately equals `tool_live` at every
14
+ * rung — one "live actions" mental model; the per-call cost asymmetry between
15
+ * AI and tool calls is priced in credits, not throttled here.
16
+ */
17
+ export const PLAN_LIMITS = {
18
+ free: {
19
+ cli: {
20
+ global: { keyRequestsPerMinute: 120, orgRequestsPerMinute: 600 },
21
+ tenantRead: { requestsPerMinute: 60, orgUnits: { limit: 500_000, windowSeconds: HOUR } },
22
+ tenantWrite: { requestsPerMinute: 30, orgUnits: { limit: 100_000, windowSeconds: HOUR } },
23
+ bulkImport: { requestsPerMinute: 10, orgRequests: { limit: 100, windowSeconds: HOUR } },
24
+ aiLive: { requestsPerMinute: 20, orgRequests: { limit: 100, windowSeconds: HOUR } },
25
+ toolLive: { requestsPerMinute: 20, orgRequests: { limit: 100, windowSeconds: HOUR } },
26
+ toolDryRun: { requestsPerMinute: 60, orgRequests: { limit: 500, windowSeconds: HOUR } },
27
+ tenantSchema: { requestsPerMinute: 20, orgRequests: { limit: 100, windowSeconds: HOUR } },
28
+ maxWriteRowsPerRequest: 5_000,
29
+ },
30
+ web: {
31
+ tenantRead: { requestsPerMinute: 120, orgUnits: { limit: 1_000_000, windowSeconds: HOUR } },
32
+ tenantWrite: { requestsPerMinute: 60, orgUnits: { limit: 500_000, windowSeconds: HOUR } },
33
+ columnRun: { requestsPerMinute: 30, orgUnits: { limit: 2_000, windowSeconds: HOUR } },
34
+ import: { requestsPerMinute: 10, orgRequests: { limit: 100, windowSeconds: HOUR } },
35
+ },
36
+ import: {
37
+ maxRowsPerFile: 50_000,
38
+ maxFileBytes: 25 * MIB,
39
+ maxDirectCsvBodyBytes: 10_000_000,
40
+ },
41
+ agents: {
42
+ maxTotalCredits: 10_000,
43
+ maxInferenceCredits: 5_000,
44
+ maxUpstreamCostUsd: 10,
45
+ maxUpstreamCostUsdByok: 10,
46
+ },
47
+ copilot: { maxSessionBudgetCredits: 5_000, defaultPerTurnCreditCeiling: 1_500 },
48
+ signals: { maxEvents: 100, maxWindowDays: 30 },
49
+ tableActions: { maxActionsPerRun: 10 },
50
+ },
51
+ starter: {
52
+ cli: {
53
+ global: { keyRequestsPerMinute: 240, orgRequestsPerMinute: 600 },
54
+ tenantRead: { requestsPerMinute: 120, orgUnits: { limit: 25_000_000, windowSeconds: DAY } },
55
+ tenantWrite: { requestsPerMinute: 120, orgUnits: { limit: 5_000_000, windowSeconds: DAY } },
56
+ bulkImport: { requestsPerMinute: 30, orgRequests: { limit: 500, windowSeconds: HOUR } },
57
+ aiLive: { requestsPerMinute: 60, orgRequests: { limit: 5_000, windowSeconds: HOUR } },
58
+ toolLive: { requestsPerMinute: 60, orgRequests: { limit: 5_000, windowSeconds: HOUR } },
59
+ toolDryRun: { requestsPerMinute: 120, orgRequests: { limit: 2_000, windowSeconds: HOUR } },
60
+ tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
61
+ maxWriteRowsPerRequest: 50_000,
62
+ },
63
+ web: {
64
+ tenantRead: { requestsPerMinute: 300, orgUnits: { limit: 20_000_000, windowSeconds: DAY } },
65
+ tenantWrite: { requestsPerMinute: 180, orgUnits: { limit: 10_000_000, windowSeconds: DAY } },
66
+ columnRun: { requestsPerMinute: 120, orgUnits: { limit: 500_000, windowSeconds: DAY } },
67
+ import: { requestsPerMinute: 30, orgRequests: { limit: 500, windowSeconds: HOUR } },
68
+ },
69
+ import: {
70
+ maxRowsPerFile: 1_000_000,
71
+ maxFileBytes: 250 * MIB,
72
+ maxDirectCsvBodyBytes: 10_000_000,
73
+ },
74
+ agents: {
75
+ maxTotalCredits: 10_000,
76
+ maxInferenceCredits: 5_000,
77
+ maxUpstreamCostUsd: 10,
78
+ maxUpstreamCostUsdByok: 250,
79
+ },
80
+ copilot: { maxSessionBudgetCredits: 5_000, defaultPerTurnCreditCeiling: 1_500 },
81
+ signals: { maxEvents: 200, maxWindowDays: 90 },
82
+ tableActions: { maxActionsPerRun: 25 },
83
+ },
84
+ pro: {
85
+ cli: {
86
+ global: { keyRequestsPerMinute: 240, orgRequestsPerMinute: 1_200 },
87
+ tenantRead: { requestsPerMinute: 240, orgUnits: { limit: 50_000_000, windowSeconds: DAY } },
88
+ tenantWrite: { requestsPerMinute: 240, orgUnits: { limit: 10_000_000, windowSeconds: DAY } },
89
+ bulkImport: { requestsPerMinute: 60, orgRequests: { limit: 1_000, windowSeconds: HOUR } },
90
+ aiLive: { requestsPerMinute: 120, orgRequests: { limit: 12_000, windowSeconds: HOUR } },
91
+ toolLive: { requestsPerMinute: 120, orgRequests: { limit: 12_000, windowSeconds: HOUR } },
92
+ toolDryRun: { requestsPerMinute: 120, orgRequests: { limit: 2_000, windowSeconds: HOUR } },
93
+ tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
94
+ maxWriteRowsPerRequest: 50_000,
95
+ },
96
+ web: {
97
+ tenantRead: { requestsPerMinute: 600, orgUnits: { limit: 40_000_000, windowSeconds: DAY } },
98
+ tenantWrite: { requestsPerMinute: 360, orgUnits: { limit: 20_000_000, windowSeconds: DAY } },
99
+ columnRun: { requestsPerMinute: 240, orgUnits: { limit: 1_000_000, windowSeconds: DAY } },
100
+ import: { requestsPerMinute: 60, orgRequests: { limit: 1_000, windowSeconds: HOUR } },
101
+ },
102
+ import: {
103
+ maxRowsPerFile: 1_000_000,
104
+ maxFileBytes: 250 * MIB,
105
+ maxDirectCsvBodyBytes: 10_000_000,
106
+ },
107
+ agents: {
108
+ maxTotalCredits: 25_000,
109
+ maxInferenceCredits: 12_500,
110
+ maxUpstreamCostUsd: 25,
111
+ maxUpstreamCostUsdByok: 250,
112
+ },
113
+ copilot: { maxSessionBudgetCredits: 10_000, defaultPerTurnCreditCeiling: 2_500 },
114
+ signals: { maxEvents: 200, maxWindowDays: 180 },
115
+ tableActions: { maxActionsPerRun: 25 },
116
+ },
117
+ team: {
118
+ cli: {
119
+ global: { keyRequestsPerMinute: 240, orgRequestsPerMinute: 2_400 },
120
+ tenantRead: { requestsPerMinute: 480, orgUnits: { limit: 100_000_000, windowSeconds: DAY } },
121
+ tenantWrite: { requestsPerMinute: 480, orgUnits: { limit: 25_000_000, windowSeconds: DAY } },
122
+ bulkImport: { requestsPerMinute: 120, orgRequests: { limit: 2_000, windowSeconds: HOUR } },
123
+ aiLive: { requestsPerMinute: 240, orgRequests: { limit: 30_000, windowSeconds: HOUR } },
124
+ toolLive: { requestsPerMinute: 240, orgRequests: { limit: 30_000, windowSeconds: HOUR } },
125
+ toolDryRun: { requestsPerMinute: 120, orgRequests: { limit: 2_000, windowSeconds: HOUR } },
126
+ tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
127
+ maxWriteRowsPerRequest: 50_000,
128
+ },
129
+ web: {
130
+ tenantRead: { requestsPerMinute: 1_200, orgUnits: { limit: 100_000_000, windowSeconds: DAY } },
131
+ tenantWrite: { requestsPerMinute: 720, orgUnits: { limit: 50_000_000, windowSeconds: DAY } },
132
+ columnRun: { requestsPerMinute: 480, orgUnits: { limit: 2_500_000, windowSeconds: DAY } },
133
+ import: { requestsPerMinute: 120, orgRequests: { limit: 2_000, windowSeconds: HOUR } },
134
+ },
135
+ import: {
136
+ maxRowsPerFile: 1_000_000,
137
+ maxFileBytes: 250 * MIB,
138
+ maxDirectCsvBodyBytes: 10_000_000,
139
+ },
140
+ agents: {
141
+ maxTotalCredits: 50_000,
142
+ maxInferenceCredits: 25_000,
143
+ maxUpstreamCostUsd: 50,
144
+ maxUpstreamCostUsdByok: 250,
145
+ },
146
+ copilot: { maxSessionBudgetCredits: 20_000, defaultPerTurnCreditCeiling: 5_000 },
147
+ signals: { maxEvents: 200, maxWindowDays: 365 },
148
+ tableActions: { maxActionsPerRun: 25 },
149
+ },
150
+ scale: {
151
+ cli: {
152
+ global: { keyRequestsPerMinute: 240, orgRequestsPerMinute: 6_000 },
153
+ tenantRead: { requestsPerMinute: 1_000, orgUnits: { limit: 500_000_000, windowSeconds: DAY } },
154
+ tenantWrite: { requestsPerMinute: 1_000, orgUnits: { limit: 100_000_000, windowSeconds: DAY } },
155
+ bulkImport: { requestsPerMinute: 240, orgRequests: { limit: 5_000, windowSeconds: HOUR } },
156
+ aiLive: { requestsPerMinute: 600, orgRequests: { limit: 100_000, windowSeconds: HOUR } },
157
+ toolLive: { requestsPerMinute: 600, orgRequests: { limit: 100_000, windowSeconds: HOUR } },
158
+ toolDryRun: { requestsPerMinute: 120, orgRequests: { limit: 2_000, windowSeconds: HOUR } },
159
+ tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
160
+ maxWriteRowsPerRequest: 50_000,
161
+ },
162
+ web: {
163
+ tenantRead: { requestsPerMinute: 2_000, orgUnits: { limit: 400_000_000, windowSeconds: DAY } },
164
+ tenantWrite: { requestsPerMinute: 1_500, orgUnits: { limit: 200_000_000, windowSeconds: DAY } },
165
+ columnRun: { requestsPerMinute: 1_000, orgUnits: { limit: 10_000_000, windowSeconds: DAY } },
166
+ import: { requestsPerMinute: 240, orgRequests: { limit: 5_000, windowSeconds: HOUR } },
167
+ },
168
+ import: {
169
+ maxRowsPerFile: 1_000_000,
170
+ maxFileBytes: 250 * MIB,
171
+ maxDirectCsvBodyBytes: 10_000_000,
172
+ },
173
+ agents: {
174
+ maxTotalCredits: 100_000,
175
+ maxInferenceCredits: 50_000,
176
+ maxUpstreamCostUsd: 100,
177
+ maxUpstreamCostUsdByok: 250,
178
+ },
179
+ copilot: { maxSessionBudgetCredits: 50_000, defaultPerTurnCreditCeiling: 10_000 },
180
+ signals: { maxEvents: 200, maxWindowDays: 365 },
181
+ tableActions: { maxActionsPerRun: 25 },
182
+ },
183
+ };
184
+ /**
185
+ * Map a raw plan-tier string (subscription `tier`, metadata tier, legacy plan
186
+ * key like `growth_250`) onto its enforcement rung. Unknown/absent tiers land
187
+ * on the unentitled "free" rung; enterprise shares "scale".
188
+ */
189
+ export function limitsTierForPlanTier(tier) {
190
+ const base = resolveBasePricingPlan(tier)?.tier;
191
+ if (!base || base === "free")
192
+ return "free";
193
+ if (base === "enterprise")
194
+ return "scale";
195
+ return base;
196
+ }
197
+ export function planLimitsForTier(tier) {
198
+ return PLAN_LIMITS[tier];
199
+ }
@@ -26,43 +26,109 @@ export declare const AI_COLUMN_CREDITS: {
26
26
  readonly medium: 75;
27
27
  readonly high: 250;
28
28
  };
29
- export declare const AI_COLUMN_WEB_SEARCH_SURCHARGE_CREDITS = 25;
29
+ /**
30
+ * Web-search grounding, billed per SEARCH on top of the model — not a flat adder.
31
+ *
32
+ * This replaces `AI_COLUMN_WEB_SEARCH_SURCHARGE_CREDITS = 25`, which was a real
33
+ * under-quote on a public pricing surface: it was a leftover from the bundled
34
+ * `*_with_web_search` model tiers that were removed when grounding moved onto
35
+ * native providers, and the billing path never read it. Actual customer price is
36
+ * the managed provider's own per-search charge (cogs-rates.ts): exa 35, parallel
37
+ * 5, firecrawl 80 at the default 5 results. The default column runs exa primary
38
+ * with parallel as its one fallback (WEB_SEARCH_ENGINES), so a row costs 35 when
39
+ * the primary answers and reserves 40 for the case where both lanes fire.
40
+ *
41
+ * LITERAL ON PURPOSE, like PRICING_CREDITS_PER_USD above: this module ships to the
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.
46
+ */
47
+ export declare const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS = 35;
48
+ export declare const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 40;
30
49
  /** Workflow/automation actions (steps, tool calls, row writes) — capacity guard. */
31
50
  export declare const AUTOMATION_ACTION_CREDITS = 0.01;
32
51
  /**
33
- * Managed email inboxes: dynamic vendor COGS × 1.25 per mailbox per month.
34
- * The representative range reflects the current InboxKit rate card (incl. its
35
- * native warmup network); the exact quote comes from the live rate card at
36
- * order time.
52
+ * Managed email inboxes: founder-ratified flat price (2026-07-25), superseding
53
+ * the earlier dynamic vendor-COGS × 1.25 range (InboxKit $2.48–3.99 Google /
54
+ * flat $5 Microsoft rate card, ×1.25 → 3,100–6,250 cr). The Oxygen-sold managed
55
+ * mailbox line is now a flat $3.00/month (3,000 credits) regardless of vendor
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.
37
59
  */
38
60
  export declare const MANAGED_INBOX_MARKUP = 1.25;
39
61
  export declare const MANAGED_INBOX_CREDITS_PER_MONTH: {
40
- readonly min: 3100;
41
- readonly typical: 3750;
42
- readonly max: 5000;
62
+ readonly min: 3000;
63
+ readonly typical: 3000;
64
+ readonly max: 3000;
43
65
  };
66
+ /**
67
+ * VOICE (the call channel). Marked up 5×, not the 1.25× infra rule the inbox and
68
+ * domain rails use: a phone number carries ongoing reputation work (warm-up,
69
+ * rotation, cap enforcement, health) that a mailbox rail does not, and the
70
+ * per-minute rate is small enough that a 1.25× markup would not cover it.
71
+ *
72
+ * A browser-softphone call bills TWO Twilio legs, which is easy to miss:
73
+ * browser/app (the rep's WebRTC leg) $0.0040 / min
74
+ * outbound to a US local/mobile $0.0140 / min
75
+ * ─────────────
76
+ * $0.0180 / min
77
+ * Costing only the outbound leg undercharges every call by 29%.
78
+ */
79
+ 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
+ export declare const VOICE_NUMBER_CREDITS_PER_MONTH = 5000;
86
+ /** Both legs, $0.018/min × 5 → $0.09/min. */
87
+ 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
+ export declare const VOICE_CREDITS_PER_AMD_CALL = 38;
44
90
  /** Managed domains: registrar at-cost × 1.25 (≈ a $10.44 .com → ~13,050 credits/yr). */
45
91
  export declare const MANAGED_DOMAIN_MARKUP = 1.25;
46
92
  export declare const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13050;
47
93
  /**
48
- * LinkedIn accounts (2026-07-14 decision): flat monthly connection fee per
49
- * connected account plus per-action charges. Sends on email/WhatsApp stay 0.
94
+ * LinkedIn accounts: founder decision (2026-07-25) — a PURE seat model. The
95
+ * flat monthly connection fee per connected account is now the WHOLE LinkedIn
96
+ * price (10,000 credits, up from the 7,000-credit 2026-07-14 Pricing Model 2.0
97
+ * figure); every per-action charge below is 0. Per-MESSAGE sends on email and
98
+ * WhatsApp stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
99
+ * connection fee, see WHATSAPP_ACCOUNT_CREDITS_PER_MONTH.
50
100
  */
51
- export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 7000;
101
+ export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 10000;
52
102
  export declare const LINKEDIN_ACTION_CREDITS: {
53
- readonly visit_profile: 1;
54
- readonly invite: 4;
55
- readonly message: 2;
56
- readonly inmail: 4;
57
- readonly follow: 1;
58
- readonly like_post: 2;
59
- readonly comment_post: 6;
103
+ readonly visit_profile: 0;
104
+ readonly invite: 0;
105
+ readonly message: 0;
106
+ readonly inmail: 0;
107
+ readonly follow: 0;
108
+ readonly like_post: 0;
109
+ readonly comment_post: 0;
60
110
  };
61
- /** Editable calculator default: a warmed account's typical monthly action mix. */
62
- export declare const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 1500;
111
+ /**
112
+ * Editable calculator default: a warmed account's typical monthly action mix.
113
+ * 0 under the pure seat model (2026-07-25) — actions no longer add to the
114
+ * LinkedIn line regardless of volume, so this default carries no credits.
115
+ * Kept (not deleted) because PRICING_CALCULATOR_DEFAULTS.linkedinActionCreditsPerAccount
116
+ * still reads it as its default value.
117
+ */
118
+ export declare const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
119
+ /**
120
+ * WhatsApp numbers: flat monthly connection fee per connected number, the same
121
+ * seat shape as LinkedIn ($10 × 1,000 credits/$). Billed off the rolling-30d peak,
122
+ * so a number connected part-way through a month still bills the full cycle.
123
+ * WhatsApp message sends themselves remain 0 credits.
124
+ */
125
+ export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 10000;
63
126
  /** Dedicated egress IP add-on. */
64
- export declare const EGRESS_IP_CREDITS_PER_MONTH = 400000;
65
- /** Email + WhatsApp sends cost nothing — the pool pays for inboxes, not sends. */
127
+ export declare const EGRESS_IP_CREDITS_PER_MONTH = 15000;
128
+ /**
129
+ * Email + WhatsApp sends cost nothing per message — the pool pays for inboxes and
130
+ * connected accounts, not for sends.
131
+ */
66
132
  export declare const SEND_CREDITS = 0;
67
133
  /**
68
134
  * Representative enrichment prices (5× provider COGS via the resolver; the
@@ -70,7 +136,7 @@ export declare const SEND_CREDITS = 0;
70
136
  * "typical" = the cheap-first waterfall's common case, used by the calculator.
71
137
  */
72
138
  export declare const ENRICHMENT_CREDITS: {
73
- readonly email_verify: 2;
139
+ readonly email_verify: 2.245;
74
140
  readonly email_find_typical: 85;
75
141
  readonly phone_find_typical: 990;
76
142
  readonly company_enrich_typical: 99;
@@ -22,41 +22,105 @@ export const TOPUP_USD_PER_1K = 1.25;
22
22
  export const SUBSCRIPTION_USD_PER_1K = 1.0;
23
23
  /** AI column runs, honest 5× of modeled tier COGS. */
24
24
  export const AI_COLUMN_CREDITS = { low: 15, medium: 75, high: 250 };
25
- export const AI_COLUMN_WEB_SEARCH_SURCHARGE_CREDITS = 25;
25
+ /**
26
+ * Web-search grounding, billed per SEARCH on top of the model — not a flat adder.
27
+ *
28
+ * This replaces `AI_COLUMN_WEB_SEARCH_SURCHARGE_CREDITS = 25`, which was a real
29
+ * under-quote on a public pricing surface: it was a leftover from the bundled
30
+ * `*_with_web_search` model tiers that were removed when grounding moved onto
31
+ * native providers, and the billing path never read it. Actual customer price is
32
+ * the managed provider's own per-search charge (cogs-rates.ts): exa 35, parallel
33
+ * 5, firecrawl 80 at the default 5 results. The default column runs exa primary
34
+ * with parallel as its one fallback (WEB_SEARCH_ENGINES), so a row costs 35 when
35
+ * the primary answers and reserves 40 for the case where both lanes fire.
36
+ *
37
+ * LITERAL ON PURPOSE, like PRICING_CREDITS_PER_USD above: this module ships to the
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.
42
+ */
43
+ export const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS = 35;
44
+ export const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 40;
26
45
  /** Workflow/automation actions (steps, tool calls, row writes) — capacity guard. */
27
46
  export const AUTOMATION_ACTION_CREDITS = 0.01;
28
47
  /**
29
- * Managed email inboxes: dynamic vendor COGS × 1.25 per mailbox per month.
30
- * The representative range reflects the current InboxKit rate card (incl. its
31
- * native warmup network); the exact quote comes from the live rate card at
32
- * order time.
48
+ * Managed email inboxes: founder-ratified flat price (2026-07-25), superseding
49
+ * the earlier dynamic vendor-COGS × 1.25 range (InboxKit $2.48–3.99 Google /
50
+ * flat $5 Microsoft rate card, ×1.25 → 3,100–6,250 cr). The Oxygen-sold managed
51
+ * mailbox line is now a flat $3.00/month (3,000 credits) regardless of vendor
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.
33
55
  */
34
56
  export const MANAGED_INBOX_MARKUP = 1.25;
35
- // Range reflects the live InboxKit rate card: Google mailboxes $2.48–3.99 by
36
- // plan tier (×1.25 → 3,100–4,990 cr), Microsoft/Azure flat $5 (×1.25 → 6,250).
37
- export const MANAGED_INBOX_CREDITS_PER_MONTH = { min: 3_100, typical: 3_750, max: 5_000 };
57
+ export const MANAGED_INBOX_CREDITS_PER_MONTH = { min: 3_000, typical: 3_000, max: 3_000 };
58
+ /**
59
+ * VOICE (the call channel). Marked up 5×, not the 1.25× infra rule the inbox and
60
+ * domain rails use: a phone number carries ongoing reputation work (warm-up,
61
+ * rotation, cap enforcement, health) that a mailbox rail does not, and the
62
+ * per-minute rate is small enough that a 1.25× markup would not cover it.
63
+ *
64
+ * A browser-softphone call bills TWO Twilio legs, which is easy to miss:
65
+ * browser/app (the rep's WebRTC leg) $0.0040 / min
66
+ * outbound to a US local/mobile $0.0140 / min
67
+ * ─────────────
68
+ * $0.0180 / min
69
+ * Costing only the outbound leg undercharges every call by 29%.
70
+ */
71
+ export const VOICE_MARKUP = 5;
72
+ /**
73
+ * Flat $5.00/mo per number (founder decision 2026-07-26). Twilio's US/CA local
74
+ * DID costs $1.15, so this is ~4.3× — priced as a round number rather than a
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;
38
82
  /** Managed domains: registrar at-cost × 1.25 (≈ a $10.44 .com → ~13,050 credits/yr). */
39
83
  export const MANAGED_DOMAIN_MARKUP = 1.25;
40
84
  export const MANAGED_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 13_050;
41
85
  /**
42
- * LinkedIn accounts (2026-07-14 decision): flat monthly connection fee per
43
- * connected account plus per-action charges. Sends on email/WhatsApp stay 0.
86
+ * LinkedIn accounts: founder decision (2026-07-25) — a PURE seat model. The
87
+ * flat monthly connection fee per connected account is now the WHOLE LinkedIn
88
+ * price (10,000 credits, up from the 7,000-credit 2026-07-14 Pricing Model 2.0
89
+ * figure); every per-action charge below is 0. Per-MESSAGE sends on email and
90
+ * WhatsApp stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
91
+ * connection fee, see WHATSAPP_ACCOUNT_CREDITS_PER_MONTH.
44
92
  */
45
- export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 7_000;
93
+ export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 10_000;
46
94
  export const LINKEDIN_ACTION_CREDITS = {
47
- visit_profile: 1,
48
- invite: 4,
49
- message: 2,
50
- inmail: 4,
51
- follow: 1,
52
- like_post: 2,
53
- comment_post: 6,
95
+ visit_profile: 0,
96
+ invite: 0,
97
+ message: 0,
98
+ inmail: 0,
99
+ follow: 0,
100
+ like_post: 0,
101
+ comment_post: 0,
54
102
  };
55
- /** Editable calculator default: a warmed account's typical monthly action mix. */
56
- export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 1_500;
103
+ /**
104
+ * Editable calculator default: a warmed account's typical monthly action mix.
105
+ * 0 under the pure seat model (2026-07-25) — actions no longer add to the
106
+ * LinkedIn line regardless of volume, so this default carries no credits.
107
+ * Kept (not deleted) because PRICING_CALCULATOR_DEFAULTS.linkedinActionCreditsPerAccount
108
+ * still reads it as its default value.
109
+ */
110
+ export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
111
+ /**
112
+ * WhatsApp numbers: flat monthly connection fee per connected number, the same
113
+ * seat shape as LinkedIn ($10 × 1,000 credits/$). Billed off the rolling-30d peak,
114
+ * so a number connected part-way through a month still bills the full cycle.
115
+ * WhatsApp message sends themselves remain 0 credits.
116
+ */
117
+ export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 10_000;
57
118
  /** Dedicated egress IP add-on. */
58
- export const EGRESS_IP_CREDITS_PER_MONTH = 400_000;
59
- /** Email + WhatsApp sends cost nothing — the pool pays for inboxes, not sends. */
119
+ export const EGRESS_IP_CREDITS_PER_MONTH = 15_000;
120
+ /**
121
+ * Email + WhatsApp sends cost nothing per message — the pool pays for inboxes and
122
+ * connected accounts, not for sends.
123
+ */
60
124
  export const SEND_CREDITS = 0;
61
125
  /**
62
126
  * Representative enrichment prices (5× provider COGS via the resolver; the
@@ -64,8 +128,8 @@ export const SEND_CREDITS = 0;
64
128
  * "typical" = the cheap-first waterfall's common case, used by the calculator.
65
129
  */
66
130
  export const ENRICHMENT_CREDITS = {
67
- email_verify: 2, // MillionVerifier first pass
68
- email_find_typical: 85, // Hunter-class finder; cheap waterfall steps run 10–99
131
+ email_verify: 2.245, // MillionVerifier first pass (exactly 5x COGS)
132
+ email_find_typical: 85, // Hunter-class finder; cheap waterfall steps run 15–99
69
133
  phone_find_typical: 990, // Prospeo/Findymail-class mobile
70
134
  company_enrich_typical: 99,
71
135
  web_search: 5, // Serper