@oxygen-agent/cli 1.354.0 → 1.377.3
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 +12 -1
- package/dist/help.js +6 -5
- package/dist/index.js +692 -160
- package/node_modules/@oxygen/shared/dist/billing.d.ts +34 -10
- package/node_modules/@oxygen/shared/dist/billing.js +86 -11
- package/node_modules/@oxygen/shared/dist/copilot-journeys.d.ts +12 -0
- package/node_modules/@oxygen/shared/dist/copilot-journeys.js +36 -0
- package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +90 -0
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +212 -0
- package/node_modules/@oxygen/shared/dist/index.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/index.js +9 -0
- package/node_modules/@oxygen/shared/dist/langfuse.d.ts +77 -0
- package/node_modules/@oxygen/shared/dist/langfuse.js +231 -0
- package/node_modules/@oxygen/shared/dist/linkedin-mentions.d.ts +37 -0
- package/node_modules/@oxygen/shared/dist/linkedin-mentions.js +157 -0
- package/node_modules/@oxygen/shared/dist/log.js +15 -2
- package/node_modules/@oxygen/shared/dist/tags.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/tags.js +5 -0
- package/node_modules/@oxygen/shared/dist/version.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.js +1 -1
- package/node_modules/@oxygen/shared/dist/workspace-agents.d.ts +8 -7
- package/node_modules/@oxygen/shared/dist/workspace-agents.js +34 -7
- package/package.json +4 -1
|
@@ -28,6 +28,12 @@ export type PricingPlanMetadata = Record<string, unknown> | null | undefined;
|
|
|
28
28
|
export declare const CONTACT_SALES_URL = "https://cal.com/tim-scheuer-mxbib9/45";
|
|
29
29
|
export declare const CREDITS_PER_USD = 1000;
|
|
30
30
|
export declare const TOPUP_USD_CENTS_PER_1K_CREDITS = 125;
|
|
31
|
+
export declare const CREDIT_TOPUP_MIN_CREDITS = 8000;
|
|
32
|
+
export declare const CREDIT_TOPUP_MAX_CREDITS = 200000;
|
|
33
|
+
export declare const CREDIT_TOPUP_STEP_CREDITS = 1000;
|
|
34
|
+
export declare const CREDIT_TOPUP_DEFAULT_CREDITS = 20000;
|
|
35
|
+
export declare function isValidCreditTopupCredits(credits: number): boolean;
|
|
36
|
+
export declare function creditTopupUsdCents(credits: number): number | null;
|
|
31
37
|
export declare const AUTOMATION_ACTION_CREDITS = 0.01;
|
|
32
38
|
export declare const CREDIT_TOPUP_PACKS: readonly [{
|
|
33
39
|
readonly id: "10";
|
|
@@ -51,13 +57,15 @@ export type CreditTopupPackId = CreditTopupPack["id"];
|
|
|
51
57
|
export declare function resolveCreditTopupPack(id: string | null | undefined): CreditTopupPack | null;
|
|
52
58
|
export declare const TRIAL_PERIOD_DAYS = 7;
|
|
53
59
|
export declare const TRIAL_CREDIT_GRANT = 20000;
|
|
60
|
+
export declare const WALKTHROUGH_COMPLETION_BONUS_CREDITS = 1000;
|
|
61
|
+
export declare const WALKTHROUGH_SCRAPE_MAX_CREDITS = 2000;
|
|
54
62
|
export declare const BASE_PRICING_PLANS: {
|
|
55
63
|
readonly free: {
|
|
56
64
|
readonly tier: "free";
|
|
57
65
|
readonly name: "Free";
|
|
58
66
|
readonly monthlyPriceCents: 0;
|
|
59
67
|
readonly monthlyCredits: 10000;
|
|
60
|
-
readonly weeklyCreditsLimit:
|
|
68
|
+
readonly weeklyCreditsLimit: null;
|
|
61
69
|
readonly rolloverCap: 10000;
|
|
62
70
|
readonly monthlyAutomationActions: null;
|
|
63
71
|
readonly automationOverageCentsPerMillion: null;
|
|
@@ -65,14 +73,14 @@ export declare const BASE_PRICING_PLANS: {
|
|
|
65
73
|
readonly byokEnabled: false;
|
|
66
74
|
readonly description: "Get $10 in credits on us every month — try OXYGEN with managed email, phone enrichment, and AI credits.";
|
|
67
75
|
readonly ctaLabel: "Start free";
|
|
68
|
-
readonly features: readonly ["$10 in credits every month", "
|
|
76
|
+
readonly features: readonly ["$10 in credits every month", "All integrations", "Workflows", "No card required"];
|
|
69
77
|
};
|
|
70
78
|
readonly starter: {
|
|
71
79
|
readonly tier: "starter";
|
|
72
80
|
readonly name: "Starter";
|
|
73
81
|
readonly monthlyPriceCents: 9900;
|
|
74
82
|
readonly monthlyCredits: 99000;
|
|
75
|
-
readonly weeklyCreditsLimit:
|
|
83
|
+
readonly weeklyCreditsLimit: null;
|
|
76
84
|
readonly rolloverCap: 99000;
|
|
77
85
|
readonly monthlyAutomationActions: null;
|
|
78
86
|
readonly automationOverageCentsPerMillion: null;
|
|
@@ -80,14 +88,14 @@ export declare const BASE_PRICING_PLANS: {
|
|
|
80
88
|
readonly byokEnabled: true;
|
|
81
89
|
readonly description: "For founders running focused managed enrichment and AI columns.";
|
|
82
90
|
readonly ctaLabel: "Choose Starter";
|
|
83
|
-
readonly features: readonly ["99,000 credits every month", "All integrations", "Workflows
|
|
91
|
+
readonly features: readonly ["99,000 credits every month", "All integrations", "Workflows", "Bring your own keys", "Standard support"];
|
|
84
92
|
};
|
|
85
93
|
readonly pro: {
|
|
86
94
|
readonly tier: "pro";
|
|
87
95
|
readonly name: "Pro";
|
|
88
96
|
readonly monthlyPriceCents: 24900;
|
|
89
97
|
readonly monthlyCredits: 249000;
|
|
90
|
-
readonly weeklyCreditsLimit:
|
|
98
|
+
readonly weeklyCreditsLimit: null;
|
|
91
99
|
readonly rolloverCap: 249000;
|
|
92
100
|
readonly monthlyAutomationActions: null;
|
|
93
101
|
readonly automationOverageCentsPerMillion: null;
|
|
@@ -97,14 +105,14 @@ export declare const BASE_PRICING_PLANS: {
|
|
|
97
105
|
readonly badge: "Most popular";
|
|
98
106
|
readonly highlighted: true;
|
|
99
107
|
readonly ctaLabel: "Choose Pro";
|
|
100
|
-
readonly features: readonly ["249,000 credits every month", "All integrations", "Workflows
|
|
108
|
+
readonly features: readonly ["249,000 credits every month", "All integrations", "Workflows", "Bring your own keys", "Standard support"];
|
|
101
109
|
};
|
|
102
110
|
readonly team: {
|
|
103
111
|
readonly tier: "team";
|
|
104
112
|
readonly name: "Team";
|
|
105
113
|
readonly monthlyPriceCents: 74900;
|
|
106
114
|
readonly monthlyCredits: 749000;
|
|
107
|
-
readonly weeklyCreditsLimit:
|
|
115
|
+
readonly weeklyCreditsLimit: null;
|
|
108
116
|
readonly rolloverCap: 749000;
|
|
109
117
|
readonly monthlyAutomationActions: null;
|
|
110
118
|
readonly automationOverageCentsPerMillion: null;
|
|
@@ -112,14 +120,14 @@ export declare const BASE_PRICING_PLANS: {
|
|
|
112
120
|
readonly byokEnabled: true;
|
|
113
121
|
readonly description: "For small GTM teams and agencies running shared workflows with their own AI keys.";
|
|
114
122
|
readonly ctaLabel: "Choose Team";
|
|
115
|
-
readonly features: readonly ["749,000 credits every month", "All integrations", "Workflows
|
|
123
|
+
readonly features: readonly ["749,000 credits every month", "All integrations", "Workflows", "Bring your own keys", "Premium support"];
|
|
116
124
|
};
|
|
117
125
|
readonly scale: {
|
|
118
126
|
readonly tier: "scale";
|
|
119
127
|
readonly name: "Scale";
|
|
120
128
|
readonly monthlyPriceCents: null;
|
|
121
129
|
readonly monthlyCredits: 10000000;
|
|
122
|
-
readonly weeklyCreditsLimit:
|
|
130
|
+
readonly weeklyCreditsLimit: null;
|
|
123
131
|
readonly rolloverCap: 10000000;
|
|
124
132
|
readonly monthlyAutomationActions: null;
|
|
125
133
|
readonly automationOverageCentsPerMillion: null;
|
|
@@ -128,7 +136,7 @@ export declare const BASE_PRICING_PLANS: {
|
|
|
128
136
|
readonly description: "For high-volume GTM teams that need custom limits and rollout support.";
|
|
129
137
|
readonly ctaLabel: "Contact sales";
|
|
130
138
|
readonly contactHref: "https://cal.com/tim-scheuer-mxbib9/45";
|
|
131
|
-
readonly features: readonly ["10,000,000+ managed credits / month", "
|
|
139
|
+
readonly features: readonly ["10,000,000+ managed credits / month", "Workflows", "Phone number enrichment on managed credits", "Custom provider routing and BYOK policies", "Dedicated onboarding"];
|
|
132
140
|
};
|
|
133
141
|
readonly enterprise: {
|
|
134
142
|
readonly tier: "enterprise";
|
|
@@ -152,6 +160,22 @@ export declare const SELF_SERVE_PLAN_TIERS: readonly SelfServePlanTier[];
|
|
|
152
160
|
export declare const CONTACT_SALES_PLAN_TIERS: readonly ContactSalesPlanTier[];
|
|
153
161
|
export declare const ACTIVE_SUBSCRIPTION_STATUSES: readonly ["active", "trialing", "past_due"];
|
|
154
162
|
export type ActiveSubscriptionStatus = (typeof ACTIVE_SUBSCRIPTION_STATUSES)[number];
|
|
163
|
+
export declare const BILLING_VISIBLE_SUBSCRIPTION_STATUSES: readonly ["active", "trialing", "past_due", "unpaid", "paused", "incomplete"];
|
|
164
|
+
export type BillingVisibleSubscriptionStatus = (typeof BILLING_VISIBLE_SUBSCRIPTION_STATUSES)[number];
|
|
165
|
+
export declare const PAST_DUE_GRACE_DAYS = 7;
|
|
166
|
+
export type SubscriptionEntitlementReason = "active" | "trialing" | "past_due_grace" | "past_due_grace_expired" | "missing_past_due_period_start" | "trial_expired" | "missing_trial_end" | "unpaid" | "paused" | "incomplete" | "canceled" | "incomplete_expired" | "missing_subscription";
|
|
167
|
+
export type SubscriptionEntitlement = {
|
|
168
|
+
entitled: boolean;
|
|
169
|
+
reason: SubscriptionEntitlementReason;
|
|
170
|
+
graceEndsAt: Date | null;
|
|
171
|
+
};
|
|
172
|
+
export declare function resolveSubscriptionEntitlement(input: {
|
|
173
|
+
status: string | null | undefined;
|
|
174
|
+
currentPeriodStart?: Date | null;
|
|
175
|
+
currentPeriodEnd?: Date | null;
|
|
176
|
+
trialEnd?: Date | null;
|
|
177
|
+
now?: Date;
|
|
178
|
+
}): SubscriptionEntitlement;
|
|
155
179
|
export type ResolvedPricingPlan = PricingPlanDefinition;
|
|
156
180
|
export declare function resolveBasePricingPlan(tier: string | null | undefined): ResolvedPricingPlan | null;
|
|
157
181
|
export declare function applyPricingPlanMetadataOverrides(// skipcq: JS-R1005
|
|
@@ -9,6 +9,23 @@ export const CONTACT_SALES_URL = "https://cal.com/tim-scheuer-mxbib9/45";
|
|
|
9
9
|
// credits bought on demand.
|
|
10
10
|
export const CREDITS_PER_USD = 1_000;
|
|
11
11
|
export const TOPUP_USD_CENTS_PER_1K_CREDITS = 125;
|
|
12
|
+
// Keep on-demand purchases inside the same $10-$250 spend envelope as the
|
|
13
|
+
// original fixed packs, but let customers choose any 1,000-credit increment.
|
|
14
|
+
export const CREDIT_TOPUP_MIN_CREDITS = 8_000;
|
|
15
|
+
export const CREDIT_TOPUP_MAX_CREDITS = 200_000;
|
|
16
|
+
export const CREDIT_TOPUP_STEP_CREDITS = 1_000;
|
|
17
|
+
export const CREDIT_TOPUP_DEFAULT_CREDITS = 20_000;
|
|
18
|
+
export function isValidCreditTopupCredits(credits) {
|
|
19
|
+
return Number.isInteger(credits)
|
|
20
|
+
&& credits >= CREDIT_TOPUP_MIN_CREDITS
|
|
21
|
+
&& credits <= CREDIT_TOPUP_MAX_CREDITS
|
|
22
|
+
&& credits % CREDIT_TOPUP_STEP_CREDITS === 0;
|
|
23
|
+
}
|
|
24
|
+
export function creditTopupUsdCents(credits) {
|
|
25
|
+
if (!isValidCreditTopupCredits(credits))
|
|
26
|
+
return null;
|
|
27
|
+
return (credits / 1_000) * TOPUP_USD_CENTS_PER_1K_CREDITS;
|
|
28
|
+
}
|
|
12
29
|
// Workflow/automation actions (steps, tool calls, row writes, retries) draw
|
|
13
30
|
// from the same credit pool at a flat capacity-guard rate — the old separate
|
|
14
31
|
// monthly action allowance + USD overage meter economy is retired (2026-07-14).
|
|
@@ -30,13 +47,20 @@ export function resolveCreditTopupPack(id) {
|
|
|
30
47
|
// credit exhaustion or when the trial clock elapses, whichever comes first.
|
|
31
48
|
export const TRIAL_PERIOD_DAYS = 7;
|
|
32
49
|
export const TRIAL_CREDIT_GRANT = 20_000;
|
|
50
|
+
// Onboarding walkthrough (2026-07-21): completing the in-product walkthrough
|
|
51
|
+
// grants a one-off bonus (idempotent per billing owner), and the walkthrough's
|
|
52
|
+
// "start scraping engagers" step may spend at most this many credits on the
|
|
53
|
+
// managed cookieless scraper (founder-approved budget; the rest of the kickoff
|
|
54
|
+
// is free connected-account reads).
|
|
55
|
+
export const WALKTHROUGH_COMPLETION_BONUS_CREDITS = 1_000;
|
|
56
|
+
export const WALKTHROUGH_SCRAPE_MAX_CREDITS = 2_000;
|
|
33
57
|
export const BASE_PRICING_PLANS = {
|
|
34
58
|
free: {
|
|
35
59
|
tier: "free",
|
|
36
60
|
name: "Free",
|
|
37
61
|
monthlyPriceCents: 0,
|
|
38
62
|
monthlyCredits: 10_000,
|
|
39
|
-
weeklyCreditsLimit:
|
|
63
|
+
weeklyCreditsLimit: null,
|
|
40
64
|
rolloverCap: 10_000,
|
|
41
65
|
monthlyAutomationActions: null,
|
|
42
66
|
automationOverageCentsPerMillion: null,
|
|
@@ -46,7 +70,6 @@ export const BASE_PRICING_PLANS = {
|
|
|
46
70
|
ctaLabel: "Start free",
|
|
47
71
|
features: [
|
|
48
72
|
"$10 in credits every month",
|
|
49
|
-
"Automation actions at 0.01 credits each",
|
|
50
73
|
"All integrations",
|
|
51
74
|
"Workflows",
|
|
52
75
|
"No card required",
|
|
@@ -57,7 +80,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
57
80
|
name: "Starter",
|
|
58
81
|
monthlyPriceCents: 9_900,
|
|
59
82
|
monthlyCredits: 99_000,
|
|
60
|
-
weeklyCreditsLimit:
|
|
83
|
+
weeklyCreditsLimit: null,
|
|
61
84
|
rolloverCap: 99_000,
|
|
62
85
|
monthlyAutomationActions: null,
|
|
63
86
|
automationOverageCentsPerMillion: null,
|
|
@@ -68,7 +91,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
68
91
|
features: [
|
|
69
92
|
"99,000 credits every month",
|
|
70
93
|
"All integrations",
|
|
71
|
-
"Workflows
|
|
94
|
+
"Workflows",
|
|
72
95
|
"Bring your own keys",
|
|
73
96
|
"Standard support",
|
|
74
97
|
],
|
|
@@ -78,7 +101,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
78
101
|
name: "Pro",
|
|
79
102
|
monthlyPriceCents: 24_900,
|
|
80
103
|
monthlyCredits: 249_000,
|
|
81
|
-
weeklyCreditsLimit:
|
|
104
|
+
weeklyCreditsLimit: null,
|
|
82
105
|
rolloverCap: 249_000,
|
|
83
106
|
monthlyAutomationActions: null,
|
|
84
107
|
automationOverageCentsPerMillion: null,
|
|
@@ -91,7 +114,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
91
114
|
features: [
|
|
92
115
|
"249,000 credits every month",
|
|
93
116
|
"All integrations",
|
|
94
|
-
"Workflows
|
|
117
|
+
"Workflows",
|
|
95
118
|
"Bring your own keys",
|
|
96
119
|
"Standard support",
|
|
97
120
|
],
|
|
@@ -101,7 +124,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
101
124
|
name: "Team",
|
|
102
125
|
monthlyPriceCents: 74_900,
|
|
103
126
|
monthlyCredits: 749_000,
|
|
104
|
-
weeklyCreditsLimit:
|
|
127
|
+
weeklyCreditsLimit: null,
|
|
105
128
|
rolloverCap: 749_000,
|
|
106
129
|
monthlyAutomationActions: null,
|
|
107
130
|
automationOverageCentsPerMillion: null,
|
|
@@ -112,7 +135,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
112
135
|
features: [
|
|
113
136
|
"749,000 credits every month",
|
|
114
137
|
"All integrations",
|
|
115
|
-
"Workflows
|
|
138
|
+
"Workflows",
|
|
116
139
|
"Bring your own keys",
|
|
117
140
|
"Premium support",
|
|
118
141
|
],
|
|
@@ -122,7 +145,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
122
145
|
name: "Scale",
|
|
123
146
|
monthlyPriceCents: null,
|
|
124
147
|
monthlyCredits: 10_000_000,
|
|
125
|
-
weeklyCreditsLimit:
|
|
148
|
+
weeklyCreditsLimit: null,
|
|
126
149
|
rolloverCap: 10_000_000,
|
|
127
150
|
monthlyAutomationActions: null,
|
|
128
151
|
automationOverageCentsPerMillion: null,
|
|
@@ -133,7 +156,7 @@ export const BASE_PRICING_PLANS = {
|
|
|
133
156
|
contactHref: CONTACT_SALES_URL,
|
|
134
157
|
features: [
|
|
135
158
|
"10,000,000+ managed credits / month",
|
|
136
|
-
"
|
|
159
|
+
"Workflows",
|
|
137
160
|
"Phone number enrichment on managed credits",
|
|
138
161
|
"Custom provider routing and BYOK policies",
|
|
139
162
|
"Dedicated onboarding",
|
|
@@ -181,6 +204,52 @@ export const ACTIVE_SUBSCRIPTION_STATUSES = [
|
|
|
181
204
|
"trialing",
|
|
182
205
|
"past_due",
|
|
183
206
|
];
|
|
207
|
+
export const BILLING_VISIBLE_SUBSCRIPTION_STATUSES = [
|
|
208
|
+
...ACTIVE_SUBSCRIPTION_STATUSES,
|
|
209
|
+
"unpaid",
|
|
210
|
+
"paused",
|
|
211
|
+
"incomplete",
|
|
212
|
+
];
|
|
213
|
+
export const PAST_DUE_GRACE_DAYS = 7;
|
|
214
|
+
export function resolveSubscriptionEntitlement(input) {
|
|
215
|
+
const now = input.now ?? new Date();
|
|
216
|
+
if (!input.status) {
|
|
217
|
+
return { entitled: false, reason: "missing_subscription", graceEndsAt: null };
|
|
218
|
+
}
|
|
219
|
+
if (input.status === "active") {
|
|
220
|
+
return { entitled: true, reason: "active", graceEndsAt: null };
|
|
221
|
+
}
|
|
222
|
+
if (input.status === "trialing") {
|
|
223
|
+
const trialEnd = input.trialEnd ?? input.currentPeriodEnd ?? null;
|
|
224
|
+
if (!trialEnd) {
|
|
225
|
+
return { entitled: false, reason: "missing_trial_end", graceEndsAt: null };
|
|
226
|
+
}
|
|
227
|
+
return trialEnd.getTime() <= now.getTime()
|
|
228
|
+
? { entitled: false, reason: "trial_expired", graceEndsAt: null }
|
|
229
|
+
: { entitled: true, reason: "trialing", graceEndsAt: null };
|
|
230
|
+
}
|
|
231
|
+
if (input.status === "past_due") {
|
|
232
|
+
if (!input.currentPeriodStart) {
|
|
233
|
+
return {
|
|
234
|
+
entitled: false,
|
|
235
|
+
reason: "missing_past_due_period_start",
|
|
236
|
+
graceEndsAt: null,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const graceEndsAt = new Date(input.currentPeriodStart.getTime() + PAST_DUE_GRACE_DAYS * 24 * 60 * 60 * 1000);
|
|
240
|
+
return graceEndsAt.getTime() > now.getTime()
|
|
241
|
+
? { entitled: true, reason: "past_due_grace", graceEndsAt }
|
|
242
|
+
: { entitled: false, reason: "past_due_grace_expired", graceEndsAt };
|
|
243
|
+
}
|
|
244
|
+
if (input.status === "unpaid"
|
|
245
|
+
|| input.status === "paused"
|
|
246
|
+
|| input.status === "incomplete"
|
|
247
|
+
|| input.status === "canceled"
|
|
248
|
+
|| input.status === "incomplete_expired") {
|
|
249
|
+
return { entitled: false, reason: input.status, graceEndsAt: null };
|
|
250
|
+
}
|
|
251
|
+
return { entitled: false, reason: "missing_subscription", graceEndsAt: null };
|
|
252
|
+
}
|
|
184
253
|
const LEGACY_PRICING_PLAN_OVERRIDES = {
|
|
185
254
|
launch_50: {
|
|
186
255
|
...BASE_PRICING_PLANS.starter,
|
|
@@ -280,6 +349,7 @@ plan, metadata) {
|
|
|
280
349
|
?? readString(record, "custom_plan_description");
|
|
281
350
|
const monthlyCredits = readCreditLimit(config, "monthlyCredits", "monthly_credits", "monthly_credit_limit");
|
|
282
351
|
const weeklyCreditsLimit = readCreditLimit(config, "weeklyCreditsLimit", "weekly_credits_limit", "weekly_credit_limit");
|
|
352
|
+
const weeklyCreditsLimitDisabled = hasExplicitNull(config, "weeklyCreditsLimit", "weekly_credits_limit", "weekly_credit_limit");
|
|
283
353
|
const rolloverCap = readCreditLimit(config, "rolloverCap", "rollover_cap", "rollover_credits");
|
|
284
354
|
const monthlyAutomationActions = readCreditLimit(config, "monthlyAutomationActions", "monthly_automation_actions", "automation_actions", "automation_action_limit");
|
|
285
355
|
const automationOverageCentsPerMillion = readCreditLimit(config, "automationOverageCentsPerMillion", "automation_overage_cents_per_million", "automation_action_overage_cents_per_million");
|
|
@@ -292,7 +362,9 @@ plan, metadata) {
|
|
|
292
362
|
...plan,
|
|
293
363
|
name: name ?? plan.name,
|
|
294
364
|
monthlyCredits: monthlyCredits ?? plan.monthlyCredits,
|
|
295
|
-
weeklyCreditsLimit:
|
|
365
|
+
weeklyCreditsLimit: weeklyCreditsLimitDisabled
|
|
366
|
+
? null
|
|
367
|
+
: weeklyCreditsLimit ?? plan.weeklyCreditsLimit,
|
|
296
368
|
rolloverCap: rolloverCap ?? plan.rolloverCap,
|
|
297
369
|
monthlyAutomationActions: monthlyAutomationActions ?? plan.monthlyAutomationActions,
|
|
298
370
|
automationOverageCentsPerMillion: automationOverageCentsPerMillion ?? plan.automationOverageCentsPerMillion,
|
|
@@ -339,6 +411,9 @@ function readCreditLimit(record, ...keys) {
|
|
|
339
411
|
}
|
|
340
412
|
return null;
|
|
341
413
|
}
|
|
414
|
+
function hasExplicitNull(record, ...keys) {
|
|
415
|
+
return keys.some((key) => Object.hasOwn(record, key) && record[key] === null);
|
|
416
|
+
}
|
|
342
417
|
export function getCurrentFreeTierCycleKey(date = new Date()) {
|
|
343
418
|
const year = date.getUTCFullYear();
|
|
344
419
|
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type CopilotJourney = {
|
|
2
|
+
slug: string;
|
|
3
|
+
title: string;
|
|
4
|
+
description: string;
|
|
5
|
+
/** Existing catalog recipe slugs this journey leans on (advisory only). */
|
|
6
|
+
recipeSlugs: readonly string[];
|
|
7
|
+
/** The first user message a journey card seeds into a new session. */
|
|
8
|
+
seedMessage: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const COPILOT_JOURNEYS: readonly CopilotJourney[];
|
|
11
|
+
export type CopilotJourneySlug = (typeof COPILOT_JOURNEYS)[number]["slug"];
|
|
12
|
+
export declare function getCopilotJourney(slug: string): CopilotJourney | null;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Workspace Copilot guided journeys (ADR 0013 §11). One canonical copy shared by
|
|
2
|
+
// the runtime (system-prompt grounding on the named recipes) and the web journey
|
|
3
|
+
// cards (seeding a session's first message) — the data is pure and client-safe.
|
|
4
|
+
// Each journey is a thin descriptor over EXISTING advisory catalog Recipes:
|
|
5
|
+
// journeys add no runtime behavior, and every guardrail (never enroll/send/buy/
|
|
6
|
+
// change DNS without approval) rides those recipes' own approval gates.
|
|
7
|
+
export const COPILOT_JOURNEYS = [
|
|
8
|
+
{
|
|
9
|
+
slug: "inbound-led-outbound",
|
|
10
|
+
title: "Inbound-led outbound",
|
|
11
|
+
description: "Turn LinkedIn engagement, profile views, and replies into a segmented outreach motion.",
|
|
12
|
+
recipeSlugs: [
|
|
13
|
+
"profile-viewer-outreach",
|
|
14
|
+
"daily-warm-lead-queue",
|
|
15
|
+
"reply-to-meeting",
|
|
16
|
+
],
|
|
17
|
+
seedMessage: "Help me turn my recent LinkedIn engagement (profile views, post reactions, replies) into a safe, segmented outreach motion. Start by showing me what signals and connected identities I have.",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
slug: "tam-sourcing",
|
|
21
|
+
title: "Map your market",
|
|
22
|
+
description: "Source and segment your addressable market from your ICP, starting with a bounded sample.",
|
|
23
|
+
recipeSlugs: ["icp-to-account-map", "outbound-pilot-50"],
|
|
24
|
+
seedMessage: "Help me map my total addressable market from my ICP. Ground it in my company profile and website, source a bounded sample first, and show me coverage and credit estimates before expanding.",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
slug: "email-infra-setup",
|
|
28
|
+
title: "Outbound infrastructure",
|
|
29
|
+
description: "Domains, inboxes, warmup, sender posture — reviewed and approved before anything is bought or sent.",
|
|
30
|
+
recipeSlugs: ["email-infra-setup"],
|
|
31
|
+
seedMessage: "Inspect my current sending setup (domains, inboxes, warmup, senders, caps, deliverability) and propose what's missing for a safe cold-email motion. Show quotes and costs — do not buy or change anything without my approval.",
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
export function getCopilotJourney(slug) {
|
|
35
|
+
return COPILOT_JOURNEYS.find((journey) => journey.slug === slug) ?? null;
|
|
36
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical hosted-AI model registry — the single source of truth for which
|
|
3
|
+
* OXYGEN-hosted model backs each reasoning tier of each hosted-AI use case, its
|
|
4
|
+
* human-readable name, its fallback chain, the OpenRouter reasoning effort to
|
|
5
|
+
* request, and the conservative pre-call price estimates used ONLY to size
|
|
6
|
+
* credit reservations (billing always settles on the provider's actual
|
|
7
|
+
* `usage.cost`, never on the numbers here).
|
|
8
|
+
*
|
|
9
|
+
* Two use cases share the registry today:
|
|
10
|
+
* - `ai_column` — managed AI table columns. Its default model ids are
|
|
11
|
+
* re-sourced verbatim by `@oxygen/integrations` (`ai-column-runner.ts`
|
|
12
|
+
* `DEFAULT_REASONING_MODELS`) and `@oxygen/tenant-db` (`ai-models.ts`
|
|
13
|
+
* `DEFAULT_MANAGED_REASONING_MODELS`). Those modules keep owning the
|
|
14
|
+
* `OXYGEN_OPENROUTER_MODEL_*` env-override resolution; this registry only
|
|
15
|
+
* supplies the defaults, so AI-column behavior is byte-for-byte unchanged.
|
|
16
|
+
* - `copilot` — the hosted copilot. Its model + fallback chain accept Doppler
|
|
17
|
+
* overrides (`OXYGEN_COPILOT_MODEL_*` / `OXYGEN_COPILOT_FALLBACK_*`) applied
|
|
18
|
+
* here by `resolveHostedAiModel`.
|
|
19
|
+
*
|
|
20
|
+
* Kept as a leaf module (mirrors ./pricing-sheet.ts): no imports, so any package
|
|
21
|
+
* can re-source the catalog without dragging in the shared barrel.
|
|
22
|
+
*/
|
|
23
|
+
export type HostedAiLevel = "low" | "medium" | "high";
|
|
24
|
+
export type HostedAiUseCase = "ai_column" | "copilot" | "agent";
|
|
25
|
+
export type HostedAiModelSpec = {
|
|
26
|
+
/** OpenRouter model id, e.g. "deepseek/deepseek-v4-flash". */
|
|
27
|
+
model: string;
|
|
28
|
+
/** Human-readable label for dashboards/UI. */
|
|
29
|
+
displayName: string;
|
|
30
|
+
/** Ordered fallback model ids tried when `model` is unavailable. */
|
|
31
|
+
fallbackModels: readonly string[];
|
|
32
|
+
/**
|
|
33
|
+
* OpenRouter reasoning effort to request; omit entirely for models that only
|
|
34
|
+
* support their max mode (Kimi K3) — the request builder sends no reasoning
|
|
35
|
+
* param for those.
|
|
36
|
+
*/
|
|
37
|
+
reasoningEffort?: "low" | "medium" | "high";
|
|
38
|
+
/**
|
|
39
|
+
* Conservative pre-call estimation prices (USD per 1M tokens). Billing settles
|
|
40
|
+
* on actual `usage.cost`; these ONLY size credit reservations.
|
|
41
|
+
*/
|
|
42
|
+
estPromptUsdPerM: number;
|
|
43
|
+
estCompletionUsdPerM: number;
|
|
44
|
+
/** Upper bound on completion tokens requested for this tier. */
|
|
45
|
+
maxOutputTokens: number;
|
|
46
|
+
};
|
|
47
|
+
export declare const HOSTED_AI_MODEL_REGISTRY: Record<HostedAiUseCase, Record<HostedAiLevel, HostedAiModelSpec>>;
|
|
48
|
+
/** The reasoning tier the hosted copilot runs at by default. */
|
|
49
|
+
export declare const COPILOT_DEFAULT_LEVEL: HostedAiLevel;
|
|
50
|
+
export declare const AGENT_DEFAULT_LEVEL: HostedAiLevel;
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the model spec for a hosted-AI use case + reasoning level.
|
|
53
|
+
*
|
|
54
|
+
* For `copilot`, Doppler overrides are applied here:
|
|
55
|
+
* - `OXYGEN_COPILOT_MODEL_{LOW,MEDIUM,HIGH}` replaces `.model` (and, since no
|
|
56
|
+
* separate label is supplied, `.displayName` falls back to the model id).
|
|
57
|
+
* - `OXYGEN_COPILOT_FALLBACK_{LOW,MEDIUM,HIGH}` replaces `.fallbackModels`
|
|
58
|
+
* from a comma-separated list.
|
|
59
|
+
*
|
|
60
|
+
* For `ai_column`, NO env handling is applied here: `@oxygen/integrations`
|
|
61
|
+
* `ai-column-runner.ts` (`resolveModel`/`resolveAiColumnTierModels`) and
|
|
62
|
+
* `@oxygen/tenant-db` `ai-models.ts` (`resolveManagedReasoningModels`) remain
|
|
63
|
+
* the sole owners of `OXYGEN_OPENROUTER_MODEL_*` resolution, so the AI-column
|
|
64
|
+
* path is untouched.
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Look a model id up across the priced registry (same-use-case tiers first).
|
|
68
|
+
* A session-level model override must land on a spec that carries ITS OWN
|
|
69
|
+
* pricing/limits — splicing an arbitrary id onto another tier's spec sizes the
|
|
70
|
+
* credit reservation for the wrong model and breaks the spend ceiling.
|
|
71
|
+
*/
|
|
72
|
+
export declare function findHostedAiModelSpec(model: string, preferredUseCase?: HostedAiUseCase): HostedAiModelSpec | null;
|
|
73
|
+
export declare function resolveHostedAiModel(input: {
|
|
74
|
+
useCase: HostedAiUseCase;
|
|
75
|
+
level: HostedAiLevel;
|
|
76
|
+
env?: Record<string, string | undefined>;
|
|
77
|
+
}): HostedAiModelSpec;
|
|
78
|
+
/**
|
|
79
|
+
* Convenience map of each reasoning tier's default `.model` id for a use case.
|
|
80
|
+
* `@oxygen/integrations` and `@oxygen/tenant-db` re-source their AI-column
|
|
81
|
+
* default catalogs from `hostedAiDefaultModels("ai_column")` so the model ids
|
|
82
|
+
* live in exactly one place. Returns a fresh object each call.
|
|
83
|
+
*/
|
|
84
|
+
export declare function hostedAiDefaultModels(useCase: HostedAiUseCase): Record<HostedAiLevel, string>;
|
|
85
|
+
/**
|
|
86
|
+
* Whether the hosted copilot is enabled for this environment. FAIL CLOSED: only
|
|
87
|
+
* the exact strings "1" or "true" (case-insensitive, trimmed) enable it;
|
|
88
|
+
* anything else — unset, "", "0", "false" — leaves it off.
|
|
89
|
+
*/
|
|
90
|
+
export declare function isCopilotEnabled(env?: Record<string, string | undefined>): boolean;
|