@opengeni/core 1.0.2 → 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/billing/agent-run-admission.d.ts +17 -0
- package/dist/default-session-model.d.ts +5 -3
- package/dist/dependencies.d.ts +3 -1
- package/dist/domain/knowledge-messages.d.ts +2 -2
- package/dist/goal-admission.d.ts +488 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +287 -52
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
- package/src/application/session-tenancy.ts +4 -8
- package/src/application/user-resource-grants.ts +0 -13
- package/src/billing/agent-run-admission.ts +107 -0
- package/src/billing/limits.ts +14 -3
- package/src/default-session-model.ts +23 -12
- package/src/dependencies.ts +3 -0
- package/src/domain/knowledge-search.test.ts +1 -1
- package/src/domain/knowledge-search.ts +2 -2
- package/src/domain/session-tool-policy.ts +14 -5
- package/src/domain/sessions.ts +11 -6
- package/src/goal-admission.ts +187 -0
- package/src/index.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -4826,7 +4826,7 @@ function withDeveloperSetupCredentialRestriction(policy, source) {
|
|
|
4826
4826
|
import {
|
|
4827
4827
|
CLAUDE_CONNECTION_KINDS as CLAUDE_CONNECTION_KINDS3,
|
|
4828
4828
|
claudeProviderId as claudeProviderId2,
|
|
4829
|
-
canonicalizeConfiguredModelId as
|
|
4829
|
+
canonicalizeConfiguredModelId as canonicalizeConfiguredModelId3,
|
|
4830
4830
|
configuredAllowedModels,
|
|
4831
4831
|
withCodexCatalogProvider as withCodexCatalogProvider3,
|
|
4832
4832
|
ORGANIZATION_GATEWAY_MODEL_ID_PREFIX as ORGANIZATION_GATEWAY_MODEL_ID_PREFIX2,
|
|
@@ -4856,6 +4856,7 @@ import {
|
|
|
4856
4856
|
OPENGENI_SLACK_BOT_SESSION_METADATA_KEY as OPENGENI_SLACK_BOT_SESSION_METADATA_KEY2,
|
|
4857
4857
|
SessionSkills,
|
|
4858
4858
|
resolveBundledSkillSelection,
|
|
4859
|
+
bundledSkillSelectionForAgentConfig as bundledSkillSelectionForAgentConfig2,
|
|
4859
4860
|
SessionSpawnDenial,
|
|
4860
4861
|
ServiceTurnInitiator,
|
|
4861
4862
|
ServiceTurnInitiatorContext as ServiceTurnInitiatorContext2,
|
|
@@ -4922,7 +4923,6 @@ import {
|
|
|
4922
4923
|
SessionToolPolicyVersionConflictError,
|
|
4923
4924
|
SessionCreateIdempotencyConflictError,
|
|
4924
4925
|
PersonalResourceAttachmentAcceptanceError,
|
|
4925
|
-
sessionTenancyProductActivated as sessionTenancyProductActivated2,
|
|
4926
4926
|
workspaceControlRequestLockTimeoutMs,
|
|
4927
4927
|
WorkspaceControlBusyError
|
|
4928
4928
|
} from "@opengeni/db";
|
|
@@ -5088,6 +5088,7 @@ function prepareExternalLinkTaskAdmission(authorization, actor) {
|
|
|
5088
5088
|
// src/billing/limits.ts
|
|
5089
5089
|
import {
|
|
5090
5090
|
configuredStaticUsageLimits,
|
|
5091
|
+
canonicalizeConfiguredModelId,
|
|
5091
5092
|
resolveModelProviderForTurn
|
|
5092
5093
|
} from "@opengeni/config";
|
|
5093
5094
|
import {
|
|
@@ -5096,7 +5097,7 @@ import {
|
|
|
5096
5097
|
countActiveOrganizationApiKeysForAccount,
|
|
5097
5098
|
countScheduledTasksForWorkspace,
|
|
5098
5099
|
countWorkspacesForAccount,
|
|
5099
|
-
|
|
5100
|
+
getSpendableCreditBalance,
|
|
5100
5101
|
isCodexBilledTurn,
|
|
5101
5102
|
recordUsageEvent,
|
|
5102
5103
|
sumUsageQuantity
|
|
@@ -5177,11 +5178,19 @@ async function checkCreditBalance(deps, input, externallyBilled) {
|
|
|
5177
5178
|
if (!usesCreditLimits(deps) || !isCostlyAction(input.action)) {
|
|
5178
5179
|
return { allowed: true };
|
|
5179
5180
|
}
|
|
5180
|
-
const balance = await
|
|
5181
|
+
const balance = await getSpendableCreditBalance(
|
|
5182
|
+
deps.db,
|
|
5183
|
+
input.accountId,
|
|
5184
|
+
input.model ? canonicalizeConfiguredModelId(deps.settings, input.model) : void 0
|
|
5185
|
+
);
|
|
5181
5186
|
if (balance.balanceMicros > 0) {
|
|
5182
5187
|
return { allowed: true };
|
|
5183
5188
|
}
|
|
5184
|
-
return {
|
|
5189
|
+
return {
|
|
5190
|
+
allowed: false,
|
|
5191
|
+
code: "insufficient_credits",
|
|
5192
|
+
message: input.model ? "No credits available for this model. Choose a model covered by your promotional credits or add credits." : "No general credits available. Promotional credits cover eligible models only."
|
|
5193
|
+
};
|
|
5185
5194
|
}
|
|
5186
5195
|
async function checkStaticCaps(deps, input, funding) {
|
|
5187
5196
|
const limits = configuredStaticUsageLimits(deps.settings);
|
|
@@ -7213,7 +7222,7 @@ function resolveWorkspaceModelSelection(input) {
|
|
|
7213
7222
|
|
|
7214
7223
|
// src/default-session-model.ts
|
|
7215
7224
|
import {
|
|
7216
|
-
canonicalizeConfiguredModelId,
|
|
7225
|
+
canonicalizeConfiguredModelId as canonicalizeConfiguredModelId2,
|
|
7217
7226
|
CLAUDE_CONNECTION_KINDS as CLAUDE_CONNECTION_KINDS2
|
|
7218
7227
|
} from "@opengeni/config";
|
|
7219
7228
|
import {
|
|
@@ -7235,7 +7244,8 @@ import {
|
|
|
7235
7244
|
workspaceCodexSubscriptionActive,
|
|
7236
7245
|
workspaceOpenRouterConnectionActive,
|
|
7237
7246
|
workspaceVercelAiGatewayConnectionActive,
|
|
7238
|
-
|
|
7247
|
+
getBillingBalance,
|
|
7248
|
+
spendableCreditMicros,
|
|
7239
7249
|
workspaceXaiSubscriptionActive,
|
|
7240
7250
|
workspaceXaiSubscriptionActiveForAuthority,
|
|
7241
7251
|
XaiAuthorityPoolInactiveError,
|
|
@@ -7371,9 +7381,12 @@ function findSelection(selections, modelId) {
|
|
|
7371
7381
|
return selections.find((selection) => selection.model.id === modelId) ?? selections.find((selection) => selection.model.aliases.includes(modelId));
|
|
7372
7382
|
}
|
|
7373
7383
|
function creditsCandidate(input) {
|
|
7384
|
+
const selections = input.creditBalance ? input.selections.filter(
|
|
7385
|
+
(selection) => spendableCreditMicros(input.creditBalance, selection.model.id) > 0
|
|
7386
|
+
) : input.selections;
|
|
7374
7387
|
const fallbackEffort = input.settings.openaiReasoningEffort;
|
|
7375
|
-
const deployment = findSelection(
|
|
7376
|
-
const configured = findSelection(
|
|
7388
|
+
const deployment = findSelection(selections, input.settings.openaiModel);
|
|
7389
|
+
const configured = findSelection(selections, input.settings.creditsDefaultModel);
|
|
7377
7390
|
if (deployment?.availability.selectable && deployment.model.cost === "credits") {
|
|
7378
7391
|
if (configured?.model.id !== deployment.model.id) return null;
|
|
7379
7392
|
return {
|
|
@@ -7397,7 +7410,7 @@ function creditsCandidate(input) {
|
|
|
7397
7410
|
source: "credits"
|
|
7398
7411
|
};
|
|
7399
7412
|
}
|
|
7400
|
-
const first =
|
|
7413
|
+
const first = selections.find(
|
|
7401
7414
|
(selection) => selection.availability.selectable && selection.model.cost === "credits"
|
|
7402
7415
|
);
|
|
7403
7416
|
return first ? {
|
|
@@ -7446,7 +7459,7 @@ function selectDefaultSessionModel(input) {
|
|
|
7446
7459
|
reasoningEffort: defaultReasoningEffortForConfiguredModel(fallback.model, fallbackEffort),
|
|
7447
7460
|
source: "deployment"
|
|
7448
7461
|
} : {
|
|
7449
|
-
model:
|
|
7462
|
+
model: canonicalizeConfiguredModelId2(input.settings, input.settings.openaiModel),
|
|
7450
7463
|
reasoningEffort: fallbackEffort,
|
|
7451
7464
|
source: "deployment"
|
|
7452
7465
|
};
|
|
@@ -7457,7 +7470,8 @@ function creditsDefaultSessionModel(input) {
|
|
|
7457
7470
|
settings: input.settings,
|
|
7458
7471
|
selections: input.selections,
|
|
7459
7472
|
workspaceDefaults: resolveWorkspaceSessionDefaults(input.workspaceSettings),
|
|
7460
|
-
creditsAvailable: true
|
|
7473
|
+
creditsAvailable: true,
|
|
7474
|
+
...input.creditBalance ? { creditBalance: input.creditBalance } : {}
|
|
7461
7475
|
});
|
|
7462
7476
|
}
|
|
7463
7477
|
async function resolveDefaultSessionModelForSelections(db, input) {
|
|
@@ -7467,10 +7481,13 @@ async function resolveDefaultSessionModelForSelections(db, input) {
|
|
|
7467
7481
|
workspaceDefaults: resolveWorkspaceSessionDefaults(input.workspaceSettings)
|
|
7468
7482
|
};
|
|
7469
7483
|
const withoutCredits = selectDefaultSessionModel({ ...decision, creditsAvailable: false });
|
|
7470
|
-
if (withoutCredits.source !== "deployment" || input.settings.billingMode !== "stripe" ||
|
|
7484
|
+
if (withoutCredits.source !== "deployment" || input.settings.billingMode !== "stripe" || !input.selections.some(
|
|
7485
|
+
(selection) => selection.availability.selectable && selection.model.cost === "credits"
|
|
7486
|
+
)) {
|
|
7471
7487
|
return withoutCredits;
|
|
7472
7488
|
}
|
|
7473
|
-
|
|
7489
|
+
const creditBalance = await getBillingBalance(db, input.accountId);
|
|
7490
|
+
return selectDefaultSessionModel({ ...decision, creditsAvailable: true, creditBalance });
|
|
7474
7491
|
}
|
|
7475
7492
|
async function connectionRestrictionsAndXaiReadiness(db, settings, context) {
|
|
7476
7493
|
const { workspaceId, subjectId, xaiAuthoritySnapshot } = context;
|
|
@@ -7788,6 +7805,7 @@ import {
|
|
|
7788
7805
|
import {
|
|
7789
7806
|
AGENT_SKILL_MANAGE_TOOL_NAMES,
|
|
7790
7807
|
AUTOMATIC_SESSION_TITLE_FALLBACK,
|
|
7808
|
+
bundledSkillSelectionForAgentConfig,
|
|
7791
7809
|
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
|
|
7792
7810
|
FIRST_PARTY_IN_PROCESS_TOOL_NAMES,
|
|
7793
7811
|
SESSION_EFFECTIVE_TOOL_POLICY_ID_LIMIT,
|
|
@@ -8023,13 +8041,17 @@ async function workspaceSessionEffectiveToolsContext(deps, workspaceId, subjectI
|
|
|
8023
8041
|
}
|
|
8024
8042
|
function sessionHasSkills(session, context) {
|
|
8025
8043
|
if (context.hasWorkspaceSkills || session.skills.length > 0) return true;
|
|
8026
|
-
|
|
8044
|
+
const bundledSkillIds = bundledSkillSelectionForAgentConfig(
|
|
8045
|
+
session.bundledSkillIds,
|
|
8046
|
+
session.agent
|
|
8047
|
+
);
|
|
8048
|
+
if (bundledSkillIds === void 0) return true;
|
|
8027
8049
|
const tools = new Set(
|
|
8028
8050
|
resolveAgentToolFamilies(session.agent).firstPartyTools(
|
|
8029
8051
|
allowedFirstPartyMcpToolsForSession2(context.settings, session.firstPartyMcpTools)
|
|
8030
8052
|
)
|
|
8031
8053
|
);
|
|
8032
|
-
return
|
|
8054
|
+
return bundledSkillIds.some((id) => {
|
|
8033
8055
|
if ([
|
|
8034
8056
|
"builtin:opengeni-documents",
|
|
8035
8057
|
"builtin:opengeni-spreadsheets",
|
|
@@ -8078,7 +8100,7 @@ function sessionEffectiveToolProjectionInput(session, toolRefs, context) {
|
|
|
8078
8100
|
) && session.sandboxOs !== "windows" ? ["code_search"] : []
|
|
8079
8101
|
] : [];
|
|
8080
8102
|
const needsTitle = session.titleSource !== "user" && (!session.title?.trim() || session.title.trim() === AUTOMATIC_SESSION_TITLE_FALLBACK);
|
|
8081
|
-
const firstPartyMcpTools = context && toolRefs.some((ref) => ref.id === "opengeni") ? resolveAgentToolFamilies(session.agent).firstPartyTools(
|
|
8103
|
+
const firstPartyMcpTools = context && toolRefs.some((ref) => ref.id === "opengeni") ? resolveAgentToolFamilies(session.agent, { sandboxAttached: sandboxAvailable }).firstPartyTools(
|
|
8082
8104
|
allowedFirstPartyMcpToolsForSession2(context.settings, session.firstPartyMcpTools)
|
|
8083
8105
|
).filter((name) => name !== "set_session_title" || !needsTitle) : [];
|
|
8084
8106
|
const interactionNames = new Set(FIRST_PARTY_IN_PROCESS_TOOL_NAMES);
|
|
@@ -8101,7 +8123,9 @@ function sessionEffectiveToolProjectionInput(session, toolRefs, context) {
|
|
|
8101
8123
|
].includes(name);
|
|
8102
8124
|
if (permissionAllowed(readOnly ? "sessions:read" : "sessions:control") && (name !== "browser_download_save" || permissionAllowed("files:upload"))) {
|
|
8103
8125
|
firstPartyModelNames.set(name, `interaction__${name}`);
|
|
8104
|
-
if (!firstPartyMcpTools.includes(name) && resolveAgentToolFamilies(session.agent
|
|
8126
|
+
if (!firstPartyMcpTools.includes(name) && resolveAgentToolFamilies(session.agent, {
|
|
8127
|
+
sandboxAttached: sandboxAvailable
|
|
8128
|
+
}).allowsFirstPartyTool(name) && session.firstPartyMcpTools.includes(name))
|
|
8105
8129
|
firstPartyMcpTools.push(name);
|
|
8106
8130
|
}
|
|
8107
8131
|
}
|
|
@@ -8132,7 +8156,8 @@ function sessionEffectiveToolProjectionInput(session, toolRefs, context) {
|
|
|
8132
8156
|
webSearch: hostedToolNames.includes("web_search"),
|
|
8133
8157
|
humanInput: context?.humanInputEnabled ?? false,
|
|
8134
8158
|
media: media.toolsKnown ? media.hosted.length + media.runtime.length > 0 : void 0,
|
|
8135
|
-
routerInHistory: context?.routerInHistory === true || context?.routerHistorySessionIds?.has(session.id) === true
|
|
8159
|
+
routerInHistory: context?.routerInHistory === true || context?.routerHistorySessionIds?.has(session.id) === true,
|
|
8160
|
+
...context ? { sandboxAttached: sandboxAvailable } : {}
|
|
8136
8161
|
};
|
|
8137
8162
|
const families = resolveAgentToolFamilies(session.agent, environment);
|
|
8138
8163
|
environment.hasDeferredTools = toolRefs.some(
|
|
@@ -8538,10 +8563,8 @@ import {
|
|
|
8538
8563
|
isRetryableDatabaseTransportFailure,
|
|
8539
8564
|
nestedPostgresSqlState as nestedPostgresSqlState3,
|
|
8540
8565
|
replayAppliedSessionFork,
|
|
8541
|
-
sessionTenancyProductActivated,
|
|
8542
8566
|
SessionTenancyAccessError,
|
|
8543
8567
|
SessionTenancyInvalidRequestError,
|
|
8544
|
-
SessionTenancyNotActivatedError,
|
|
8545
8568
|
transitionSessionVisibility
|
|
8546
8569
|
} from "@opengeni/db";
|
|
8547
8570
|
import { publishDurableSessionEvents } from "@opengeni/events";
|
|
@@ -8605,9 +8628,6 @@ async function requireManagedHumanPrivateSessionCreate(deps, authorization, work
|
|
|
8605
8628
|
async function requireSessionTenancyMutationGate(deps, authorization, workspaceId, permissions) {
|
|
8606
8629
|
requireVerifiedOwningUser(authorization, workspaceId);
|
|
8607
8630
|
for (const permission of permissions) requirePermission(authorization.grant, permission);
|
|
8608
|
-
if (!await sessionTenancyProductActivated(deps.db, workspaceId)) {
|
|
8609
|
-
throw new SessionTenancyNotActivatedError();
|
|
8610
|
-
}
|
|
8611
8631
|
}
|
|
8612
8632
|
async function publishExactCommittedEvent(deps, input) {
|
|
8613
8633
|
if (input.eventId === null && input.eventSequence === null) return;
|
|
@@ -8879,11 +8899,6 @@ async function requireAtomicPersonalResourceAttachment(deps, authorization, work
|
|
|
8879
8899
|
cause: error
|
|
8880
8900
|
});
|
|
8881
8901
|
}
|
|
8882
|
-
if (!await sessionTenancyProductActivated2(deps.db, workspaceId)) {
|
|
8883
|
-
throw new HTTPException17(409, {
|
|
8884
|
-
message: "Session tenancy is not activated for this organization."
|
|
8885
|
-
});
|
|
8886
|
-
}
|
|
8887
8902
|
if (existingSession && intent.expectedAuthorityEpoch === void 0) {
|
|
8888
8903
|
throw new HTTPException17(422, {
|
|
8889
8904
|
message: "Personal-resource attachment requires expectedAuthorityEpoch."
|
|
@@ -9248,6 +9263,13 @@ function automaticTitleForAgentChildCreate(presentation, goal, initialMessage) {
|
|
|
9248
9263
|
return null;
|
|
9249
9264
|
}
|
|
9250
9265
|
async function createAndStartSessionWithOutcome(input) {
|
|
9266
|
+
const frozenBundledSkillIds = bundledSkillSelectionForAgentConfig2(
|
|
9267
|
+
input.bundledSkillIds,
|
|
9268
|
+
input.agentConfig
|
|
9269
|
+
);
|
|
9270
|
+
if (frozenBundledSkillIds !== input.bundledSkillIds) {
|
|
9271
|
+
input = { ...input, bundledSkillIds: frozenBundledSkillIds };
|
|
9272
|
+
}
|
|
9251
9273
|
const sessionMetadata = metadataWithTurnExecutionPolicyV1(
|
|
9252
9274
|
{
|
|
9253
9275
|
...input.metadata,
|
|
@@ -9631,7 +9653,7 @@ function canonicalConfiguredModel(settings, model) {
|
|
|
9631
9653
|
if (model === null || model === void 0) {
|
|
9632
9654
|
return model;
|
|
9633
9655
|
}
|
|
9634
|
-
const canonicalModel =
|
|
9656
|
+
const canonicalModel = canonicalizeConfiguredModelId3(settings, model);
|
|
9635
9657
|
if (canonicalModel.startsWith(CODEX_MODEL_ID_PREFIX) && settings.resolvedCodexModelsJson !== void 0) {
|
|
9636
9658
|
if (settings.codexSubscriptionEnabled && configuredAllowedModels(withCodexCatalogProvider3(settings)).includes(canonicalModel)) {
|
|
9637
9659
|
return canonicalModel;
|
|
@@ -10253,6 +10275,7 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
|
|
|
10253
10275
|
if (agentResolution.instructions !== void 0) {
|
|
10254
10276
|
payload.instructions = agentResolution.instructions;
|
|
10255
10277
|
}
|
|
10278
|
+
bundledSkillIds = bundledSkillSelectionForAgentConfig2(bundledSkillIds, agentConfig);
|
|
10256
10279
|
const parentCallingTurn = parentSession && creationInitiator.actor ? await getSessionTurnForAttempt3(
|
|
10257
10280
|
db,
|
|
10258
10281
|
workspaceId,
|
|
@@ -12391,7 +12414,7 @@ import {
|
|
|
12391
12414
|
applyCreditDebitAfterUse,
|
|
12392
12415
|
checkWorkspaceAllowance as checkWorkspaceAllowance2,
|
|
12393
12416
|
creditDebitAttributionForTurn,
|
|
12394
|
-
|
|
12417
|
+
getSpendableCreditBalance as getSpendableCreditBalance2,
|
|
12395
12418
|
listKnowledgeEntries,
|
|
12396
12419
|
recordUsageEvent as recordUsageEvent2,
|
|
12397
12420
|
sumUsageQuantity as sumUsageQuantity2,
|
|
@@ -12521,7 +12544,7 @@ async function searchKnowledgeEntries(db, context, input, embedder, settings) {
|
|
|
12521
12544
|
context.accountId,
|
|
12522
12545
|
context.workspaceId,
|
|
12523
12546
|
async (lockedDb) => {
|
|
12524
|
-
const balance = await
|
|
12547
|
+
const balance = await getSpendableCreditBalance2(lockedDb, context.accountId);
|
|
12525
12548
|
if (balance.balanceMicros <= 0)
|
|
12526
12549
|
return keywordFallback(lockedDb, new KnowledgeVectorFundingError(), "awaiting_funding");
|
|
12527
12550
|
const attribution = billingActor.kind === "agent" ? await creditDebitAttributionForTurn(lockedDb, {
|
|
@@ -12751,6 +12774,220 @@ function filenameForMimeType(mimeType) {
|
|
|
12751
12774
|
}
|
|
12752
12775
|
}
|
|
12753
12776
|
|
|
12777
|
+
// src/goal-admission.ts
|
|
12778
|
+
import {
|
|
12779
|
+
isModelAvailableForNewSelection as isModelAvailableForNewSelection2,
|
|
12780
|
+
policyProviderIdForModel as policyProviderIdForModel2,
|
|
12781
|
+
resolveModelProvider,
|
|
12782
|
+
runnableLatencyModesForModel,
|
|
12783
|
+
withCodexCatalogProvider as withCodexCatalogProvider4,
|
|
12784
|
+
withXaiSubscriptionCatalogProvider as withXaiSubscriptionCatalogProvider2
|
|
12785
|
+
} from "@opengeni/config";
|
|
12786
|
+
import {
|
|
12787
|
+
evaluateWorkspaceModelPolicy as evaluateWorkspaceModelPolicy3
|
|
12788
|
+
} from "@opengeni/contracts";
|
|
12789
|
+
import { isCodexBilledModel as isCodexBilledModel2 } from "@opengeni/codex";
|
|
12790
|
+
import { getWorkspaceModelPolicy as getWorkspaceModelPolicy3 } from "@opengeni/db";
|
|
12791
|
+
|
|
12792
|
+
// src/billing/agent-run-admission.ts
|
|
12793
|
+
import {
|
|
12794
|
+
canonicalizeConfiguredModelId as canonicalizeConfiguredModelId4,
|
|
12795
|
+
configuredStaticUsageLimits as configuredStaticUsageLimits2
|
|
12796
|
+
} from "@opengeni/config";
|
|
12797
|
+
import {
|
|
12798
|
+
checkWorkspaceAllowance as checkWorkspaceAllowance3,
|
|
12799
|
+
getSpendableCreditBalance as getSpendableCreditBalance3,
|
|
12800
|
+
isCodexBilledTurn as isCodexBilledTurn2,
|
|
12801
|
+
sumUsageQuantity as sumUsageQuantity3
|
|
12802
|
+
} from "@opengeni/db";
|
|
12803
|
+
async function agentRunAdmissionDenial(services, input) {
|
|
12804
|
+
const codexBilled = await isCodexBilledTurn2({
|
|
12805
|
+
db: services.db,
|
|
12806
|
+
settings: services.settings,
|
|
12807
|
+
workspaceId: input.workspaceId,
|
|
12808
|
+
model: input.model
|
|
12809
|
+
});
|
|
12810
|
+
const externallyBilled = modelFundingForAdmission(
|
|
12811
|
+
services.settings,
|
|
12812
|
+
input.model,
|
|
12813
|
+
codexBilled
|
|
12814
|
+
).fundedWithoutCredits;
|
|
12815
|
+
if (!externallyBilled && (services.settings.billingMode === "stripe" || services.settings.usageLimitsMode === "managed")) {
|
|
12816
|
+
if (services.entitlements) {
|
|
12817
|
+
const decision = await services.entitlements.admitRun({
|
|
12818
|
+
accountId: input.accountId,
|
|
12819
|
+
workspaceId: input.workspaceId,
|
|
12820
|
+
action: "agent_run:create",
|
|
12821
|
+
quantity: input.requestedAgentRuns
|
|
12822
|
+
});
|
|
12823
|
+
if (!decision.allowed) return "insufficient_credits";
|
|
12824
|
+
} else {
|
|
12825
|
+
const balance = await getSpendableCreditBalance3(
|
|
12826
|
+
services.db,
|
|
12827
|
+
input.accountId,
|
|
12828
|
+
canonicalizeConfiguredModelId4(services.settings, input.model)
|
|
12829
|
+
);
|
|
12830
|
+
if (balance.balanceMicros <= 0) return "insufficient_credits";
|
|
12831
|
+
}
|
|
12832
|
+
}
|
|
12833
|
+
if (!externallyBilled) {
|
|
12834
|
+
const refusal = await checkWorkspaceAllowance3(services.db, {
|
|
12835
|
+
accountId: input.accountId,
|
|
12836
|
+
workspaceId: input.workspaceId,
|
|
12837
|
+
subjectId: input.initiatingHumanSubjectId ?? null
|
|
12838
|
+
});
|
|
12839
|
+
if (refusal) return refusal.code;
|
|
12840
|
+
}
|
|
12841
|
+
if (services.settings.usageLimitsMode !== "static" && services.settings.usageLimitsMode !== "managed") {
|
|
12842
|
+
return null;
|
|
12843
|
+
}
|
|
12844
|
+
const limits = configuredStaticUsageLimits2(services.settings);
|
|
12845
|
+
if (!externallyBilled && limits.maxMonthlyCostMicrosPerAccount) {
|
|
12846
|
+
const used = await sumUsageQuantity3(services.db, {
|
|
12847
|
+
accountId: input.accountId,
|
|
12848
|
+
eventType: "model.cost",
|
|
12849
|
+
since: startOfUtcMonth2()
|
|
12850
|
+
});
|
|
12851
|
+
if (used >= limits.maxMonthlyCostMicrosPerAccount) {
|
|
12852
|
+
return "monthly_model_cost_limit";
|
|
12853
|
+
}
|
|
12854
|
+
}
|
|
12855
|
+
if (limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
12856
|
+
const used = await sumUsageQuantity3(services.db, {
|
|
12857
|
+
workspaceId: input.workspaceId,
|
|
12858
|
+
eventType: "agent_run.created",
|
|
12859
|
+
since: startOfUtcMonth2()
|
|
12860
|
+
});
|
|
12861
|
+
if (used + input.requestedAgentRuns > limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
12862
|
+
return "monthly_agent_run_limit";
|
|
12863
|
+
}
|
|
12864
|
+
}
|
|
12865
|
+
return null;
|
|
12866
|
+
}
|
|
12867
|
+
function startOfUtcMonth2() {
|
|
12868
|
+
const now = /* @__PURE__ */ new Date();
|
|
12869
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
|
|
12870
|
+
}
|
|
12871
|
+
|
|
12872
|
+
// src/goal-admission.ts
|
|
12873
|
+
function goalContinuationModelDecision(input) {
|
|
12874
|
+
const catalogSettings = input.settings.supergrokSubscriptionEnabled ? withXaiSubscriptionCatalogProvider2(
|
|
12875
|
+
input.settings.codexSubscriptionEnabled ? withCodexCatalogProvider4(input.settings) : input.settings
|
|
12876
|
+
) : input.settings.codexSubscriptionEnabled ? withCodexCatalogProvider4(input.settings) : input.settings;
|
|
12877
|
+
const model = input.inheritedModel;
|
|
12878
|
+
if (!resolveModelProvider(catalogSettings, model)) {
|
|
12879
|
+
return {
|
|
12880
|
+
model,
|
|
12881
|
+
blocked: "The selected model is unavailable. Choose an available model before resuming.",
|
|
12882
|
+
pausedReason: "model_unavailable"
|
|
12883
|
+
};
|
|
12884
|
+
}
|
|
12885
|
+
if (!isModelAvailableForNewSelection2(catalogSettings, model)) {
|
|
12886
|
+
return {
|
|
12887
|
+
model,
|
|
12888
|
+
blocked: "The selected model has been retired. Choose an available model before resuming.",
|
|
12889
|
+
pausedReason: "model_unavailable"
|
|
12890
|
+
};
|
|
12891
|
+
}
|
|
12892
|
+
if (input.workspaceModelPolicy !== null && !evaluateWorkspaceModelPolicy3(input.workspaceModelPolicy, {
|
|
12893
|
+
providerId: policyProviderIdForModel2(catalogSettings, model),
|
|
12894
|
+
modelId: model
|
|
12895
|
+
}).allowed) {
|
|
12896
|
+
return {
|
|
12897
|
+
model,
|
|
12898
|
+
blocked: "Workspace policy blocks the selected model. Choose an allowed model before resuming.",
|
|
12899
|
+
pausedReason: "model_policy"
|
|
12900
|
+
};
|
|
12901
|
+
}
|
|
12902
|
+
if (input.codexCompactionMode === "remote_v2" && !isCodexBilledModel2(model)) {
|
|
12903
|
+
return {
|
|
12904
|
+
model,
|
|
12905
|
+
blocked: "This conversation requires a Codex model. Choose a Codex model before resuming.",
|
|
12906
|
+
pausedReason: "model_policy"
|
|
12907
|
+
};
|
|
12908
|
+
}
|
|
12909
|
+
if (!runnableLatencyModesForModel(catalogSettings, model).includes(input.latencyMode ?? "standard")) {
|
|
12910
|
+
return {
|
|
12911
|
+
model,
|
|
12912
|
+
blocked: "The selected model does not support this conversation's latency mode. Choose a supported mode or model before resuming.",
|
|
12913
|
+
pausedReason: "model_policy"
|
|
12914
|
+
};
|
|
12915
|
+
}
|
|
12916
|
+
return { model, blocked: null };
|
|
12917
|
+
}
|
|
12918
|
+
async function resolveGoalModelAdmission(db, settings, input) {
|
|
12919
|
+
const catalog = await resolveWorkspaceCatalogSettings(db, settings, {
|
|
12920
|
+
accountId: input.accountId,
|
|
12921
|
+
workspaceId: input.workspaceId,
|
|
12922
|
+
retainedProductModelId: input.model
|
|
12923
|
+
});
|
|
12924
|
+
const workspaceModelPolicy = await getWorkspaceModelPolicy3(db, input.workspaceId);
|
|
12925
|
+
return {
|
|
12926
|
+
settings: catalog.settings,
|
|
12927
|
+
...goalContinuationModelDecision({
|
|
12928
|
+
settings: catalog.settings,
|
|
12929
|
+
workspaceModelPolicy,
|
|
12930
|
+
inheritedModel: input.model,
|
|
12931
|
+
...input.codexCompactionMode ? { codexCompactionMode: input.codexCompactionMode } : {},
|
|
12932
|
+
...input.latencyMode ? { latencyMode: input.latencyMode } : {}
|
|
12933
|
+
})
|
|
12934
|
+
};
|
|
12935
|
+
}
|
|
12936
|
+
async function goalRunBudgetBlocked(services, input) {
|
|
12937
|
+
const denial = await agentRunAdmissionDenial(services, { ...input, requestedAgentRuns: 1 });
|
|
12938
|
+
if (denial === null) return null;
|
|
12939
|
+
const blocks = {
|
|
12940
|
+
insufficient_credits: services.entitlements ? {
|
|
12941
|
+
pausedReason: "usage_policy",
|
|
12942
|
+
message: "The application's usage policy blocks another run. Resume when it allows."
|
|
12943
|
+
} : {
|
|
12944
|
+
pausedReason: "credits",
|
|
12945
|
+
message: "Insufficient Opengeni credits. Add credits before resuming."
|
|
12946
|
+
},
|
|
12947
|
+
allowance_exhausted: {
|
|
12948
|
+
pausedReason: "allowance",
|
|
12949
|
+
message: "Opengeni usage allowance exhausted. Resume when your allowance is available."
|
|
12950
|
+
},
|
|
12951
|
+
monthly_model_cost_limit: {
|
|
12952
|
+
pausedReason: "budget",
|
|
12953
|
+
message: "Monthly model spending limit reached. Resume when the spending limit allows."
|
|
12954
|
+
},
|
|
12955
|
+
monthly_agent_run_limit: {
|
|
12956
|
+
pausedReason: "usage_limit",
|
|
12957
|
+
message: "Monthly agent run limit reached. Resume when the run limit allows."
|
|
12958
|
+
}
|
|
12959
|
+
};
|
|
12960
|
+
return blocks[denial];
|
|
12961
|
+
}
|
|
12962
|
+
var GoalResumeBlockedError = class extends Error {
|
|
12963
|
+
constructor(pausedReason, message) {
|
|
12964
|
+
super(message);
|
|
12965
|
+
this.pausedReason = pausedReason;
|
|
12966
|
+
this.name = "GoalResumeBlockedError";
|
|
12967
|
+
}
|
|
12968
|
+
};
|
|
12969
|
+
async function assertGoalResumeAllowed(services, session, causalTurn) {
|
|
12970
|
+
const decision = await resolveGoalModelAdmission(
|
|
12971
|
+
services.db,
|
|
12972
|
+
services.catalogSourceSettings ?? services.settings,
|
|
12973
|
+
session
|
|
12974
|
+
);
|
|
12975
|
+
if (decision.blocked) {
|
|
12976
|
+
throw new GoalResumeBlockedError(decision.pausedReason, decision.blocked);
|
|
12977
|
+
}
|
|
12978
|
+
const block = await goalRunBudgetBlocked(
|
|
12979
|
+
{ ...services, settings: decision.settings },
|
|
12980
|
+
{
|
|
12981
|
+
accountId: session.accountId,
|
|
12982
|
+
workspaceId: session.workspaceId,
|
|
12983
|
+
model: decision.model,
|
|
12984
|
+
// Resuming does not lend the clicking user's allowance or credentials.
|
|
12985
|
+
initiatingHumanSubjectId: causalTurn?.initiatingHumanSubjectId ?? null
|
|
12986
|
+
}
|
|
12987
|
+
);
|
|
12988
|
+
if (block) throw new GoalResumeBlockedError(block.pausedReason, block.message);
|
|
12989
|
+
}
|
|
12990
|
+
|
|
12754
12991
|
// src/application/external-workspace-members.ts
|
|
12755
12992
|
import { HTTPException as HTTPException18 } from "hono/http-exception";
|
|
12756
12993
|
import {
|
|
@@ -17695,7 +17932,7 @@ function orderScheduledTaskAccessAttention(items) {
|
|
|
17695
17932
|
}
|
|
17696
17933
|
|
|
17697
17934
|
// src/domain/insights.ts
|
|
17698
|
-
import { configuredStaticUsageLimits as
|
|
17935
|
+
import { configuredStaticUsageLimits as configuredStaticUsageLimits3 } from "@opengeni/config";
|
|
17699
17936
|
import {
|
|
17700
17937
|
WorkspaceInsightsSnapshot
|
|
17701
17938
|
} from "@opengeni/contracts";
|
|
@@ -17826,7 +18063,7 @@ function cacheHitPct(cached2, input) {
|
|
|
17826
18063
|
function startOfUtcDay(date) {
|
|
17827
18064
|
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
|
|
17828
18065
|
}
|
|
17829
|
-
function
|
|
18066
|
+
function startOfUtcMonth3(date) {
|
|
17830
18067
|
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
|
|
17831
18068
|
}
|
|
17832
18069
|
function startOfUtcYear(date) {
|
|
@@ -17855,7 +18092,7 @@ function resolveRangeWindow(range, now) {
|
|
|
17855
18092
|
cacheSeriesLabel = "Cache hit % / UTC day";
|
|
17856
18093
|
break;
|
|
17857
18094
|
case "month":
|
|
17858
|
-
since =
|
|
18095
|
+
since = startOfUtcMonth3(now);
|
|
17859
18096
|
rangeLabel = "This month (UTC)";
|
|
17860
18097
|
priorLabel = "Prior equal window";
|
|
17861
18098
|
seriesLabel = "Credit $ / UTC day";
|
|
@@ -17986,7 +18223,7 @@ async function getWorkspaceInsights(db, settings, input, observePhase) {
|
|
|
17986
18223
|
until: window.until,
|
|
17987
18224
|
priorSince: window.priorSince,
|
|
17988
18225
|
priorUntil: window.priorUntil,
|
|
17989
|
-
monthSince:
|
|
18226
|
+
monthSince: startOfUtcMonth3(now),
|
|
17990
18227
|
granularity: input.range === "today" ? "hour" : "day",
|
|
17991
18228
|
warmGroupLimit: 24
|
|
17992
18229
|
})
|
|
@@ -18229,7 +18466,7 @@ async function getWorkspaceInsights(db, settings, input, observePhase) {
|
|
|
18229
18466
|
billing: fact ? billingPathOf(fact.billingPath) : null
|
|
18230
18467
|
};
|
|
18231
18468
|
});
|
|
18232
|
-
const limits =
|
|
18469
|
+
const limits = configuredStaticUsageLimits3(settings);
|
|
18233
18470
|
const floor = floorRows.filter((row) => {
|
|
18234
18471
|
if (!model) return true;
|
|
18235
18472
|
return row.model === model;
|
|
@@ -20178,7 +20415,7 @@ import {
|
|
|
20178
20415
|
withWorkspaceSubjectRls as withWorkspaceSubjectRls6
|
|
20179
20416
|
} from "@opengeni/db";
|
|
20180
20417
|
import { HTTPException as HTTPException29 } from "hono/http-exception";
|
|
20181
|
-
import { canonicalizeConfiguredModelId as
|
|
20418
|
+
import { canonicalizeConfiguredModelId as canonicalizeConfiguredModelId5 } from "@opengeni/config";
|
|
20182
20419
|
function hasOwn(value, key) {
|
|
20183
20420
|
return typeof value === "object" && value !== null && Object.hasOwn(value, key);
|
|
20184
20421
|
}
|
|
@@ -20203,7 +20440,7 @@ function mapNewSessionDraft(row) {
|
|
|
20203
20440
|
}
|
|
20204
20441
|
function draftModelProvided(settings, draft) {
|
|
20205
20442
|
if (draft.modelProvided !== void 0) return draft.modelProvided;
|
|
20206
|
-
return !(
|
|
20443
|
+
return !(canonicalizeConfiguredModelId5(settings, draft.model) === canonicalizeConfiguredModelId5(settings, settings.openaiModel) && draft.reasoningEffort === settings.openaiReasoningEffort && draft.latencyMode === "standard");
|
|
20207
20444
|
}
|
|
20208
20445
|
async function actorDefaultModel(deps, grant, workspaceId) {
|
|
20209
20446
|
return await resolveDefaultSessionModel(deps.db, deps.settings, {
|
|
@@ -20477,7 +20714,7 @@ async function submitComposerDraftForRequest(deps, grant, workspaceId, sessionId
|
|
|
20477
20714
|
import { DraftTimelineAnnotations as DraftTimelineAnnotations3 } from "@opengeni/contracts";
|
|
20478
20715
|
import { HTTPException as HTTPException30 } from "hono/http-exception";
|
|
20479
20716
|
import {
|
|
20480
|
-
checkWorkspaceAllowance as
|
|
20717
|
+
checkWorkspaceAllowance as checkWorkspaceAllowance4,
|
|
20481
20718
|
deleteSessionQueueItemInTransaction,
|
|
20482
20719
|
editQueuedTurnInTransaction,
|
|
20483
20720
|
getComposerDraftInTransaction as getComposerDraftInTransaction2,
|
|
@@ -20486,7 +20723,7 @@ import {
|
|
|
20486
20723
|
getWorkspaceControlEvent as getWorkspaceControlEvent2,
|
|
20487
20724
|
getSessionQueueSnapshot,
|
|
20488
20725
|
frozenInitiatorForCommandActor as frozenInitiatorForCommandActor2,
|
|
20489
|
-
isCodexBilledTurn as
|
|
20726
|
+
isCodexBilledTurn as isCodexBilledTurn3,
|
|
20490
20727
|
moveQueuedTurnInTransaction,
|
|
20491
20728
|
mutateSessionControlInTransaction,
|
|
20492
20729
|
mutateWorkspaceControlInTransaction,
|
|
@@ -20564,7 +20801,7 @@ async function assertFreshAgentCommandAllowance(tx, deps, context, targetSession
|
|
|
20564
20801
|
workspaceId: context.workspaceId,
|
|
20565
20802
|
retainedProductModelId: target.model
|
|
20566
20803
|
});
|
|
20567
|
-
const codexBilled = await
|
|
20804
|
+
const codexBilled = await isCodexBilledTurn3({
|
|
20568
20805
|
db: tx,
|
|
20569
20806
|
settings,
|
|
20570
20807
|
workspaceId: context.workspaceId,
|
|
@@ -20575,7 +20812,7 @@ async function assertFreshAgentCommandAllowance(tx, deps, context, targetSession
|
|
|
20575
20812
|
}
|
|
20576
20813
|
}
|
|
20577
20814
|
const frozen = await frozenInitiatorForCommandActor2(tx, context.workspaceId, agentActor(context));
|
|
20578
|
-
const refusal = await
|
|
20815
|
+
const refusal = await checkWorkspaceAllowance4(tx, {
|
|
20579
20816
|
accountId: target.accountId,
|
|
20580
20817
|
workspaceId: context.workspaceId,
|
|
20581
20818
|
subjectId: initiatingHumanForAllowance(frozen)
|
|
@@ -21432,9 +21669,7 @@ async function consentManagedHumanSandboxRecovery(deps, authorization, workspace
|
|
|
21432
21669
|
import {
|
|
21433
21670
|
issueSelfUserResourceGrant,
|
|
21434
21671
|
listSelfUserResourceAuthorities,
|
|
21435
|
-
revokeSelfUserResourceGrant
|
|
21436
|
-
sessionTenancyProductActivated as sessionTenancyProductActivated3,
|
|
21437
|
-
SessionTenancyNotActivatedError as SessionTenancyNotActivatedError2
|
|
21672
|
+
revokeSelfUserResourceGrant
|
|
21438
21673
|
} from "@opengeni/db";
|
|
21439
21674
|
var LIST_PERMISSIONS = {
|
|
21440
21675
|
connection: ["connections:read"],
|
|
@@ -21452,9 +21687,6 @@ var ISSUE_PERMISSIONS = {
|
|
|
21452
21687
|
};
|
|
21453
21688
|
async function requireOwnerProductGate(deps, authorization, workspaceId, permissions) {
|
|
21454
21689
|
requireOwnerAuthority(authorization, workspaceId, permissions);
|
|
21455
|
-
if (!await sessionTenancyProductActivated3(deps.db, workspaceId)) {
|
|
21456
|
-
throw new SessionTenancyNotActivatedError2();
|
|
21457
|
-
}
|
|
21458
21690
|
}
|
|
21459
21691
|
function requireOwnerAuthority(authorization, workspaceId, permissions) {
|
|
21460
21692
|
if (!authorization.canonicalLocalHumanSession) {
|
|
@@ -21466,9 +21698,6 @@ function requireOwnerAuthority(authorization, workspaceId, permissions) {
|
|
|
21466
21698
|
}
|
|
21467
21699
|
async function listManagedHumanUserResourceAuthorities(deps, authorization, workspaceId, input) {
|
|
21468
21700
|
requireOwnerAuthority(authorization, workspaceId, LIST_PERMISSIONS[input.resourceKind]);
|
|
21469
|
-
if (!await sessionTenancyProductActivated3(deps.db, workspaceId)) {
|
|
21470
|
-
return { authorities: [], nextCursor: null };
|
|
21471
|
-
}
|
|
21472
21701
|
return await listSelfUserResourceAuthorities(deps.db, {
|
|
21473
21702
|
accountId: authorization.grant.accountId,
|
|
21474
21703
|
workspaceId,
|
|
@@ -22195,6 +22424,7 @@ export {
|
|
|
22195
22424
|
EditableArtifactStaleBaseError,
|
|
22196
22425
|
EditableArtifactUndoTargetError,
|
|
22197
22426
|
GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES,
|
|
22427
|
+
GoalResumeBlockedError,
|
|
22198
22428
|
InMemoryEditableArtifactLiveTicketStore,
|
|
22199
22429
|
InMemoryEditableArtifactStableIdFactory,
|
|
22200
22430
|
InMemoryEditableArtifactStore,
|
|
@@ -22266,6 +22496,7 @@ export {
|
|
|
22266
22496
|
agentAccessListScopeForViewer,
|
|
22267
22497
|
agentAccessPermitsCrossTreeAccess,
|
|
22268
22498
|
agentConfigParentFor,
|
|
22499
|
+
agentRunAdmissionDenial,
|
|
22269
22500
|
apiIntegrationsMatchingDelegations,
|
|
22270
22501
|
appendArchivedSessionEventsForRequest,
|
|
22271
22502
|
appendRigSetupCommand,
|
|
@@ -22285,6 +22516,7 @@ export {
|
|
|
22285
22516
|
assertConversationDeliveryOutcome,
|
|
22286
22517
|
assertConversationInboundEnvelope,
|
|
22287
22518
|
assertConversationProviderReceipt,
|
|
22519
|
+
assertGoalResumeAllowed,
|
|
22288
22520
|
assertIsoTimestamp,
|
|
22289
22521
|
assertKnownVideoGenerationModelIds,
|
|
22290
22522
|
assertManagedUserAdmission,
|
|
@@ -22438,6 +22670,8 @@ export {
|
|
|
22438
22670
|
getManagedSession,
|
|
22439
22671
|
getWorkspaceInsights,
|
|
22440
22672
|
githubAppActionPolicyActor,
|
|
22673
|
+
goalContinuationModelDecision,
|
|
22674
|
+
goalRunBudgetBlocked,
|
|
22441
22675
|
googleDrivePublicationDelegationFromVisibleConnections,
|
|
22442
22676
|
governedLearningEvidenceIsSlackDerived,
|
|
22443
22677
|
governedLearningSlackImportance,
|
|
@@ -22642,6 +22876,7 @@ export {
|
|
|
22642
22876
|
resolveFikenDefaultCompanySlug,
|
|
22643
22877
|
resolveFirstPartyMcpToolsForCreate,
|
|
22644
22878
|
resolveGitHubRepositoryBindings,
|
|
22879
|
+
resolveGoalModelAdmission,
|
|
22645
22880
|
resolveMemberSubjectId,
|
|
22646
22881
|
resolveRigProviderImageForRun,
|
|
22647
22882
|
resolveRigProviderImageSelection,
|