@oxygen-agent/cli 1.1010.650 → 1.1010.721
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 +1 -1
- package/dist/inbox-needs-reply-notice.d.ts +12 -0
- package/dist/inbox-needs-reply-notice.js +51 -0
- package/dist/index.js +186 -45
- package/dist/skills.js +48 -22
- package/node_modules/@oxygen/shared/dist/billing-anchors.d.ts +33 -2
- package/node_modules/@oxygen/shared/dist/billing-anchors.js +67 -2
- package/node_modules/@oxygen/shared/dist/billing.d.ts +63 -9
- package/node_modules/@oxygen/shared/dist/billing.js +96 -14
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +11 -1
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +4 -4
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +4 -4
- package/node_modules/@oxygen/shared/dist/email-hard-bounce.d.ts +25 -0
- package/node_modules/@oxygen/shared/dist/email-hard-bounce.js +27 -0
- package/node_modules/@oxygen/shared/dist/feature-gates.d.ts +6 -1
- package/node_modules/@oxygen/shared/dist/feature-gates.js +7 -1
- package/node_modules/@oxygen/shared/dist/index.d.ts +2 -1
- package/node_modules/@oxygen/shared/dist/index.js +2 -1
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +114 -0
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +150 -0
- package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +19 -2
- package/node_modules/@oxygen/shared/dist/plan-band.d.ts +118 -0
- package/node_modules/@oxygen/shared/dist/plan-band.js +147 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +131 -120
- package/node_modules/@oxygen/shared/dist/plan-limits.js +80 -71
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +79 -14
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +61 -12
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +4 -3
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +9 -3
- package/node_modules/@oxygen/shared/dist/process-resource.d.ts +4 -0
- package/node_modules/@oxygen/shared/dist/process-resource.js +25 -0
- package/node_modules/@oxygen/shared/dist/repricing.d.ts +130 -0
- package/node_modules/@oxygen/shared/dist/repricing.js +320 -0
- package/node_modules/@oxygen/shared/dist/sending-limits.d.ts +32 -0
- package/node_modules/@oxygen/shared/dist/sending-limits.js +49 -0
- package/node_modules/@oxygen/shared/dist/sequence-failures.js +4 -1
- package/node_modules/@oxygen/shared/dist/stripe-price-catalog.d.ts +24 -0
- package/node_modules/@oxygen/shared/dist/stripe-price-catalog.js +58 -1
- package/node_modules/@oxygen/shared/dist/table-capacity.d.ts +39 -10
- package/node_modules/@oxygen/shared/dist/table-capacity.js +68 -4
- package/node_modules/@oxygen/shared/dist/telemetry.d.ts +9 -0
- package/node_modules/@oxygen/shared/dist/telemetry.js +36 -2
- package/node_modules/@oxygen/shared/dist/trace-context.d.ts +29 -0
- package/node_modules/@oxygen/shared/dist/trace-context.js +88 -0
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
- package/package.json +1 -1
- package/node_modules/@oxygen/shared/dist/email-warmup-readiness.d.ts +0 -64
- package/node_modules/@oxygen/shared/dist/email-warmup-readiness.js +0 -90
|
@@ -11,10 +11,12 @@ const HOUR = 60 * 60;
|
|
|
11
11
|
const DAY = 24 * HOUR;
|
|
12
12
|
const MIB = 1024 * 1024;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* The per-rung Table import ceiling this matrix reports: today's envelope. The
|
|
15
|
+
* ceiling ENFORCED on an import is the workspace's plan-band rows-per-Table
|
|
16
|
+
* limit (`resolveWorkspaceTableCapacity`, PROPOSED P-60: a file can fill an
|
|
17
|
+
* empty Table exactly), which the web import paths resolve per organization.
|
|
18
|
+
* Imports into a non-empty Table remain subject to that Table's remaining
|
|
19
|
+
* capacity and the workspace-wide envelope.
|
|
18
20
|
*/
|
|
19
21
|
export const TABLE_IMPORT_ROW_LIMIT = WORKSPACE_TABLE_CAPACITY.tableRowLimit;
|
|
20
22
|
// The platform request-body ceiling belongs to the same question as the import
|
|
@@ -33,38 +35,46 @@ export const MAX_CLI_JSON_BODY_BYTES = 2_000_000;
|
|
|
33
35
|
* The per-rung limit matrix. `ai_live` deliberately equals `tool_live` at every
|
|
34
36
|
* rung — one "live actions" mental model; the per-call cost asymmetry between
|
|
35
37
|
* AI and tool calls is priced in credits, not throttled here.
|
|
38
|
+
*
|
|
39
|
+
* API rates follow the 2026-09 repricing (decision L2, ratified 2026-09-26):
|
|
40
|
+
* `cli.global` is the per-organization and per-key request total per minute,
|
|
41
|
+
* 1,200 / 3,000 / 6,000 / 12,000 / 30,000 from free to scale. The per-operation
|
|
42
|
+
* buckets below are PROPOSED (P-52, repricing spec § 4.2): each pre-repricing
|
|
43
|
+
* bucket multiplied by its rung's organization factor, 2x on free and 5x on
|
|
44
|
+
* every paid rung, and never above the rung's per-key total. `tenantSchema` and
|
|
45
|
+
* the flat `tenant_admin` guard in the web rate limiter are DDL abuse guards and
|
|
46
|
+
* stay unscaled.
|
|
36
47
|
*/
|
|
37
48
|
export const PLAN_LIMITS = {
|
|
38
49
|
free: {
|
|
39
50
|
cli: {
|
|
40
|
-
global: { keyRequestsPerMinute:
|
|
41
|
-
tenantRead: { requestsPerMinute:
|
|
42
|
-
tenantWrite: { requestsPerMinute:
|
|
43
|
-
bulkImport: { requestsPerMinute:
|
|
44
|
-
aiLive: { requestsPerMinute:
|
|
45
|
-
toolLive: { requestsPerMinute:
|
|
46
|
-
toolDryRun: { requestsPerMinute:
|
|
51
|
+
global: { keyRequestsPerMinute: 1_200, orgRequestsPerMinute: 1_200 },
|
|
52
|
+
tenantRead: { requestsPerMinute: 120, orgUnits: { limit: 1_000_000, windowSeconds: HOUR } },
|
|
53
|
+
tenantWrite: { requestsPerMinute: 60, orgUnits: { limit: 200_000, windowSeconds: HOUR } },
|
|
54
|
+
bulkImport: { requestsPerMinute: 20, orgRequests: { limit: 200, windowSeconds: HOUR } },
|
|
55
|
+
aiLive: { requestsPerMinute: 40, orgRequests: { limit: 200, windowSeconds: HOUR } },
|
|
56
|
+
toolLive: { requestsPerMinute: 40, orgRequests: { limit: 200, windowSeconds: HOUR } },
|
|
57
|
+
toolDryRun: { requestsPerMinute: 120, orgRequests: { limit: 1_000, windowSeconds: HOUR } },
|
|
47
58
|
tenantSchema: { requestsPerMinute: 20, orgRequests: { limit: 100, windowSeconds: HOUR } },
|
|
48
59
|
maxWriteRowsPerRequest: 5_000,
|
|
49
60
|
},
|
|
50
61
|
web: {
|
|
51
|
-
tenantRead: { requestsPerMinute:
|
|
52
|
-
tenantWrite: { requestsPerMinute:
|
|
53
|
-
columnRun: { requestsPerMinute:
|
|
54
|
-
import: { requestsPerMinute:
|
|
62
|
+
tenantRead: { requestsPerMinute: 240, orgUnits: { limit: 2_000_000, windowSeconds: HOUR } },
|
|
63
|
+
tenantWrite: { requestsPerMinute: 120, orgUnits: { limit: 1_000_000, windowSeconds: HOUR } },
|
|
64
|
+
columnRun: { requestsPerMinute: 60, orgUnits: { limit: 4_000, windowSeconds: HOUR } },
|
|
65
|
+
import: { requestsPerMinute: 20, orgRequests: { limit: 200, windowSeconds: HOUR } },
|
|
55
66
|
},
|
|
56
67
|
import: {
|
|
57
68
|
maxRowsPerFile: TABLE_IMPORT_ROW_LIMIT,
|
|
58
69
|
maxFileBytes: 100 * MIB,
|
|
59
70
|
maxDirectCsvBodyBytes: 10_000_000,
|
|
60
71
|
},
|
|
61
|
-
// Sized against the free tier's actual funding (OXP-10.2.4, 2026-08-17):
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
// the whole signup grant before the customer saw anything work.
|
|
72
|
+
// Sized against the free tier's actual funding (OXP-10.2.4, 2026-08-17): one
|
|
73
|
+
// signup grant of FREE_SIGNUP_GRANT_CREDITS (1,000) with no monthly allowance
|
|
74
|
+
// to refill it. The previous ceilings were written when `free` meant a
|
|
75
|
+
// churned org that could spend nothing, so they were harmless at any value;
|
|
76
|
+
// an Agent run capped at the old 1,000 (today's unit) could consume the
|
|
77
|
+
// ENTIRE lifetime grant before the customer saw anything work.
|
|
68
78
|
//
|
|
69
79
|
// These are runaway guards, not the billing meter — a workspace that tops up
|
|
70
80
|
// is bounded by its balance, not by these. The intent is only that no single
|
|
@@ -75,32 +85,31 @@ export const PLAN_LIMITS = {
|
|
|
75
85
|
maxUpstreamCostUsd: 10,
|
|
76
86
|
maxUpstreamCostUsdByok: 10,
|
|
77
87
|
},
|
|
78
|
-
// Left at 5,000/1,500
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
// split grant exists to prevent.
|
|
88
|
+
// Left at 500/150 deliberately (5,000/1,500 before the 2026-09-19 unit
|
|
89
|
+
// change). A founder who picks the in-product path over the CLI must be able
|
|
90
|
+
// to complete one real Copilot session on the 1,000-credit signup grant
|
|
91
|
+
// alone. Lowering this would re-create a dead-on-arrival Copilot.
|
|
83
92
|
copilot: { maxSessionBudgetCredits: 500, defaultPerTurnCreditCeiling: 150 },
|
|
84
93
|
signals: { maxEvents: 100, maxWindowDays: 30 },
|
|
85
94
|
tableActions: { maxActionsPerRun: 10 },
|
|
86
95
|
},
|
|
87
96
|
starter: {
|
|
88
97
|
cli: {
|
|
89
|
-
global: { keyRequestsPerMinute:
|
|
90
|
-
tenantRead: { requestsPerMinute:
|
|
91
|
-
tenantWrite: { requestsPerMinute:
|
|
92
|
-
bulkImport: { requestsPerMinute:
|
|
93
|
-
aiLive: { requestsPerMinute:
|
|
94
|
-
toolLive: { requestsPerMinute:
|
|
95
|
-
toolDryRun: { requestsPerMinute:
|
|
98
|
+
global: { keyRequestsPerMinute: 3_000, orgRequestsPerMinute: 3_000 },
|
|
99
|
+
tenantRead: { requestsPerMinute: 600, orgUnits: { limit: 125_000_000, windowSeconds: DAY } },
|
|
100
|
+
tenantWrite: { requestsPerMinute: 600, orgUnits: { limit: 25_000_000, windowSeconds: DAY } },
|
|
101
|
+
bulkImport: { requestsPerMinute: 150, orgRequests: { limit: 2_500, windowSeconds: HOUR } },
|
|
102
|
+
aiLive: { requestsPerMinute: 300, orgRequests: { limit: 25_000, windowSeconds: HOUR } },
|
|
103
|
+
toolLive: { requestsPerMinute: 300, orgRequests: { limit: 25_000, windowSeconds: HOUR } },
|
|
104
|
+
toolDryRun: { requestsPerMinute: 600, orgRequests: { limit: 10_000, windowSeconds: HOUR } },
|
|
96
105
|
tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
|
|
97
106
|
maxWriteRowsPerRequest: 50_000,
|
|
98
107
|
},
|
|
99
108
|
web: {
|
|
100
|
-
tenantRead: { requestsPerMinute:
|
|
101
|
-
tenantWrite: { requestsPerMinute:
|
|
102
|
-
columnRun: { requestsPerMinute:
|
|
103
|
-
import: { requestsPerMinute:
|
|
109
|
+
tenantRead: { requestsPerMinute: 1_500, orgUnits: { limit: 100_000_000, windowSeconds: DAY } },
|
|
110
|
+
tenantWrite: { requestsPerMinute: 900, orgUnits: { limit: 50_000_000, windowSeconds: DAY } },
|
|
111
|
+
columnRun: { requestsPerMinute: 600, orgUnits: { limit: 2_500_000, windowSeconds: DAY } },
|
|
112
|
+
import: { requestsPerMinute: 150, orgRequests: { limit: 2_500, windowSeconds: HOUR } },
|
|
104
113
|
},
|
|
105
114
|
import: {
|
|
106
115
|
maxRowsPerFile: TABLE_IMPORT_ROW_LIMIT,
|
|
@@ -119,21 +128,21 @@ export const PLAN_LIMITS = {
|
|
|
119
128
|
},
|
|
120
129
|
pro: {
|
|
121
130
|
cli: {
|
|
122
|
-
global: { keyRequestsPerMinute:
|
|
123
|
-
tenantRead: { requestsPerMinute:
|
|
124
|
-
tenantWrite: { requestsPerMinute:
|
|
125
|
-
bulkImport: { requestsPerMinute:
|
|
126
|
-
aiLive: { requestsPerMinute:
|
|
127
|
-
toolLive: { requestsPerMinute:
|
|
128
|
-
toolDryRun: { requestsPerMinute:
|
|
131
|
+
global: { keyRequestsPerMinute: 6_000, orgRequestsPerMinute: 6_000 },
|
|
132
|
+
tenantRead: { requestsPerMinute: 1_200, orgUnits: { limit: 250_000_000, windowSeconds: DAY } },
|
|
133
|
+
tenantWrite: { requestsPerMinute: 1_200, orgUnits: { limit: 50_000_000, windowSeconds: DAY } },
|
|
134
|
+
bulkImport: { requestsPerMinute: 300, orgRequests: { limit: 5_000, windowSeconds: HOUR } },
|
|
135
|
+
aiLive: { requestsPerMinute: 600, orgRequests: { limit: 60_000, windowSeconds: HOUR } },
|
|
136
|
+
toolLive: { requestsPerMinute: 600, orgRequests: { limit: 60_000, windowSeconds: HOUR } },
|
|
137
|
+
toolDryRun: { requestsPerMinute: 600, orgRequests: { limit: 10_000, windowSeconds: HOUR } },
|
|
129
138
|
tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
|
|
130
139
|
maxWriteRowsPerRequest: 50_000,
|
|
131
140
|
},
|
|
132
141
|
web: {
|
|
133
|
-
tenantRead: { requestsPerMinute:
|
|
134
|
-
tenantWrite: { requestsPerMinute:
|
|
135
|
-
columnRun: { requestsPerMinute:
|
|
136
|
-
import: { requestsPerMinute:
|
|
142
|
+
tenantRead: { requestsPerMinute: 3_000, orgUnits: { limit: 200_000_000, windowSeconds: DAY } },
|
|
143
|
+
tenantWrite: { requestsPerMinute: 1_800, orgUnits: { limit: 100_000_000, windowSeconds: DAY } },
|
|
144
|
+
columnRun: { requestsPerMinute: 1_200, orgUnits: { limit: 5_000_000, windowSeconds: DAY } },
|
|
145
|
+
import: { requestsPerMinute: 300, orgRequests: { limit: 5_000, windowSeconds: HOUR } },
|
|
137
146
|
},
|
|
138
147
|
import: {
|
|
139
148
|
maxRowsPerFile: TABLE_IMPORT_ROW_LIMIT,
|
|
@@ -152,21 +161,21 @@ export const PLAN_LIMITS = {
|
|
|
152
161
|
},
|
|
153
162
|
team: {
|
|
154
163
|
cli: {
|
|
155
|
-
global: { keyRequestsPerMinute:
|
|
156
|
-
tenantRead: { requestsPerMinute:
|
|
157
|
-
tenantWrite: { requestsPerMinute:
|
|
158
|
-
bulkImport: { requestsPerMinute:
|
|
159
|
-
aiLive: { requestsPerMinute:
|
|
160
|
-
toolLive: { requestsPerMinute:
|
|
161
|
-
toolDryRun: { requestsPerMinute:
|
|
164
|
+
global: { keyRequestsPerMinute: 12_000, orgRequestsPerMinute: 12_000 },
|
|
165
|
+
tenantRead: { requestsPerMinute: 2_400, orgUnits: { limit: 500_000_000, windowSeconds: DAY } },
|
|
166
|
+
tenantWrite: { requestsPerMinute: 2_400, orgUnits: { limit: 125_000_000, windowSeconds: DAY } },
|
|
167
|
+
bulkImport: { requestsPerMinute: 600, orgRequests: { limit: 10_000, windowSeconds: HOUR } },
|
|
168
|
+
aiLive: { requestsPerMinute: 1_200, orgRequests: { limit: 150_000, windowSeconds: HOUR } },
|
|
169
|
+
toolLive: { requestsPerMinute: 1_200, orgRequests: { limit: 150_000, windowSeconds: HOUR } },
|
|
170
|
+
toolDryRun: { requestsPerMinute: 600, orgRequests: { limit: 10_000, windowSeconds: HOUR } },
|
|
162
171
|
tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
|
|
163
172
|
maxWriteRowsPerRequest: 50_000,
|
|
164
173
|
},
|
|
165
174
|
web: {
|
|
166
|
-
tenantRead: { requestsPerMinute:
|
|
167
|
-
tenantWrite: { requestsPerMinute:
|
|
168
|
-
columnRun: { requestsPerMinute:
|
|
169
|
-
import: { requestsPerMinute:
|
|
175
|
+
tenantRead: { requestsPerMinute: 6_000, orgUnits: { limit: 500_000_000, windowSeconds: DAY } },
|
|
176
|
+
tenantWrite: { requestsPerMinute: 3_600, orgUnits: { limit: 250_000_000, windowSeconds: DAY } },
|
|
177
|
+
columnRun: { requestsPerMinute: 2_400, orgUnits: { limit: 12_500_000, windowSeconds: DAY } },
|
|
178
|
+
import: { requestsPerMinute: 600, orgRequests: { limit: 10_000, windowSeconds: HOUR } },
|
|
170
179
|
},
|
|
171
180
|
import: {
|
|
172
181
|
maxRowsPerFile: TABLE_IMPORT_ROW_LIMIT,
|
|
@@ -185,21 +194,21 @@ export const PLAN_LIMITS = {
|
|
|
185
194
|
},
|
|
186
195
|
scale: {
|
|
187
196
|
cli: {
|
|
188
|
-
global: { keyRequestsPerMinute:
|
|
189
|
-
tenantRead: { requestsPerMinute:
|
|
190
|
-
tenantWrite: { requestsPerMinute:
|
|
191
|
-
bulkImport: { requestsPerMinute:
|
|
192
|
-
aiLive: { requestsPerMinute:
|
|
193
|
-
toolLive: { requestsPerMinute:
|
|
194
|
-
toolDryRun: { requestsPerMinute:
|
|
197
|
+
global: { keyRequestsPerMinute: 30_000, orgRequestsPerMinute: 30_000 },
|
|
198
|
+
tenantRead: { requestsPerMinute: 5_000, orgUnits: { limit: 2_500_000_000, windowSeconds: DAY } },
|
|
199
|
+
tenantWrite: { requestsPerMinute: 5_000, orgUnits: { limit: 500_000_000, windowSeconds: DAY } },
|
|
200
|
+
bulkImport: { requestsPerMinute: 1_200, orgRequests: { limit: 25_000, windowSeconds: HOUR } },
|
|
201
|
+
aiLive: { requestsPerMinute: 3_000, orgRequests: { limit: 500_000, windowSeconds: HOUR } },
|
|
202
|
+
toolLive: { requestsPerMinute: 3_000, orgRequests: { limit: 500_000, windowSeconds: HOUR } },
|
|
203
|
+
toolDryRun: { requestsPerMinute: 600, orgRequests: { limit: 10_000, windowSeconds: HOUR } },
|
|
195
204
|
tenantSchema: { requestsPerMinute: 60, orgRequests: { limit: 600, windowSeconds: HOUR } },
|
|
196
205
|
maxWriteRowsPerRequest: 50_000,
|
|
197
206
|
},
|
|
198
207
|
web: {
|
|
199
|
-
tenantRead: { requestsPerMinute:
|
|
200
|
-
tenantWrite: { requestsPerMinute:
|
|
201
|
-
columnRun: { requestsPerMinute:
|
|
202
|
-
import: { requestsPerMinute:
|
|
208
|
+
tenantRead: { requestsPerMinute: 10_000, orgUnits: { limit: 2_000_000_000, windowSeconds: DAY } },
|
|
209
|
+
tenantWrite: { requestsPerMinute: 7_500, orgUnits: { limit: 1_000_000_000, windowSeconds: DAY } },
|
|
210
|
+
columnRun: { requestsPerMinute: 5_000, orgUnits: { limit: 50_000_000, windowSeconds: DAY } },
|
|
211
|
+
import: { requestsPerMinute: 1_200, orgRequests: { limit: 25_000, windowSeconds: HOUR } },
|
|
203
212
|
},
|
|
204
213
|
import: {
|
|
205
214
|
maxRowsPerFile: TABLE_IMPORT_ROW_LIMIT,
|
|
@@ -72,19 +72,73 @@ export declare const AI_COLUMN_CREDITS: {
|
|
|
72
72
|
* never read.
|
|
73
73
|
*
|
|
74
74
|
* The figures below describe the DEFAULT research column, which since D53 discovers
|
|
75
|
-
* then reads: `serper.search` (0.5) finds the URLs, then
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* grounded on the snippets
|
|
75
|
+
* then reads: `serper.search` (0.5) finds the URLs, then an additive read turns the
|
|
76
|
+
* top result's ~160-char SERP teaser into real page text. The read tries OXYGEN's
|
|
77
|
+
* own `web.page_fetch` (0.1) first and `exa.contents` (0.5) only when the native
|
|
78
|
+
* fetch cannot read the page. So a typical row spends 0.6 and a preview reserves
|
|
79
|
+
* 4.6: the ceiling covers the `exa.search` fallback (3.5) firing when serper finds
|
|
80
|
+
* nothing plus both read lanes. A read miss leaves the row grounded on the snippets
|
|
81
|
+
* it already has.
|
|
81
82
|
*
|
|
82
83
|
* Both numbers are RESOLVER-DERIVED and pinned by pricing-sheet-conformance.test.ts
|
|
83
84
|
* against the shipped default, so a re-price or a lane change fails a test rather
|
|
84
85
|
* than quietly mispricing this page. Do not hand-edit them.
|
|
85
86
|
*/
|
|
86
|
-
export declare const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS =
|
|
87
|
-
export declare const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 4.
|
|
87
|
+
export declare const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS = 0.6;
|
|
88
|
+
export declare const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 4.6;
|
|
89
|
+
/**
|
|
90
|
+
* Research depth (Claygent parity). `quick` is the single grounded pass priced
|
|
91
|
+
* above (the column's tier price plus AI_COLUMN_WEB_SEARCH_*; 2.1 typical at the
|
|
92
|
+
* Fast tier). A `standard` or `deep` row runs a bounded agent loop — several model
|
|
93
|
+
* turns over a growing evidence list — on a model the DEPTH fixes (standard on the
|
|
94
|
+
* Fast tier, deep on Balanced; the column's own tier applies to quick only), so its
|
|
95
|
+
* model leg is one flat price per row, reserved once:
|
|
96
|
+
*
|
|
97
|
+
* standard: 4.3 + 1.2 tools = 5.5 typical
|
|
98
|
+
* deep: 7.6 + 2.4 tools = 10 typical
|
|
99
|
+
*
|
|
100
|
+
* Founder-ratified 2026-09-26: 30-50% under Clay, >=5x markup. The Clay comparison
|
|
101
|
+
* it was set against: Clay web research bills per row in Data Credits — GPT-5 Nano
|
|
102
|
+
* 0.5 DC, Mini/Flash 1 DC, Claygent Neon 2 DC, Argon 3 DC — at >= $0.05 per DC plus
|
|
103
|
+
* ~$0.01 of action per row; OXYGEN credits are $0.01. Every figure must also keep
|
|
104
|
+
* >= 5x over the loop's modelled COGS. Pinned against the live estimator by
|
|
105
|
+
* @oxygen/integrations pricing-sheet-conformance.test.ts.
|
|
106
|
+
*/
|
|
107
|
+
export declare const RESEARCH_DEPTH_MODEL_CREDITS: {
|
|
108
|
+
readonly standard: 4.3;
|
|
109
|
+
readonly deep: 7.6;
|
|
110
|
+
};
|
|
111
|
+
/** The tier whose model each loop depth runs on, whatever tier the column stores. */
|
|
112
|
+
export declare const RESEARCH_DEPTH_MODEL_TIER: {
|
|
113
|
+
readonly standard: "low";
|
|
114
|
+
readonly deep: "medium";
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* The tool half of a standard/deep row. `typical` is the ratified planning shape —
|
|
118
|
+
* standard: 2 serper searches + 2 native page reads; deep: 3 serper searches + 4
|
|
119
|
+
* native reads + 1 exa.contents fallback read. `reserved` is every budgeted tool
|
|
120
|
+
* call at its dearest lane — each web_search, the row's shared exa.search pool
|
|
121
|
+
* (standard 1, deep 2: the zero-result fallback and semantic_search draw on it),
|
|
122
|
+
* each read's full ladder, deep's one Firecrawl read and site crawls. Deep's
|
|
123
|
+
* company-news call is opt-in (a news lead-lane column) and adds its own price to
|
|
124
|
+
* the reserve only there. Resolver-derived, pinned like the above.
|
|
125
|
+
*/
|
|
126
|
+
export declare const RESEARCH_DEPTH_GROUNDING_CREDITS: {
|
|
127
|
+
readonly standard: {
|
|
128
|
+
readonly typical: 1.2;
|
|
129
|
+
readonly reserved: 7.4;
|
|
130
|
+
};
|
|
131
|
+
readonly deep: {
|
|
132
|
+
readonly typical: 2.4;
|
|
133
|
+
readonly reserved: 19.8;
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
/** Typical per-row totals at each depth's default tier (founder-ratified 2026-09-26). */
|
|
137
|
+
export declare const RESEARCH_DEPTH_TYPICAL_ROW_CREDITS: {
|
|
138
|
+
readonly quick: 2.1;
|
|
139
|
+
readonly standard: 5.5;
|
|
140
|
+
readonly deep: 10;
|
|
141
|
+
};
|
|
88
142
|
/** Workflow/automation actions (steps, tool calls, row writes) — capacity guard. */
|
|
89
143
|
export declare const AUTOMATION_ACTION_CREDITS = 0.001;
|
|
90
144
|
/**
|
|
@@ -113,7 +167,7 @@ export declare const MANAGED_INBOX_CREDITS_PER_MONTH: {
|
|
|
113
167
|
* Costing only the outbound leg undercharges every call by 29%.
|
|
114
168
|
*/
|
|
115
169
|
export declare const VOICE_MARKUP = 5;
|
|
116
|
-
export declare const VOICE_NUMBER_CREDITS_PER_MONTH =
|
|
170
|
+
export declare const VOICE_NUMBER_CREDITS_PER_MONTH = 1000;
|
|
117
171
|
export declare const VOICE_CREDITS_PER_MINUTE = 9;
|
|
118
172
|
export declare const VOICE_CREDITS_PER_AMD_CALL = 3.8;
|
|
119
173
|
/** Managed domains: registrar at-cost × 1.25 (≈ a $10.44 .com → ~13,050 credits/yr). */
|
|
@@ -142,8 +196,12 @@ export declare const PLACEMENT_TEST_OVERAGE_CREDITS = 16.6;
|
|
|
142
196
|
* price; every per-action charge is 0. Per-MESSAGE sends on email and WhatsApp
|
|
143
197
|
* stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
|
|
144
198
|
* connection fee, see WHATSAPP_ACCOUNT_CREDITS_PER_MONTH.
|
|
199
|
+
*
|
|
200
|
+
* The value is the seeded price after the 2026-09 repricing (3,400, decision
|
|
201
|
+
* 2.1). The price in force before its effective-date switch is lower: resolve
|
|
202
|
+
* it with repricedChargeCredits from `@oxygen/shared/repricing` on the server.
|
|
145
203
|
*/
|
|
146
|
-
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH =
|
|
204
|
+
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 3400;
|
|
147
205
|
export declare const LINKEDIN_ACTION_CREDITS: {
|
|
148
206
|
readonly visit_profile: 0;
|
|
149
207
|
readonly invite: 0;
|
|
@@ -156,11 +214,18 @@ export declare const LINKEDIN_ACTION_CREDITS: {
|
|
|
156
214
|
export declare const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
|
|
157
215
|
/**
|
|
158
216
|
* WhatsApp numbers: flat monthly connection fee per connected number, the same
|
|
159
|
-
* seat shape as LinkedIn.
|
|
160
|
-
*
|
|
161
|
-
*
|
|
217
|
+
* seat shape as LinkedIn. WhatsApp message sends themselves remain 0 credits.
|
|
218
|
+
* Seeded at the 2026-09 repricing's price (3,000, decision 2.3); resolve the
|
|
219
|
+
* price in force with repricedChargeCredits.
|
|
220
|
+
*/
|
|
221
|
+
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 3000;
|
|
222
|
+
/**
|
|
223
|
+
* X accounts: monthly credit reservation per connected account (2026-09
|
|
224
|
+
* repricing, decision 2.2). Like the LinkedIn and WhatsApp constants above this
|
|
225
|
+
* is the seeded, post-repricing price; show the price in force with
|
|
226
|
+
* repricedChargeCredits from `@oxygen/shared/repricing`.
|
|
162
227
|
*/
|
|
163
|
-
export declare const
|
|
228
|
+
export declare const X_ACCOUNT_CREDITS_PER_MONTH = 1000;
|
|
164
229
|
/** Dedicated egress IP add-on. */
|
|
165
230
|
export declare const EGRESS_IP_CREDITS_PER_MONTH = 2500;
|
|
166
231
|
/**
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* loadPricingBook() instead of importing this file, so a staff re-price at
|
|
35
35
|
* /admin/costs takes effect without a deploy.
|
|
36
36
|
*/
|
|
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, MANAGED_INBOX_USD_CENTS as SNAPSHOT_MANAGED_INBOX_USD_CENTS, SENDING_DOMAIN_USD_CENTS as SNAPSHOT_SENDING_DOMAIN_USD_CENTS, SENDING_SEAT_USD_CENTS as SNAPSHOT_SENDING_SEAT_USD_CENTS, 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_100 as SNAPSHOT_SUBSCRIPTION_USD_PER_100, TOPUP_USD_PER_100 as SNAPSHOT_TOPUP_USD_PER_100, 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";
|
|
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, MANAGED_INBOX_USD_CENTS as SNAPSHOT_MANAGED_INBOX_USD_CENTS, SENDING_DOMAIN_USD_CENTS as SNAPSHOT_SENDING_DOMAIN_USD_CENTS, SENDING_SEAT_USD_CENTS as SNAPSHOT_SENDING_SEAT_USD_CENTS, 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_100 as SNAPSHOT_SUBSCRIPTION_USD_PER_100, TOPUP_USD_PER_100 as SNAPSHOT_TOPUP_USD_PER_100, 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, X_ACCOUNT_CREDITS_PER_MONTH as SNAPSHOT_X_ACCOUNT_CREDITS_PER_MONTH, } from "./pricing-snapshot.generated.js";
|
|
38
38
|
export { creditsToUsd, usdToCredits } from "./pricing-snapshot.generated.js";
|
|
39
39
|
export const PRICING_SHEET_VERIFIED = SNAPSHOT_PRICE_SHEET_VERIFIED;
|
|
40
40
|
export const PRICING_CREDITS_PER_USD = SNAPSHOT_CREDITS_PER_USD;
|
|
@@ -67,19 +67,57 @@ export const AI_COLUMN_CREDITS = { low: 1.5, medium: 7.5, high: 25 };
|
|
|
67
67
|
* never read.
|
|
68
68
|
*
|
|
69
69
|
* The figures below describe the DEFAULT research column, which since D53 discovers
|
|
70
|
-
* then reads: `serper.search` (0.5) finds the URLs, then
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* grounded on the snippets
|
|
70
|
+
* then reads: `serper.search` (0.5) finds the URLs, then an additive read turns the
|
|
71
|
+
* top result's ~160-char SERP teaser into real page text. The read tries OXYGEN's
|
|
72
|
+
* own `web.page_fetch` (0.1) first and `exa.contents` (0.5) only when the native
|
|
73
|
+
* fetch cannot read the page. So a typical row spends 0.6 and a preview reserves
|
|
74
|
+
* 4.6: the ceiling covers the `exa.search` fallback (3.5) firing when serper finds
|
|
75
|
+
* nothing plus both read lanes. A read miss leaves the row grounded on the snippets
|
|
76
|
+
* it already has.
|
|
76
77
|
*
|
|
77
78
|
* Both numbers are RESOLVER-DERIVED and pinned by pricing-sheet-conformance.test.ts
|
|
78
79
|
* against the shipped default, so a re-price or a lane change fails a test rather
|
|
79
80
|
* than quietly mispricing this page. Do not hand-edit them.
|
|
80
81
|
*/
|
|
81
|
-
export const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS =
|
|
82
|
-
export const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 4.
|
|
82
|
+
export const AI_COLUMN_WEB_SEARCH_TYPICAL_CREDITS = 0.6;
|
|
83
|
+
export const AI_COLUMN_WEB_SEARCH_RESERVED_CREDITS = 4.6;
|
|
84
|
+
/**
|
|
85
|
+
* Research depth (Claygent parity). `quick` is the single grounded pass priced
|
|
86
|
+
* above (the column's tier price plus AI_COLUMN_WEB_SEARCH_*; 2.1 typical at the
|
|
87
|
+
* Fast tier). A `standard` or `deep` row runs a bounded agent loop — several model
|
|
88
|
+
* turns over a growing evidence list — on a model the DEPTH fixes (standard on the
|
|
89
|
+
* Fast tier, deep on Balanced; the column's own tier applies to quick only), so its
|
|
90
|
+
* model leg is one flat price per row, reserved once:
|
|
91
|
+
*
|
|
92
|
+
* standard: 4.3 + 1.2 tools = 5.5 typical
|
|
93
|
+
* deep: 7.6 + 2.4 tools = 10 typical
|
|
94
|
+
*
|
|
95
|
+
* Founder-ratified 2026-09-26: 30-50% under Clay, >=5x markup. The Clay comparison
|
|
96
|
+
* it was set against: Clay web research bills per row in Data Credits — GPT-5 Nano
|
|
97
|
+
* 0.5 DC, Mini/Flash 1 DC, Claygent Neon 2 DC, Argon 3 DC — at >= $0.05 per DC plus
|
|
98
|
+
* ~$0.01 of action per row; OXYGEN credits are $0.01. Every figure must also keep
|
|
99
|
+
* >= 5x over the loop's modelled COGS. Pinned against the live estimator by
|
|
100
|
+
* @oxygen/integrations pricing-sheet-conformance.test.ts.
|
|
101
|
+
*/
|
|
102
|
+
export const RESEARCH_DEPTH_MODEL_CREDITS = { standard: 4.3, deep: 7.6 };
|
|
103
|
+
/** The tier whose model each loop depth runs on, whatever tier the column stores. */
|
|
104
|
+
export const RESEARCH_DEPTH_MODEL_TIER = { standard: "low", deep: "medium" };
|
|
105
|
+
/**
|
|
106
|
+
* The tool half of a standard/deep row. `typical` is the ratified planning shape —
|
|
107
|
+
* standard: 2 serper searches + 2 native page reads; deep: 3 serper searches + 4
|
|
108
|
+
* native reads + 1 exa.contents fallback read. `reserved` is every budgeted tool
|
|
109
|
+
* call at its dearest lane — each web_search, the row's shared exa.search pool
|
|
110
|
+
* (standard 1, deep 2: the zero-result fallback and semantic_search draw on it),
|
|
111
|
+
* each read's full ladder, deep's one Firecrawl read and site crawls. Deep's
|
|
112
|
+
* company-news call is opt-in (a news lead-lane column) and adds its own price to
|
|
113
|
+
* the reserve only there. Resolver-derived, pinned like the above.
|
|
114
|
+
*/
|
|
115
|
+
export const RESEARCH_DEPTH_GROUNDING_CREDITS = {
|
|
116
|
+
standard: { typical: 1.2, reserved: 7.4 },
|
|
117
|
+
deep: { typical: 2.4, reserved: 19.8 },
|
|
118
|
+
};
|
|
119
|
+
/** Typical per-row totals at each depth's default tier (founder-ratified 2026-09-26). */
|
|
120
|
+
export const RESEARCH_DEPTH_TYPICAL_ROW_CREDITS = { quick: 2.1, standard: 5.5, deep: 10 };
|
|
83
121
|
/** Workflow/automation actions (steps, tool calls, row writes) — capacity guard. */
|
|
84
122
|
export const AUTOMATION_ACTION_CREDITS = SNAPSHOT_AUTOMATION_ACTION_CREDITS;
|
|
85
123
|
/**
|
|
@@ -137,17 +175,28 @@ export const PLACEMENT_TEST_OVERAGE_CREDITS = SNAPSHOT_PLACEMENT_TEST_OVERAGE_CR
|
|
|
137
175
|
* price; every per-action charge is 0. Per-MESSAGE sends on email and WhatsApp
|
|
138
176
|
* stay 0 too — but a connected WhatsApp NUMBER carries its own monthly
|
|
139
177
|
* connection fee, see WHATSAPP_ACCOUNT_CREDITS_PER_MONTH.
|
|
178
|
+
*
|
|
179
|
+
* The value is the seeded price after the 2026-09 repricing (3,400, decision
|
|
180
|
+
* 2.1). The price in force before its effective-date switch is lower: resolve
|
|
181
|
+
* it with repricedChargeCredits from `@oxygen/shared/repricing` on the server.
|
|
140
182
|
*/
|
|
141
183
|
export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = SNAPSHOT_LINKEDIN_ACCOUNT_CREDITS_PER_MONTH;
|
|
142
184
|
export const LINKEDIN_ACTION_CREDITS = SNAPSHOT_LINKEDIN_ACTION_CREDITS;
|
|
143
185
|
export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = SNAPSHOT_LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH;
|
|
144
186
|
/**
|
|
145
187
|
* WhatsApp numbers: flat monthly connection fee per connected number, the same
|
|
146
|
-
* seat shape as LinkedIn.
|
|
147
|
-
*
|
|
148
|
-
*
|
|
188
|
+
* seat shape as LinkedIn. WhatsApp message sends themselves remain 0 credits.
|
|
189
|
+
* Seeded at the 2026-09 repricing's price (3,000, decision 2.3); resolve the
|
|
190
|
+
* price in force with repricedChargeCredits.
|
|
149
191
|
*/
|
|
150
192
|
export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = SNAPSHOT_WHATSAPP_ACCOUNT_CREDITS_PER_MONTH;
|
|
193
|
+
/**
|
|
194
|
+
* X accounts: monthly credit reservation per connected account (2026-09
|
|
195
|
+
* repricing, decision 2.2). Like the LinkedIn and WhatsApp constants above this
|
|
196
|
+
* is the seeded, post-repricing price; show the price in force with
|
|
197
|
+
* repricedChargeCredits from `@oxygen/shared/repricing`.
|
|
198
|
+
*/
|
|
199
|
+
export const X_ACCOUNT_CREDITS_PER_MONTH = SNAPSHOT_X_ACCOUNT_CREDITS_PER_MONTH;
|
|
151
200
|
/** Dedicated egress IP add-on. */
|
|
152
201
|
export const EGRESS_IP_CREDITS_PER_MONTH = SNAPSHOT_EGRESS_IP_CREDITS_PER_MONTH;
|
|
153
202
|
/**
|
|
@@ -15,8 +15,9 @@ export declare const MANAGED_DOMAIN_MARKUP = 1.25;
|
|
|
15
15
|
export declare const VOICE_MARKUP = 5;
|
|
16
16
|
/** Applied to actual provider inference cost at settle time. */
|
|
17
17
|
export declare const COPILOT_CREDIT_MARKUP_MULTIPLIER = 5;
|
|
18
|
-
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH =
|
|
19
|
-
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH =
|
|
18
|
+
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 3400;
|
|
19
|
+
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 3000;
|
|
20
|
+
export declare const X_ACCOUNT_CREDITS_PER_MONTH = 1000;
|
|
20
21
|
export declare const EGRESS_IP_CREDITS_PER_MONTH = 2500;
|
|
21
22
|
export declare const SENDING_MAILBOX_CREDITS_PER_MONTH = 100;
|
|
22
23
|
export declare const MANAGED_INBOX_CREDITS_PER_MONTH = 300;
|
|
@@ -37,7 +38,7 @@ export declare const SENDING_SEAT_USD_CENTS: {
|
|
|
37
38
|
export type SendingSeatKey = keyof typeof SENDING_SEAT_USD_CENTS;
|
|
38
39
|
export declare const MANAGED_INBOX_USD_CENTS = 400;
|
|
39
40
|
export declare const SENDING_DOMAIN_USD_CENTS = 1250;
|
|
40
|
-
export declare const VOICE_NUMBER_CREDITS_PER_MONTH =
|
|
41
|
+
export declare const VOICE_NUMBER_CREDITS_PER_MONTH = 1000;
|
|
41
42
|
export declare const VOICE_CREDITS_PER_MINUTE = 9;
|
|
42
43
|
export declare const VOICE_CREDITS_PER_AMD_CALL = 3.8;
|
|
43
44
|
/** Workflow steps, tool calls and row writes — a capacity guard, not a margin line. */
|
|
@@ -32,8 +32,14 @@ export const VOICE_MARKUP = 5;
|
|
|
32
32
|
/** Applied to actual provider inference cost at settle time. */
|
|
33
33
|
export const COPILOT_CREDIT_MARKUP_MULTIPLIER = 5;
|
|
34
34
|
// --- seats and recurring charges --------------------------------------------
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
//
|
|
36
|
+
// The connected-account reservations (LinkedIn, WhatsApp, X, phone number) carry
|
|
37
|
+
// the 2026-09 repricing's NEW price. Until its effective-date switch the price in
|
|
38
|
+
// force is lower; a surface that shows or charges one resolves it with
|
|
39
|
+
// repricedChargeCredits (@oxygen/shared/repricing), never from this literal alone.
|
|
40
|
+
export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 3_400;
|
|
41
|
+
export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 3_000;
|
|
42
|
+
export const X_ACCOUNT_CREDITS_PER_MONTH = 1_000;
|
|
37
43
|
export const EGRESS_IP_CREDITS_PER_MONTH = 2_500;
|
|
38
44
|
export const SENDING_MAILBOX_CREDITS_PER_MONTH = 100;
|
|
39
45
|
export const MANAGED_INBOX_CREDITS_PER_MONTH = 300;
|
|
@@ -74,7 +80,7 @@ export const SENDING_SEAT_USD_CENTS = {
|
|
|
74
80
|
export const MANAGED_INBOX_USD_CENTS = 400;
|
|
75
81
|
export const SENDING_DOMAIN_USD_CENTS = 1_250;
|
|
76
82
|
// --- voice ------------------------------------------------------------------
|
|
77
|
-
export const VOICE_NUMBER_CREDITS_PER_MONTH =
|
|
83
|
+
export const VOICE_NUMBER_CREDITS_PER_MONTH = 1_000;
|
|
78
84
|
export const VOICE_CREDITS_PER_MINUTE = 9;
|
|
79
85
|
export const VOICE_CREDITS_PER_AMD_CALL = 3.8;
|
|
80
86
|
// --- per-action -------------------------------------------------------------
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { hostname } from "node:os";
|
|
3
|
+
/**
|
|
4
|
+
* The per-process OTel resource identity: which box, which process.
|
|
5
|
+
*
|
|
6
|
+
* The OTLP destinations turn resource auto-detection off (`autoDetectResources:
|
|
7
|
+
* false`) because Node's process detector copies argv verbatim — inline scripts
|
|
8
|
+
* and credentials included. That also dropped `host.name`, so every replica's
|
|
9
|
+
* spans, metrics and logs arrived indistinguishable. These two attributes are
|
|
10
|
+
* the safe part of what detection used to provide, stated explicitly.
|
|
11
|
+
*
|
|
12
|
+
* `service.instance.id` is minted once per process: a restart is a new
|
|
13
|
+
* instance, and two replicas on one host never collide the way a pid can.
|
|
14
|
+
*/
|
|
15
|
+
const SERVICE_INSTANCE_ID = randomUUID();
|
|
16
|
+
export function processResourceIdentity() {
|
|
17
|
+
let host = "unknown";
|
|
18
|
+
try {
|
|
19
|
+
host = hostname() || "unknown";
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// A sandbox without os access still gets a stable instance id.
|
|
23
|
+
}
|
|
24
|
+
return { "host.name": host, "service.instance.id": SERVICE_INSTANCE_ID };
|
|
25
|
+
}
|