@opengeni/api-router 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +1 -1
- package/dist/{chunk-A4J3LBH6.js → chunk-BAZXDFT2.js} +185 -93
- package/dist/{chunk-A4J3LBH6.js.map → chunk-BAZXDFT2.js.map} +1 -1
- package/dist/credit-promotion-snapshot.d.ts +6 -0
- package/dist/index.js +1 -1
- package/dist/integrations/marketplace-plugin.d.ts +43 -43
- package/dist/routes/billing.d.ts +3 -1
- package/package.json +20 -20
- package/src/credit-promotion-snapshot.ts +36 -0
- package/src/mcp/action-catalog.gen.ts +24 -16
- package/src/model-catalog.ts +1 -0
- package/src/routes/billing.ts +72 -15
- package/src/routes/managed-onboarding.ts +2 -0
- package/src/routes/organization-memberships.ts +2 -0
- package/src/routes/workspaces.ts +27 -12
package/dist/app.js
CHANGED
|
@@ -3803,8 +3803,8 @@ async function sendIntegrationEndpointTest(input) {
|
|
|
3803
3803
|
// src/routes/workspace-integrations.ts
|
|
3804
3804
|
import { HTTPException as HTTPException14 } from "hono/http-exception";
|
|
3805
3805
|
import { z as z10 } from "zod";
|
|
3806
|
-
function newIntegrationSecret(
|
|
3807
|
-
return `${
|
|
3806
|
+
function newIntegrationSecret(prefix2) {
|
|
3807
|
+
return `${prefix2}_${randomBytes2(32).toString("base64url")}`;
|
|
3808
3808
|
}
|
|
3809
3809
|
function iso(value) {
|
|
3810
3810
|
return value ? value.toISOString() : null;
|
|
@@ -4378,13 +4378,13 @@ function registerApiKeyRoutes(app, deps) {
|
|
|
4378
4378
|
quantity: 1
|
|
4379
4379
|
});
|
|
4380
4380
|
const token = generateApiKeyToken();
|
|
4381
|
-
const
|
|
4381
|
+
const prefix2 = token.slice(0, 14);
|
|
4382
4382
|
const apiKey = await createApiKey(deps.db, {
|
|
4383
4383
|
accountId: grant.accountId,
|
|
4384
4384
|
workspaceId: grant.workspaceId,
|
|
4385
4385
|
name: body3.name,
|
|
4386
4386
|
description: body3.description ?? null,
|
|
4387
|
-
prefix,
|
|
4387
|
+
prefix: prefix2,
|
|
4388
4388
|
keyHash: await sha256Hex(token),
|
|
4389
4389
|
permissions,
|
|
4390
4390
|
expiresAt: body3.expiresAt ? new Date(body3.expiresAt) : null
|
|
@@ -5843,6 +5843,7 @@ function projectClientModel(model) {
|
|
|
5843
5843
|
id: model.id,
|
|
5844
5844
|
label: model.label,
|
|
5845
5845
|
...model.shortLabel ? { shortLabel: model.shortLabel } : {},
|
|
5846
|
+
...model.logoUrl ? { logoUrl: model.logoUrl } : {},
|
|
5846
5847
|
...publicProvider,
|
|
5847
5848
|
...source === void 0 ? {} : { source },
|
|
5848
5849
|
api: model.api,
|
|
@@ -15383,8 +15384,8 @@ function boundedState(value) {
|
|
|
15383
15384
|
function pkceChallenge(verifier) {
|
|
15384
15385
|
return createHash4("sha256").update(verifier, "ascii").digest("base64url");
|
|
15385
15386
|
}
|
|
15386
|
-
function opaque(
|
|
15387
|
-
return `${
|
|
15387
|
+
function opaque(prefix2) {
|
|
15388
|
+
return `${prefix2}${randomBytes5(32).toString("base64url")}`;
|
|
15388
15389
|
}
|
|
15389
15390
|
function tokenHash(value) {
|
|
15390
15391
|
return createHash4("sha256").update(value, "utf8").digest("hex");
|
|
@@ -21620,21 +21621,21 @@ function projectScheduledTaskUtf8(value, maxBytes) {
|
|
|
21620
21621
|
return { value, originalBytes, deliveredBytes: originalBytes, truncated: false };
|
|
21621
21622
|
}
|
|
21622
21623
|
let marker = "";
|
|
21623
|
-
let
|
|
21624
|
+
let prefix2 = "";
|
|
21624
21625
|
let omittedBytes = originalBytes;
|
|
21625
21626
|
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
21626
21627
|
marker = `\u2026[${omittedBytes} UTF-8 bytes omitted]`;
|
|
21627
21628
|
if (Buffer.byteLength(marker, "utf8") > byteLimit) {
|
|
21628
21629
|
marker = utf8Prefix2(marker, byteLimit);
|
|
21629
|
-
|
|
21630
|
+
prefix2 = "";
|
|
21630
21631
|
break;
|
|
21631
21632
|
}
|
|
21632
|
-
|
|
21633
|
-
const nextOmitted = originalBytes - Buffer.byteLength(
|
|
21633
|
+
prefix2 = utf8Prefix2(value, byteLimit - Buffer.byteLength(marker, "utf8"));
|
|
21634
|
+
const nextOmitted = originalBytes - Buffer.byteLength(prefix2, "utf8");
|
|
21634
21635
|
if (nextOmitted === omittedBytes) break;
|
|
21635
21636
|
omittedBytes = nextOmitted;
|
|
21636
21637
|
}
|
|
21637
|
-
const projected = `${
|
|
21638
|
+
const projected = `${prefix2}${marker}`;
|
|
21638
21639
|
return {
|
|
21639
21640
|
value: projected,
|
|
21640
21641
|
originalBytes,
|
|
@@ -25081,8 +25082,8 @@ function sniffSlackReactionImageMime(bytes) {
|
|
|
25081
25082
|
return null;
|
|
25082
25083
|
}
|
|
25083
25084
|
function hasMarkupPrefix(bytes) {
|
|
25084
|
-
const
|
|
25085
|
-
return
|
|
25085
|
+
const prefix2 = new TextDecoder("utf-8", { fatal: false }).decode(bytes.subarray(0, Math.min(bytes.byteLength, 256))).replace(/^\uFEFF/u, "").trimStart().toLowerCase();
|
|
25086
|
+
return prefix2.startsWith("<svg") || prefix2.startsWith("<html") || prefix2.startsWith("<!doctype") || prefix2.startsWith("<?xml");
|
|
25086
25087
|
}
|
|
25087
25088
|
function isCompletePng(bytes) {
|
|
25088
25089
|
const signature = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
@@ -38568,14 +38569,9 @@ var ACTION_CATALOG = [
|
|
|
38568
38569
|
"method": "GET",
|
|
38569
38570
|
"path": "/v1/organizations/:accountId/insights/calls",
|
|
38570
38571
|
"request": [],
|
|
38571
|
-
"response": [
|
|
38572
|
-
|
|
38573
|
-
|
|
38574
|
-
"id": "GET /v1/organizations/:accountId/insights/usage",
|
|
38575
|
-
"method": "GET",
|
|
38576
|
-
"path": "/v1/organizations/:accountId/insights/usage",
|
|
38577
|
-
"request": [],
|
|
38578
|
-
"response": []
|
|
38572
|
+
"response": [
|
|
38573
|
+
"InsightsCallsResponse"
|
|
38574
|
+
]
|
|
38579
38575
|
},
|
|
38580
38576
|
{
|
|
38581
38577
|
"id": "GET /v1/organizations/:organizationId/codex/accounts",
|
|
@@ -38728,14 +38724,9 @@ var ACTION_CATALOG = [
|
|
|
38728
38724
|
"method": "GET",
|
|
38729
38725
|
"path": "/v1/workspaces/:workspaceId/insights/calls",
|
|
38730
38726
|
"request": [],
|
|
38731
|
-
"response": [
|
|
38732
|
-
|
|
38733
|
-
|
|
38734
|
-
"id": "GET /v1/workspaces/:workspaceId/insights/usage",
|
|
38735
|
-
"method": "GET",
|
|
38736
|
-
"path": "/v1/workspaces/:workspaceId/insights/usage",
|
|
38737
|
-
"request": [],
|
|
38738
|
-
"response": []
|
|
38727
|
+
"response": [
|
|
38728
|
+
"InsightsCallsResponse"
|
|
38729
|
+
]
|
|
38739
38730
|
},
|
|
38740
38731
|
{
|
|
38741
38732
|
"id": "GET /v1/workspaces/:workspaceId/instruction-policies/:revisionId",
|
|
@@ -39296,6 +39287,15 @@ var ACTION_CATALOG = [
|
|
|
39296
39287
|
"GetOrganizationCredentialProviderResponse"
|
|
39297
39288
|
]
|
|
39298
39289
|
},
|
|
39290
|
+
{
|
|
39291
|
+
"id": "getOrganizationInsightsUsage",
|
|
39292
|
+
"method": "GET",
|
|
39293
|
+
"path": "/v1/organizations/:accountId/insights/usage",
|
|
39294
|
+
"request": [],
|
|
39295
|
+
"response": [
|
|
39296
|
+
"InsightsUsageResponse"
|
|
39297
|
+
]
|
|
39298
|
+
},
|
|
39299
39299
|
{
|
|
39300
39300
|
"id": "getOrganizationIntegrationCatalog",
|
|
39301
39301
|
"method": "GET",
|
|
@@ -39751,6 +39751,15 @@ var ACTION_CATALOG = [
|
|
|
39751
39751
|
"WorkspaceInsightsResponse"
|
|
39752
39752
|
]
|
|
39753
39753
|
},
|
|
39754
|
+
{
|
|
39755
|
+
"id": "getWorkspaceInsightsUsage",
|
|
39756
|
+
"method": "GET",
|
|
39757
|
+
"path": "/v1/workspaces/:workspaceId/insights/usage",
|
|
39758
|
+
"request": [],
|
|
39759
|
+
"response": [
|
|
39760
|
+
"InsightsUsageResponse"
|
|
39761
|
+
]
|
|
39762
|
+
},
|
|
39754
39763
|
{
|
|
39755
39764
|
"id": "getWorkspaceLearningHistory",
|
|
39756
39765
|
"method": "GET",
|
|
@@ -73499,13 +73508,13 @@ function registerCatalogAssetRoutes(app, deps) {
|
|
|
73499
73508
|
});
|
|
73500
73509
|
}
|
|
73501
73510
|
function catalogAssetKeyFromPath(pathname) {
|
|
73502
|
-
const
|
|
73503
|
-
if (!pathname.startsWith(
|
|
73511
|
+
const prefix2 = "/v1/";
|
|
73512
|
+
if (!pathname.startsWith(prefix2)) {
|
|
73504
73513
|
return null;
|
|
73505
73514
|
}
|
|
73506
73515
|
let key;
|
|
73507
73516
|
try {
|
|
73508
|
-
key = decodeURIComponent(pathname.slice(
|
|
73517
|
+
key = decodeURIComponent(pathname.slice(prefix2.length));
|
|
73509
73518
|
} catch {
|
|
73510
73519
|
return null;
|
|
73511
73520
|
}
|
|
@@ -82445,8 +82454,8 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82445
82454
|
"/v1/workspaces/:workspaceId/variable-sets",
|
|
82446
82455
|
"/v1/workspaces/:workspaceId/environments"
|
|
82447
82456
|
];
|
|
82448
|
-
for (const
|
|
82449
|
-
app.get(`${
|
|
82457
|
+
for (const prefix2 of prefixes) {
|
|
82458
|
+
app.get(`${prefix2}`, async (c) => {
|
|
82450
82459
|
const workspaceId = c.req.param("workspaceId");
|
|
82451
82460
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82452
82461
|
requirePermission4(grant, "variable-sets:list");
|
|
@@ -82459,14 +82468,14 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82459
82468
|
})
|
|
82460
82469
|
);
|
|
82461
82470
|
});
|
|
82462
|
-
app.post(`${
|
|
82471
|
+
app.post(`${prefix2}`, async (c) => {
|
|
82463
82472
|
const workspaceId = c.req.param("workspaceId");
|
|
82464
82473
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82465
82474
|
const grant = authorization.grant;
|
|
82466
82475
|
requirePermission4(grant, "variable-sets:write");
|
|
82467
82476
|
const key = requireVariableSetEncryption2(settings);
|
|
82468
82477
|
const payload = await parseRequestJson(c, CreateVariableSetRequest);
|
|
82469
|
-
if (
|
|
82478
|
+
if (prefix2.endsWith("/environments") && payload.scope !== "workspace") {
|
|
82470
82479
|
throw new HTTPException61(422, {
|
|
82471
82480
|
message: "the legacy environments route only creates workspace-scoped variable sets"
|
|
82472
82481
|
});
|
|
@@ -82530,8 +82539,8 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82530
82539
|
});
|
|
82531
82540
|
return c.json(created, 201);
|
|
82532
82541
|
});
|
|
82533
|
-
if (
|
|
82534
|
-
app.post(`${
|
|
82542
|
+
if (prefix2.endsWith("/variable-sets")) {
|
|
82543
|
+
app.post(`${prefix2}/resolve-attachments`, async (c) => {
|
|
82535
82544
|
const workspaceId = c.req.param("workspaceId");
|
|
82536
82545
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82537
82546
|
requirePermission4(grant, "variable-sets:attach");
|
|
@@ -82549,15 +82558,15 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82549
82558
|
return c.json(ResolveVariableSetAttachmentsResponse.parse({ variableSets }));
|
|
82550
82559
|
});
|
|
82551
82560
|
}
|
|
82552
|
-
app.get(`${
|
|
82561
|
+
app.get(`${prefix2}/:variableSetId`, async (c) => {
|
|
82553
82562
|
const workspaceId = c.req.param("workspaceId");
|
|
82554
82563
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82555
82564
|
requirePermission4(grant, "variable-sets:read");
|
|
82556
82565
|
requirePermission4(grant, "secrets:list");
|
|
82557
82566
|
return c.json(await requireVariableSetForApi(db, grant, c.req.param("variableSetId")));
|
|
82558
82567
|
});
|
|
82559
|
-
if (
|
|
82560
|
-
app.get(`${
|
|
82568
|
+
if (prefix2.endsWith("/variable-sets")) {
|
|
82569
|
+
app.get(`${prefix2}/:variableSetId/variables/:name`, async (c) => {
|
|
82561
82570
|
const workspaceId = c.req.param("workspaceId");
|
|
82562
82571
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82563
82572
|
requirePermission4(grant, "variable-sets:read");
|
|
@@ -82581,7 +82590,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82581
82590
|
return c.json(secret);
|
|
82582
82591
|
});
|
|
82583
82592
|
}
|
|
82584
|
-
app.patch(`${
|
|
82593
|
+
app.patch(`${prefix2}/:variableSetId`, async (c) => {
|
|
82585
82594
|
const workspaceId = c.req.param("workspaceId");
|
|
82586
82595
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82587
82596
|
const grant = authorization.grant;
|
|
@@ -82629,7 +82638,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82629
82638
|
});
|
|
82630
82639
|
return c.json(updated);
|
|
82631
82640
|
});
|
|
82632
|
-
app.delete(`${
|
|
82641
|
+
app.delete(`${prefix2}/:variableSetId`, async (c) => {
|
|
82633
82642
|
const workspaceId = c.req.param("workspaceId");
|
|
82634
82643
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82635
82644
|
const grant = authorization.grant;
|
|
@@ -82666,7 +82675,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82666
82675
|
});
|
|
82667
82676
|
return c.json({ ok: true });
|
|
82668
82677
|
});
|
|
82669
|
-
app.put(`${
|
|
82678
|
+
app.put(`${prefix2}/:variableSetId/variables/:name`, async (c) => {
|
|
82670
82679
|
const workspaceId = c.req.param("workspaceId");
|
|
82671
82680
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82672
82681
|
const grant = authorization.grant;
|
|
@@ -82705,7 +82714,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82705
82714
|
});
|
|
82706
82715
|
return c.json(metadata);
|
|
82707
82716
|
});
|
|
82708
|
-
app.delete(`${
|
|
82717
|
+
app.delete(`${prefix2}/:variableSetId/variables/:name`, async (c) => {
|
|
82709
82718
|
const workspaceId = c.req.param("workspaceId");
|
|
82710
82719
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82711
82720
|
const grant = authorization.grant;
|
|
@@ -83021,10 +83030,43 @@ import {
|
|
|
83021
83030
|
OrganizationUsageWorkspacePageQuery
|
|
83022
83031
|
} from "@opengeni/contracts";
|
|
83023
83032
|
import { OrganizationModelUsageQuery } from "@opengeni/contracts/organization-model-usage";
|
|
83024
|
-
import { configuredEntitlements } from "@opengeni/config";
|
|
83033
|
+
import { configuredEntitlements, promotionalCreditScope } from "@opengeni/config";
|
|
83034
|
+
|
|
83035
|
+
// src/credit-promotion-snapshot.ts
|
|
83036
|
+
import { PromotionalCreditScope } from "@opengeni/contracts";
|
|
83037
|
+
var prefix = "opengeni_credit_scope_";
|
|
83038
|
+
var countKey = `${prefix}v1`;
|
|
83039
|
+
function creditScopeMetadata(scope) {
|
|
83040
|
+
if (!scope) return {};
|
|
83041
|
+
const encoded = JSON.stringify(PromotionalCreditScope.parse(scope));
|
|
83042
|
+
const chunks = encoded.match(/[\s\S]{1,400}/g);
|
|
83043
|
+
if (chunks.length > 24)
|
|
83044
|
+
throw new Error("Promotional credit policy exceeds checkout metadata limits");
|
|
83045
|
+
return Object.fromEntries([
|
|
83046
|
+
[countKey, String(chunks.length)],
|
|
83047
|
+
...chunks.map((chunk, index) => [`${prefix}${index}`, chunk])
|
|
83048
|
+
]);
|
|
83049
|
+
}
|
|
83050
|
+
function creditScopeFromMetadata(metadata) {
|
|
83051
|
+
if (!metadata || !Object.keys(metadata).some((key) => key.startsWith(prefix))) return void 0;
|
|
83052
|
+
const count = Number(metadata[countKey]);
|
|
83053
|
+
if (!Number.isInteger(count) || count < 1 || count > 24) {
|
|
83054
|
+
throw new Error("Invalid promotional credit snapshot");
|
|
83055
|
+
}
|
|
83056
|
+
let encoded = "";
|
|
83057
|
+
for (let index = 0; index < count; index++) {
|
|
83058
|
+
const chunk = metadata[`${prefix}${index}`];
|
|
83059
|
+
if (!chunk) throw new Error("Incomplete promotional credit snapshot");
|
|
83060
|
+
encoded += chunk;
|
|
83061
|
+
}
|
|
83062
|
+
return PromotionalCreditScope.parse(JSON.parse(encoded));
|
|
83063
|
+
}
|
|
83064
|
+
|
|
83065
|
+
// src/routes/billing.ts
|
|
83025
83066
|
import {
|
|
83026
83067
|
applyCreditLedgerEntry,
|
|
83027
83068
|
getBillingBalance,
|
|
83069
|
+
readCreditPromotionPolicy,
|
|
83028
83070
|
getBillingCustomer,
|
|
83029
83071
|
getCreditLedgerEntry,
|
|
83030
83072
|
hasCreditLedgerEntry,
|
|
@@ -83034,6 +83076,7 @@ import {
|
|
|
83034
83076
|
getOrganizationUsageSummary,
|
|
83035
83077
|
getOrganizationUsageWorkspacePage,
|
|
83036
83078
|
withSessionRlsActorContext as withSessionRlsActorContext8,
|
|
83079
|
+
withRlsContext as withRlsContext2,
|
|
83037
83080
|
getManagedAccount as getManagedAccount2,
|
|
83038
83081
|
markStripeWebhookProcessed,
|
|
83039
83082
|
recordStripeWebhookEvent,
|
|
@@ -83139,6 +83182,12 @@ function registerBillingRoutes(app, deps) {
|
|
|
83139
83182
|
const accountId = requireSelectedAccount(context, body3.accountId, "billing:manage");
|
|
83140
83183
|
const stripe = stripeClient(deps);
|
|
83141
83184
|
const promotion = body3.promotionCode ? await resolveCheckoutPromotionCode(stripe, body3.promotionCode) : null;
|
|
83185
|
+
const promotionalScope = promotion ? promotionalCreditScope(
|
|
83186
|
+
{
|
|
83187
|
+
creditPromotionPolicy: await readCreditPromotionPolicy(deps.db) ?? deps.settings.creditPromotionPolicy
|
|
83188
|
+
},
|
|
83189
|
+
promotion.couponId
|
|
83190
|
+
) : void 0;
|
|
83142
83191
|
const amountCents = body3.amountUsd !== void 0 ? usdToCents(body3.amountUsd) : promotion?.amountOffCents ?? null;
|
|
83143
83192
|
if (amountCents === null) {
|
|
83144
83193
|
throw new HTTPException64(422, {
|
|
@@ -83150,6 +83199,11 @@ function registerBillingRoutes(app, deps) {
|
|
|
83150
83199
|
message: "Credits must be between $5 and $10,000."
|
|
83151
83200
|
});
|
|
83152
83201
|
}
|
|
83202
|
+
if (promotionalScope && (!promotion?.amountOffCents || amountCents !== promotion.amountOffCents)) {
|
|
83203
|
+
throw new HTTPException64(422, {
|
|
83204
|
+
message: "Redeem this offer for its exact credit amount. Buy additional credits separately."
|
|
83205
|
+
});
|
|
83206
|
+
}
|
|
83153
83207
|
const amountMicros = centsToMicros(amountCents);
|
|
83154
83208
|
const customerId = await getOrCreateStripeCustomer(deps, stripe, context, accountId);
|
|
83155
83209
|
const idempotencyKey = `checkout:${accountId}:${amountMicros}:${crypto.randomUUID()}`;
|
|
@@ -83167,8 +83221,10 @@ function registerBillingRoutes(app, deps) {
|
|
|
83167
83221
|
successUrl: body3.successUrl,
|
|
83168
83222
|
cancelUrl: body3.cancelUrl,
|
|
83169
83223
|
idempotencyKey,
|
|
83224
|
+
promotionalScope,
|
|
83170
83225
|
...promotion ? {
|
|
83171
83226
|
promotionCodeId: promotion.id,
|
|
83227
|
+
couponId: promotion.couponId,
|
|
83172
83228
|
fullyDiscounted: promotion.percentOff === 100 || (promotion.amountOffCents ?? 0) >= amountCents
|
|
83173
83229
|
} : {}
|
|
83174
83230
|
}),
|
|
@@ -83187,7 +83243,8 @@ function registerBillingRoutes(app, deps) {
|
|
|
83187
83243
|
CreateCheckoutResponse.parse({
|
|
83188
83244
|
checkoutSessionId: session.id,
|
|
83189
83245
|
url: session.url,
|
|
83190
|
-
amountUsd: amountCents / 100
|
|
83246
|
+
amountUsd: amountCents / 100,
|
|
83247
|
+
promotionalScope
|
|
83191
83248
|
})
|
|
83192
83249
|
);
|
|
83193
83250
|
});
|
|
@@ -83231,6 +83288,7 @@ function registerBillingRoutes(app, deps) {
|
|
|
83231
83288
|
state: entry2 ? "granted" : "pending",
|
|
83232
83289
|
amountMicros: entry2?.amountMicros ?? credit.amountMicros,
|
|
83233
83290
|
currency: "usd",
|
|
83291
|
+
promotionalScope: creditScopeFromMetadata(session.metadata),
|
|
83234
83292
|
free: entry2 ? entry2.sourceType === "stripe_checkout_coupon" : isFreeCouponCheckout(session)
|
|
83235
83293
|
},
|
|
83236
83294
|
balance: entry2 ? await getBillingBalance(deps.db, accountId) : null
|
|
@@ -83330,7 +83388,7 @@ function stripeCheckoutSessionCreateParams(input) {
|
|
|
83330
83388
|
return {
|
|
83331
83389
|
mode: "payment",
|
|
83332
83390
|
// Stripe takes either a code field on its page or one discount up front.
|
|
83333
|
-
...input.promotionCodeId ? { discounts: [{ promotion_code: input.promotionCodeId }] } : { allow_promotion_codes:
|
|
83391
|
+
...input.promotionCodeId ? { discounts: [{ promotion_code: input.promotionCodeId }] } : { allow_promotion_codes: false },
|
|
83334
83392
|
customer: input.customerId,
|
|
83335
83393
|
customer_update: {
|
|
83336
83394
|
address: "auto",
|
|
@@ -83359,6 +83417,8 @@ function stripeCheckoutSessionCreateParams(input) {
|
|
|
83359
83417
|
}
|
|
83360
83418
|
],
|
|
83361
83419
|
metadata: {
|
|
83420
|
+
...creditScopeMetadata(input.promotionalScope),
|
|
83421
|
+
...input.couponId ? { opengeni_credit_offer_id: input.couponId } : {},
|
|
83362
83422
|
opengeni_account_id: input.accountId,
|
|
83363
83423
|
opengeni_credit_amount_usd: (input.amountCents / 100).toFixed(2),
|
|
83364
83424
|
opengeni_credit_micros: String(input.amountMicros),
|
|
@@ -83500,6 +83560,10 @@ async function grantCheckoutSessionCredits(deps, session, source) {
|
|
|
83500
83560
|
}
|
|
83501
83561
|
const credit = decision.credit;
|
|
83502
83562
|
const freeCouponCheckout = isFreeCouponCheckout(session);
|
|
83563
|
+
const promotionalScope = creditScopeFromMetadata(session.metadata);
|
|
83564
|
+
if (promotionalScope && !freeCouponCheckout) {
|
|
83565
|
+
throw new Error("Scoped promotional credits require a fully discounted checkout");
|
|
83566
|
+
}
|
|
83503
83567
|
if (!await getManagedAccount2(deps.db, credit.accountId)) {
|
|
83504
83568
|
console.info(
|
|
83505
83569
|
"[api] stripe webhook ignored a checkout session for an account not in this deployment",
|
|
@@ -83526,10 +83590,13 @@ async function grantCheckoutSessionCredits(deps, session, source) {
|
|
|
83526
83590
|
accountId: credit.accountId,
|
|
83527
83591
|
type: freeCouponCheckout ? "grant" : "credit_topup",
|
|
83528
83592
|
amountMicros: credit.amountMicros,
|
|
83593
|
+
eligibleModelIds: promotionalScope?.eligibleModelIds,
|
|
83529
83594
|
sourceType: freeCouponCheckout ? "stripe_checkout_coupon" : "stripe_checkout_session",
|
|
83530
83595
|
sourceId: session.id,
|
|
83531
83596
|
idempotencyKey: credit.idempotencyKey,
|
|
83532
83597
|
metadata: {
|
|
83598
|
+
...promotionalScope ? { creditOfferLabel: promotionalScope.label } : {},
|
|
83599
|
+
creditOfferId: session.metadata?.opengeni_credit_offer_id ?? null,
|
|
83533
83600
|
stripeEventId: source.stripeEventId,
|
|
83534
83601
|
stripePaymentIntentId: typeof session.payment_intent === "string" ? session.payment_intent : session.payment_intent?.id ?? null,
|
|
83535
83602
|
stripePackageId: credit.packageId,
|
|
@@ -83555,7 +83622,12 @@ async function resolveCheckoutPromotionCode(stripe, code) {
|
|
|
83555
83622
|
throw new HTTPException64(422, { message: "That code isn't valid or has expired." });
|
|
83556
83623
|
}
|
|
83557
83624
|
const amountOffCents = coupon.amount_off && coupon.currency === "usd" ? coupon.amount_off : coupon.currency_options?.usd?.amount_off ?? null;
|
|
83558
|
-
return {
|
|
83625
|
+
return {
|
|
83626
|
+
id: promotionCode.id,
|
|
83627
|
+
couponId: coupon.id,
|
|
83628
|
+
amountOffCents,
|
|
83629
|
+
percentOff: coupon.percent_off ?? null
|
|
83630
|
+
};
|
|
83559
83631
|
}
|
|
83560
83632
|
async function mirrorPaymentIntentCustomer(deps, event) {
|
|
83561
83633
|
const intent = event.data.object;
|
|
@@ -83637,18 +83709,26 @@ async function releaseDisputedCredits(deps, stripe, event) {
|
|
|
83637
83709
|
return;
|
|
83638
83710
|
}
|
|
83639
83711
|
const holdIdempotencyKey = `stripe:dispute_hold:${dispute.id}`;
|
|
83640
|
-
if (!await hasCreditLedgerEntry(deps.db, accountId, holdIdempotencyKey)) {
|
|
83641
|
-
return;
|
|
83642
|
-
}
|
|
83643
83712
|
const debitMicros = await creditAdjustmentMicros(deps, metadata, dispute.amount);
|
|
83644
|
-
await
|
|
83645
|
-
|
|
83646
|
-
|
|
83647
|
-
|
|
83648
|
-
|
|
83649
|
-
|
|
83650
|
-
|
|
83651
|
-
|
|
83713
|
+
await withRlsContext2(deps.db, { accountId }, async (tx) => {
|
|
83714
|
+
await applyCreditLedgerEntry(tx, {
|
|
83715
|
+
accountId,
|
|
83716
|
+
type: "credit_dispute_hold",
|
|
83717
|
+
amountMicros: -debitMicros,
|
|
83718
|
+
sourceType: "stripe_dispute",
|
|
83719
|
+
sourceId: dispute.id,
|
|
83720
|
+
idempotencyKey: holdIdempotencyKey,
|
|
83721
|
+
metadata: { stripeDisputeId: dispute.id, stripeEventType: event.type }
|
|
83722
|
+
});
|
|
83723
|
+
await applyCreditLedgerEntry(tx, {
|
|
83724
|
+
accountId,
|
|
83725
|
+
type: "credit_dispute_release",
|
|
83726
|
+
amountMicros: debitMicros,
|
|
83727
|
+
sourceType: "stripe_dispute",
|
|
83728
|
+
sourceId: dispute.id,
|
|
83729
|
+
idempotencyKey: `stripe:dispute_release:${dispute.id}`,
|
|
83730
|
+
metadata: { stripeDisputeId: dispute.id, stripeEventType: event.type }
|
|
83731
|
+
});
|
|
83652
83732
|
});
|
|
83653
83733
|
}
|
|
83654
83734
|
async function creditAdjustmentMicros(deps, metadata, amountCents) {
|
|
@@ -91702,9 +91782,9 @@ async function requireGitHubManageGrant(c, deps, workspaceId, expectedState) {
|
|
|
91702
91782
|
}
|
|
91703
91783
|
}
|
|
91704
91784
|
function allCookieValues(c, name) {
|
|
91705
|
-
const
|
|
91706
|
-
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(
|
|
91707
|
-
const raw = part.slice(
|
|
91785
|
+
const prefix2 = `${name}=`;
|
|
91786
|
+
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(prefix2)).map((part) => {
|
|
91787
|
+
const raw = part.slice(prefix2.length);
|
|
91708
91788
|
try {
|
|
91709
91789
|
return decodeURIComponent(raw);
|
|
91710
91790
|
} catch {
|
|
@@ -96472,12 +96552,12 @@ function requireStateCookie(c, state) {
|
|
|
96472
96552
|
}
|
|
96473
96553
|
}
|
|
96474
96554
|
function allCookieValues2(c, name) {
|
|
96475
|
-
const
|
|
96476
|
-
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(
|
|
96555
|
+
const prefix2 = `${name}=`;
|
|
96556
|
+
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(prefix2)).map((part) => {
|
|
96477
96557
|
try {
|
|
96478
|
-
return decodeURIComponent(part.slice(
|
|
96558
|
+
return decodeURIComponent(part.slice(prefix2.length));
|
|
96479
96559
|
} catch {
|
|
96480
|
-
return part.slice(
|
|
96560
|
+
return part.slice(prefix2.length);
|
|
96481
96561
|
}
|
|
96482
96562
|
});
|
|
96483
96563
|
}
|
|
@@ -100099,9 +100179,9 @@ function openGeniRealtimeInstructions(additional) {
|
|
|
100099
100179
|
const trimmed = additional?.trim();
|
|
100100
100180
|
if (!trimmed) return OPENGENI_REALTIME_BASE_INSTRUCTIONS;
|
|
100101
100181
|
const heading = "\n\n## Additional realtime guidance\nFollow the guidance below for this conversation unless it conflicts with the operating, delegation, safety, permission, or context-handling rules above.\n";
|
|
100102
|
-
const
|
|
100103
|
-
const remaining = REALTIME_INSTRUCTIONS_MAX_BYTES - Buffer.byteLength(
|
|
100104
|
-
return `${
|
|
100182
|
+
const prefix2 = `${OPENGENI_REALTIME_BASE_INSTRUCTIONS}${heading}`;
|
|
100183
|
+
const remaining = REALTIME_INSTRUCTIONS_MAX_BYTES - Buffer.byteLength(prefix2, "utf8");
|
|
100184
|
+
return `${prefix2}${takeUtf8Head(trimmed, Math.max(0, remaining))}`;
|
|
100105
100185
|
}
|
|
100106
100186
|
function takeUtf8Head(value, maximumBytes) {
|
|
100107
100187
|
if (Buffer.byteLength(value, "utf8") <= maximumBytes) return value;
|
|
@@ -106311,6 +106391,8 @@ import {
|
|
|
106311
106391
|
import { loadWorkspaceCodexModelAvailability } from "@opengeni/core";
|
|
106312
106392
|
import {
|
|
106313
106393
|
allWorkspacePermissions,
|
|
106394
|
+
getBillingBalance as getBillingBalance2,
|
|
106395
|
+
spendableCreditMicros,
|
|
106314
106396
|
createWorkspace,
|
|
106315
106397
|
ensureWorkspaceByExternalIdentity,
|
|
106316
106398
|
findWorkspaceByExternalIdentity as findWorkspaceByExternalIdentity2,
|
|
@@ -106905,25 +106987,31 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
106905
106987
|
organizationOpenRouterCustomModels: organizationProviders.openrouter.models
|
|
106906
106988
|
});
|
|
106907
106989
|
const workspaceSettings = workspace?.settings ?? {};
|
|
106990
|
+
const creditBalance = deps.settings.billingMode === "stripe" ? await getBillingBalance2(deps.db, grant.accountId) : void 0;
|
|
106908
106991
|
const defaultSelection = await resolveDefaultSessionModelForSelections(deps.db, {
|
|
106909
106992
|
settings: workspaceCatalogSettings,
|
|
106910
106993
|
accountId: grant.accountId,
|
|
106911
106994
|
workspaceSettings,
|
|
106912
106995
|
selections
|
|
106913
106996
|
});
|
|
106997
|
+
const catalog = projectWorkspaceModelCatalog(selections, {
|
|
106998
|
+
defaultSelection,
|
|
106999
|
+
creditsSelection: creditsDefaultSessionModel({
|
|
107000
|
+
settings: workspaceCatalogSettings,
|
|
107001
|
+
selections,
|
|
107002
|
+
workspaceSettings
|
|
107003
|
+
})
|
|
107004
|
+
});
|
|
107005
|
+
if (creditBalance) {
|
|
107006
|
+
for (const model of catalog.models) {
|
|
107007
|
+
if (model.cost !== "credits") continue;
|
|
107008
|
+
model.creditFunding = creditBalance.promotionalCredits?.some(
|
|
107009
|
+
(credit) => credit.remainingMicros > 0 && credit.eligibleModelIds.includes(model.id)
|
|
107010
|
+
) ? "promotional" : spendableCreditMicros(creditBalance, model.id) > 0 ? "general" : "unavailable";
|
|
107011
|
+
}
|
|
107012
|
+
}
|
|
106914
107013
|
c.header("cache-control", "private, no-store");
|
|
106915
|
-
return c.json(
|
|
106916
|
-
WorkspaceModelCatalogResponse2.parse(
|
|
106917
|
-
projectWorkspaceModelCatalog(selections, {
|
|
106918
|
-
defaultSelection,
|
|
106919
|
-
creditsSelection: creditsDefaultSessionModel({
|
|
106920
|
-
settings: workspaceCatalogSettings,
|
|
106921
|
-
selections,
|
|
106922
|
-
workspaceSettings
|
|
106923
|
-
})
|
|
106924
|
-
})
|
|
106925
|
-
)
|
|
106926
|
-
);
|
|
107014
|
+
return c.json(WorkspaceModelCatalogResponse2.parse(catalog));
|
|
106927
107015
|
});
|
|
106928
107016
|
app.get("/v1/workspaces/:workspaceId/gateway-custom-models", async (c) => {
|
|
106929
107017
|
const workspaceId = c.req.param("workspaceId");
|
|
@@ -111974,7 +112062,7 @@ import {
|
|
|
111974
112062
|
hasEditableArtifactSessionLink as hasEditableArtifactSessionLink2,
|
|
111975
112063
|
hasWorkspaceArtifactSessionLink,
|
|
111976
112064
|
transactionallyAuthorizeEditableArtifactActor,
|
|
111977
|
-
withRlsContext as
|
|
112065
|
+
withRlsContext as withRlsContext3
|
|
111978
112066
|
} from "@opengeni/db";
|
|
111979
112067
|
import { HTTPException as HTTPException106 } from "hono/http-exception";
|
|
111980
112068
|
import { z as z54 } from "zod";
|
|
@@ -112005,7 +112093,7 @@ function registerSessionArtifactAssociationRoutes(app, deps) {
|
|
|
112005
112093
|
const linked = kind === "editable" ? await hasEditableArtifactSessionLink2(deps.db, scope, sessionId, artifactId2) : await hasWorkspaceArtifactSessionLink(deps.db, workspaceId, sessionId, artifactId2);
|
|
112006
112094
|
if (!linked) throw new HTTPException106(404, { message: "Artifact association not found" });
|
|
112007
112095
|
if (kind === "editable") {
|
|
112008
|
-
const decision = await
|
|
112096
|
+
const decision = await withRlsContext3(
|
|
112009
112097
|
deps.db,
|
|
112010
112098
|
scope,
|
|
112011
112099
|
(tx) => transactionallyAuthorizeEditableArtifactActor(tx, {
|
|
@@ -113138,8 +113226,8 @@ function setTransactionCookie(context, deps, transactionId, transactionSecret) {
|
|
|
113138
113226
|
}
|
|
113139
113227
|
function requireTransactionSecret(context, transactionId) {
|
|
113140
113228
|
const value = getCookie(context, MANAGED_AUTH_LOGIN_TRANSACTION_COOKIE);
|
|
113141
|
-
const
|
|
113142
|
-
const secret = value?.startsWith(
|
|
113229
|
+
const prefix2 = `${transactionId}.`;
|
|
113230
|
+
const secret = value?.startsWith(prefix2) ? value.slice(prefix2.length) : null;
|
|
113143
113231
|
if (!secret || !/^[A-Za-z0-9_-]{43}$/.test(secret)) {
|
|
113144
113232
|
throw managedAuthApiError(401, "invalid_transaction");
|
|
113145
113233
|
}
|
|
@@ -113739,6 +113827,7 @@ function registerCanonicalHumanIdentityRoutes(app, deps) {
|
|
|
113739
113827
|
}
|
|
113740
113828
|
|
|
113741
113829
|
// src/routes/organization-memberships.ts
|
|
113830
|
+
import { signupCreditModelIds } from "@opengeni/config";
|
|
113742
113831
|
import {
|
|
113743
113832
|
lookupExternalIdentityForRequest,
|
|
113744
113833
|
cancelExternalWorkspaceMemberGrantForRequest,
|
|
@@ -113985,6 +114074,7 @@ function registerOrganizationMembershipRoutes(app, deps) {
|
|
|
113985
114074
|
subjectId,
|
|
113986
114075
|
subjectLabel: session.user.email || session.user.name,
|
|
113987
114076
|
...payload,
|
|
114077
|
+
trialCreditModelIds: signupCreditModelIds(deps.settings),
|
|
113988
114078
|
trialCreditsEnabled: deps.settings.productAccessMode === "managed" && deps.settings.verifiedSignupTrialCreditsEnabled
|
|
113989
114079
|
})
|
|
113990
114080
|
),
|
|
@@ -115156,6 +115246,7 @@ function registerOrganizationRecoveryRoutes(app, deps, services = productionServ
|
|
|
115156
115246
|
}
|
|
115157
115247
|
|
|
115158
115248
|
// src/routes/managed-onboarding.ts
|
|
115249
|
+
import { signupCreditModelIds as signupCreditModelIds2 } from "@opengeni/config";
|
|
115159
115250
|
import {
|
|
115160
115251
|
CompleteSelfServiceOrganizationSetupRequest,
|
|
115161
115252
|
CompleteSelfServiceOrganizationSetupResponse,
|
|
@@ -115216,6 +115307,7 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
115216
115307
|
organizationName,
|
|
115217
115308
|
operationId: parsed.data.operationId,
|
|
115218
115309
|
requestFingerprint,
|
|
115310
|
+
trialCreditModelIds: signupCreditModelIds2(deps.settings),
|
|
115219
115311
|
trialCreditsEnabled: deps.settings.productAccessMode === "managed" && deps.settings.verifiedSignupTrialCreditsEnabled
|
|
115220
115312
|
})
|
|
115221
115313
|
);
|
|
@@ -116531,14 +116623,14 @@ function resolveSlackWorkspaceRoute(input) {
|
|
|
116531
116623
|
source: "thread"
|
|
116532
116624
|
};
|
|
116533
116625
|
}
|
|
116534
|
-
const
|
|
116535
|
-
if (
|
|
116536
|
-
const named = matchCandidate(candidates,
|
|
116626
|
+
const prefix2 = AUTHORED_BY_INVOKER.has(input.entry.triggerKind) ? parseSlackWorkspacePrefix(splitSlackLeadingMention(input.entry.text, input.botUserId).rest) : null;
|
|
116627
|
+
if (prefix2) {
|
|
116628
|
+
const named = matchCandidate(candidates, prefix2.requested);
|
|
116537
116629
|
if (named === "ambiguous" || !named) {
|
|
116538
116630
|
return {
|
|
116539
116631
|
kind: "denied",
|
|
116540
116632
|
reason: "no_access_to_named",
|
|
116541
|
-
requested:
|
|
116633
|
+
requested: prefix2.requested,
|
|
116542
116634
|
candidates
|
|
116543
116635
|
};
|
|
116544
116636
|
}
|
|
@@ -122415,10 +122507,10 @@ function createAppComposition(deps) {
|
|
|
122415
122507
|
const workspaceId = c.req.param("workspaceId");
|
|
122416
122508
|
const grant = await requireAccessGrant53(c, routeDeps, workspaceId);
|
|
122417
122509
|
const url = new URL(c.req.url);
|
|
122418
|
-
const
|
|
122510
|
+
const prefix2 = `/v1/workspaces/${workspaceId}/codemode/sdk`;
|
|
122419
122511
|
let forwarded;
|
|
122420
122512
|
try {
|
|
122421
|
-
const path = url.pathname.slice(
|
|
122513
|
+
const path = url.pathname.slice(prefix2.length) + url.search;
|
|
122422
122514
|
forwarded = await codemodeSessionRequest(routeDeps, grant, c.req.raw, path, (session) => {
|
|
122423
122515
|
assertConfiguredCodemodeSessionProxyPath(session, path, c.req.method);
|
|
122424
122516
|
const proxyTools = configuredCodemodeSessionProxyTools(routeDeps.settings, session);
|
|
@@ -124045,4 +124137,4 @@ export {
|
|
|
124045
124137
|
withDefaultEnabledCapabilityMcpTools,
|
|
124046
124138
|
workflowIdForSession4 as workflowIdForSession
|
|
124047
124139
|
};
|
|
124048
|
-
//# sourceMappingURL=chunk-
|
|
124140
|
+
//# sourceMappingURL=chunk-BAZXDFT2.js.map
|