@opengeni/core 2.6.3-canary.0 → 2.6.4-canary.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/limits.d.ts +5 -0
- package/dist/dependencies.d.ts +10 -1
- package/dist/domain/sessions.d.ts +24 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1049 -316
- package/dist/index.js.map +1 -1
- package/dist/model-catalog.d.ts +89 -0
- package/package.json +10 -10
- package/src/billing/limits.ts +52 -22
- package/src/dependencies.ts +15 -1
- package/src/domain/scheduled-tasks.ts +52 -1
- package/src/domain/sessions.ts +790 -344
- package/src/index.ts +1 -0
- package/src/model-catalog.ts +565 -0
package/dist/index.js
CHANGED
|
@@ -208,6 +208,367 @@ function filenameForMimeType(mimeType) {
|
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
// src/model-catalog.ts
|
|
212
|
+
import {
|
|
213
|
+
applyModelCatalogDocument,
|
|
214
|
+
configuredGatewayWorkspaceProductModelIds,
|
|
215
|
+
configuredModels,
|
|
216
|
+
configuredModelNotes,
|
|
217
|
+
configuredOpenRouterWorkspaceProductModelIds,
|
|
218
|
+
configuredProviders,
|
|
219
|
+
validateModelCatalogSettings,
|
|
220
|
+
withCodexCatalogProvider,
|
|
221
|
+
withWorkspaceGatewayCatalogProvider,
|
|
222
|
+
withWorkspaceOpenRouterCatalogProvider,
|
|
223
|
+
withXaiSubscriptionCatalogProvider,
|
|
224
|
+
WORKSPACE_GATEWAY_MODEL_ID_PREFIX,
|
|
225
|
+
WORKSPACE_OPENROUTER_MODEL_ID_PREFIX,
|
|
226
|
+
WORKSPACE_OPENROUTER_PROVIDER_ID
|
|
227
|
+
} from "@opengeni/config";
|
|
228
|
+
import {
|
|
229
|
+
evaluateWorkspaceModelPolicy
|
|
230
|
+
} from "@opengeni/contracts";
|
|
231
|
+
import {
|
|
232
|
+
getDeploymentModelCatalog,
|
|
233
|
+
getWorkspaceGatewayCustomModelForExecution,
|
|
234
|
+
getWorkspaceOpenRouterCustomModelForExecution,
|
|
235
|
+
listWorkspaceGatewayCustomModels,
|
|
236
|
+
listWorkspaceOpenRouterCustomModels
|
|
237
|
+
} from "@opengeni/db";
|
|
238
|
+
function isWorkspaceGatewayCustomModelId(settings, modelId) {
|
|
239
|
+
return modelId.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX) && !configuredGatewayWorkspaceProductModelIds(settings).includes(modelId);
|
|
240
|
+
}
|
|
241
|
+
function isWorkspaceOpenRouterCustomModelId(settings, modelId) {
|
|
242
|
+
return modelId.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX) && !configuredOpenRouterWorkspaceProductModelIds(settings).includes(modelId);
|
|
243
|
+
}
|
|
244
|
+
function workspaceCustomModelReference(settings, modelId) {
|
|
245
|
+
if (isWorkspaceGatewayCustomModelId(settings, modelId)) {
|
|
246
|
+
return {
|
|
247
|
+
providerKind: "vercel_gateway",
|
|
248
|
+
upstreamModelId: modelId.slice(WORKSPACE_GATEWAY_MODEL_ID_PREFIX.length)
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
if (isWorkspaceOpenRouterCustomModelId(settings, modelId)) {
|
|
252
|
+
return {
|
|
253
|
+
providerKind: "openrouter",
|
|
254
|
+
upstreamModelId: modelId.slice(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX.length)
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
function isWorkspaceCustomModelId(settings, modelId) {
|
|
260
|
+
return workspaceCustomModelReference(settings, modelId) !== null;
|
|
261
|
+
}
|
|
262
|
+
async function resolveCatalogSettings(db, envSettings) {
|
|
263
|
+
if (envSettings.modelCatalogSource === "code") {
|
|
264
|
+
validateModelCatalogSettings(envSettings);
|
|
265
|
+
return {
|
|
266
|
+
settings: envSettings,
|
|
267
|
+
source: "code",
|
|
268
|
+
version: null,
|
|
269
|
+
modelNotes: configuredModelNotes(envSettings)
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const row = await getDeploymentModelCatalog(db);
|
|
273
|
+
if (!row) {
|
|
274
|
+
throw new Error("database model catalog source is configured but the singleton row is missing");
|
|
275
|
+
}
|
|
276
|
+
const settings = applyModelCatalogDocument(envSettings, row.document);
|
|
277
|
+
validateModelCatalogSettings(settings);
|
|
278
|
+
return {
|
|
279
|
+
settings,
|
|
280
|
+
source: "database",
|
|
281
|
+
version: row.version,
|
|
282
|
+
modelNotes: configuredModelNotes(settings)
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
async function resolveWorkspaceCatalogSettings(db, envSettings, input) {
|
|
286
|
+
const retainedProductModelIds = [
|
|
287
|
+
...input.retainedProductModelIds ?? [],
|
|
288
|
+
input.retainedProductModelId
|
|
289
|
+
];
|
|
290
|
+
const retainedGatewayUpstreamModelIds = retainedProductModelIds.flatMap(
|
|
291
|
+
(productModelId) => productModelId?.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX) ? [productModelId.slice(WORKSPACE_GATEWAY_MODEL_ID_PREFIX.length)] : []
|
|
292
|
+
);
|
|
293
|
+
const retainedOpenRouterUpstreamModelIds = retainedProductModelIds.flatMap(
|
|
294
|
+
(productModelId) => productModelId?.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX) ? [productModelId.slice(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX.length)] : []
|
|
295
|
+
);
|
|
296
|
+
const [
|
|
297
|
+
resolved,
|
|
298
|
+
activeGatewayCustomModels,
|
|
299
|
+
activeOpenRouterCustomModels,
|
|
300
|
+
retainedGatewayCustomModels,
|
|
301
|
+
retainedOpenRouterCustomModels
|
|
302
|
+
] = await Promise.all([
|
|
303
|
+
resolveCatalogSettings(db, envSettings),
|
|
304
|
+
listWorkspaceGatewayCustomModels(db, {
|
|
305
|
+
accountId: input.accountId,
|
|
306
|
+
workspaceId: input.workspaceId
|
|
307
|
+
}),
|
|
308
|
+
listWorkspaceOpenRouterCustomModels(db, {
|
|
309
|
+
accountId: input.accountId,
|
|
310
|
+
workspaceId: input.workspaceId
|
|
311
|
+
}),
|
|
312
|
+
Promise.all(
|
|
313
|
+
[...new Set(retainedGatewayUpstreamModelIds)].map(
|
|
314
|
+
async (upstreamModelId) => await getWorkspaceGatewayCustomModelForExecution(db, {
|
|
315
|
+
accountId: input.accountId,
|
|
316
|
+
workspaceId: input.workspaceId,
|
|
317
|
+
upstreamModelId
|
|
318
|
+
})
|
|
319
|
+
)
|
|
320
|
+
),
|
|
321
|
+
Promise.all(
|
|
322
|
+
[...new Set(retainedOpenRouterUpstreamModelIds)].map(
|
|
323
|
+
async (upstreamModelId) => await getWorkspaceOpenRouterCustomModelForExecution(db, {
|
|
324
|
+
accountId: input.accountId,
|
|
325
|
+
workspaceId: input.workspaceId,
|
|
326
|
+
upstreamModelId
|
|
327
|
+
})
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
]);
|
|
331
|
+
const includeRetainedModels = (activeModels, retainedModels) => {
|
|
332
|
+
const customModels = [...activeModels];
|
|
333
|
+
const includedUpstreamModelIds = new Set(activeModels.map((model) => model.upstreamModelId));
|
|
334
|
+
for (const retainedCustomModel of retainedModels) {
|
|
335
|
+
if (retainedCustomModel && !includedUpstreamModelIds.has(retainedCustomModel.upstreamModelId)) {
|
|
336
|
+
customModels.push(retainedCustomModel);
|
|
337
|
+
includedUpstreamModelIds.add(retainedCustomModel.upstreamModelId);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return customModels;
|
|
341
|
+
};
|
|
342
|
+
const gatewayCustomModels = includeRetainedModels(
|
|
343
|
+
activeGatewayCustomModels,
|
|
344
|
+
retainedGatewayCustomModels
|
|
345
|
+
);
|
|
346
|
+
const openRouterCustomModels = includeRetainedModels(
|
|
347
|
+
activeOpenRouterCustomModels,
|
|
348
|
+
retainedOpenRouterCustomModels
|
|
349
|
+
);
|
|
350
|
+
return {
|
|
351
|
+
...resolved,
|
|
352
|
+
settings: withWorkspaceOpenRouterCatalogProvider(
|
|
353
|
+
withWorkspaceGatewayCatalogProvider(resolved.settings, gatewayCustomModels),
|
|
354
|
+
openRouterCustomModels
|
|
355
|
+
)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
var MODEL_CREDENTIAL_READINESS_OBSERVATION_MAX_AGE_MS = 5 * 6e4;
|
|
359
|
+
function modelDefinitionRunnable(model) {
|
|
360
|
+
return model.capabilities.inputModalities.includes("text") && model.capabilities.outputModalities.includes("text") && model.capabilities.transports.sse.runnable;
|
|
361
|
+
}
|
|
362
|
+
function observedCredentialReadiness(input) {
|
|
363
|
+
if (!input.observation) {
|
|
364
|
+
return {
|
|
365
|
+
status: "not_ready",
|
|
366
|
+
reason: "prerequisites_missing",
|
|
367
|
+
basis: input.basis,
|
|
368
|
+
checkedAt: null
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
const checkedAtMs = Date.parse(input.observation.checkedAt);
|
|
372
|
+
if (!Number.isFinite(checkedAtMs)) {
|
|
373
|
+
return {
|
|
374
|
+
status: "error",
|
|
375
|
+
reason: "resolver_error",
|
|
376
|
+
basis: input.basis,
|
|
377
|
+
checkedAt: null
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
const checkedAt = new Date(checkedAtMs).toISOString();
|
|
381
|
+
if (Math.abs(input.nowMs - checkedAtMs) > input.maxAgeMs) {
|
|
382
|
+
return {
|
|
383
|
+
status: "not_ready",
|
|
384
|
+
reason: "observation_stale",
|
|
385
|
+
basis: input.basis,
|
|
386
|
+
checkedAt
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
if (input.observation.status === "ready") {
|
|
390
|
+
return { status: "ready", reason: null, basis: input.basis, checkedAt };
|
|
391
|
+
}
|
|
392
|
+
if (input.observation.status === "not_ready") {
|
|
393
|
+
return {
|
|
394
|
+
status: "not_ready",
|
|
395
|
+
reason: input.observation.reason === "needs_reauth" ? "needs_reauth" : "prerequisites_missing",
|
|
396
|
+
basis: input.basis,
|
|
397
|
+
checkedAt
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
status: "error",
|
|
402
|
+
reason: "resolver_error",
|
|
403
|
+
basis: input.basis,
|
|
404
|
+
checkedAt
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function credentialReadinessFor(input) {
|
|
408
|
+
const source = input.model.credentialSource;
|
|
409
|
+
if (source.kind === "connected_subscription") {
|
|
410
|
+
const active = source.provider === "xai" ? input.xaiSubscriptionActive : input.codexSubscriptionActive;
|
|
411
|
+
return active ? { status: "ready", reason: null, basis: "connection", checkedAt: null } : {
|
|
412
|
+
status: "not_ready",
|
|
413
|
+
reason: "needs_reauth",
|
|
414
|
+
basis: "connection",
|
|
415
|
+
checkedAt: null
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
if (source.kind === "workspace_connection") {
|
|
419
|
+
const connectionActive = input.model.providerId === WORKSPACE_OPENROUTER_PROVIDER_ID ? input.workspaceOpenRouterConnectionActive : input.workspaceGatewayConnectionActive;
|
|
420
|
+
return connectionActive ? { status: "ready", reason: null, basis: "connection", checkedAt: null } : {
|
|
421
|
+
status: "not_ready",
|
|
422
|
+
reason: "needs_reauth",
|
|
423
|
+
basis: "connection",
|
|
424
|
+
checkedAt: null
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
if (source.kind === "deployment" && source.mechanism === "none") {
|
|
428
|
+
return { status: "ready", reason: null, basis: "configuration", checkedAt: null };
|
|
429
|
+
}
|
|
430
|
+
if (source.kind === "deployment" && source.mechanism === "api_key") {
|
|
431
|
+
return input.provider?.apiKey ? { status: "ready", reason: null, basis: "configuration", checkedAt: null } : {
|
|
432
|
+
status: "not_ready",
|
|
433
|
+
reason: "missing_credential",
|
|
434
|
+
basis: "configuration",
|
|
435
|
+
checkedAt: null
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
return observedCredentialReadiness({
|
|
439
|
+
observation: input.observation,
|
|
440
|
+
basis: "resolver",
|
|
441
|
+
nowMs: input.nowMs,
|
|
442
|
+
maxAgeMs: input.maxAgeMs
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
function isXaiGrokModel(model) {
|
|
446
|
+
return model.providerId === "xai" && model.id.startsWith("xai/grok-");
|
|
447
|
+
}
|
|
448
|
+
function observationTimestamp(observation) {
|
|
449
|
+
if (!observation || typeof observation.checkedAt !== "string") {
|
|
450
|
+
return { checkedAt: null, checkedAtMs: null };
|
|
451
|
+
}
|
|
452
|
+
const checkedAtMs = Date.parse(observation.checkedAt);
|
|
453
|
+
if (!Number.isFinite(checkedAtMs)) {
|
|
454
|
+
return { checkedAt: null, checkedAtMs: null };
|
|
455
|
+
}
|
|
456
|
+
return { checkedAt: new Date(checkedAtMs).toISOString(), checkedAtMs };
|
|
457
|
+
}
|
|
458
|
+
function xaiGrokAvailabilityFor(input) {
|
|
459
|
+
const { checkedAt, checkedAtMs } = observationTimestamp(input.observation);
|
|
460
|
+
const freshSuccessfulObservation = input.observation?.status === "available" && input.observation.reason === null && checkedAtMs !== null && checkedAtMs <= input.nowMs && input.nowMs - checkedAtMs <= input.maxAgeMs;
|
|
461
|
+
if (freshSuccessfulObservation) {
|
|
462
|
+
return {
|
|
463
|
+
status: "available",
|
|
464
|
+
selectable: true,
|
|
465
|
+
reason: null,
|
|
466
|
+
checkedAt
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
return {
|
|
470
|
+
status: "unavailable",
|
|
471
|
+
selectable: false,
|
|
472
|
+
reason: input.observation?.status === "unavailable" ? input.observation.reason ?? "provider_unhealthy" : "provider_unhealthy",
|
|
473
|
+
checkedAt
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
function availabilityFor(input) {
|
|
477
|
+
if (!modelDefinitionRunnable(input.model)) {
|
|
478
|
+
return {
|
|
479
|
+
status: "unavailable",
|
|
480
|
+
selectable: false,
|
|
481
|
+
reason: "unsupported",
|
|
482
|
+
checkedAt: null
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
if (input.credentialReadiness.status !== "ready") {
|
|
486
|
+
return {
|
|
487
|
+
status: "unavailable",
|
|
488
|
+
selectable: false,
|
|
489
|
+
reason: input.credentialReadiness.reason === "missing_credential" ? "missing_credential" : input.credentialReadiness.reason === "needs_reauth" ? "needs_reauth" : "credential_not_ready",
|
|
490
|
+
checkedAt: input.credentialReadiness.checkedAt
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
if (!input.policyAllowed) {
|
|
494
|
+
return {
|
|
495
|
+
status: "unavailable",
|
|
496
|
+
selectable: false,
|
|
497
|
+
reason: "policy_blocked",
|
|
498
|
+
checkedAt: null
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
if (isXaiGrokModel(input.model)) {
|
|
502
|
+
return xaiGrokAvailabilityFor({
|
|
503
|
+
observation: input.observation,
|
|
504
|
+
nowMs: input.nowMs,
|
|
505
|
+
maxAgeMs: input.maxAgeMs
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
if (!input.observation) {
|
|
509
|
+
return { status: "unknown", selectable: true, reason: null, checkedAt: null };
|
|
510
|
+
}
|
|
511
|
+
if (input.observation.status === "unavailable") {
|
|
512
|
+
return {
|
|
513
|
+
status: "unavailable",
|
|
514
|
+
selectable: false,
|
|
515
|
+
reason: input.observation.reason ?? "provider_unhealthy",
|
|
516
|
+
checkedAt: input.observation.checkedAt
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
status: input.observation.status,
|
|
521
|
+
selectable: true,
|
|
522
|
+
reason: null,
|
|
523
|
+
checkedAt: input.observation.checkedAt
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
function resolveWorkspaceModelSelection(input) {
|
|
527
|
+
const codexSettings = input.settings.codexSubscriptionEnabled ? withCodexCatalogProvider(input.settings) : input.settings;
|
|
528
|
+
const xaiSettings = input.settings.supergrokSubscriptionEnabled ? withXaiSubscriptionCatalogProvider(codexSettings) : codexSettings;
|
|
529
|
+
const catalogSettings = withWorkspaceOpenRouterCatalogProvider(
|
|
530
|
+
withWorkspaceGatewayCatalogProvider(xaiSettings, input.workspaceGatewayCustomModels ?? []),
|
|
531
|
+
input.workspaceOpenRouterCustomModels ?? []
|
|
532
|
+
);
|
|
533
|
+
const providers = new Map(
|
|
534
|
+
configuredProviders(catalogSettings).map((provider) => [provider.id, provider])
|
|
535
|
+
);
|
|
536
|
+
const requestedNowMs = input.now?.getTime();
|
|
537
|
+
const nowMs = typeof requestedNowMs === "number" && Number.isFinite(requestedNowMs) ? requestedNowMs : Date.now();
|
|
538
|
+
const maxAgeMs = typeof input.credentialReadinessMaxAgeMs === "number" && Number.isFinite(input.credentialReadinessMaxAgeMs) && input.credentialReadinessMaxAgeMs >= 0 ? input.credentialReadinessMaxAgeMs : MODEL_CREDENTIAL_READINESS_OBSERVATION_MAX_AGE_MS;
|
|
539
|
+
return configuredModels(catalogSettings).map((model) => {
|
|
540
|
+
const provider = providers.get(model.providerId);
|
|
541
|
+
const policyAllowed = evaluateWorkspaceModelPolicy(input.policy, {
|
|
542
|
+
providerId: model.providerId,
|
|
543
|
+
modelId: model.id
|
|
544
|
+
}).allowed;
|
|
545
|
+
const credentialReadiness = credentialReadinessFor({
|
|
546
|
+
model,
|
|
547
|
+
provider,
|
|
548
|
+
codexSubscriptionActive: input.codexSubscriptionActive,
|
|
549
|
+
xaiSubscriptionActive: input.xaiSubscriptionActive === true,
|
|
550
|
+
workspaceGatewayConnectionActive: input.workspaceGatewayConnectionActive === true,
|
|
551
|
+
workspaceOpenRouterConnectionActive: input.workspaceOpenRouterConnectionActive === true,
|
|
552
|
+
observation: input.credentialReadinessObservations?.[model.definitionVersion],
|
|
553
|
+
nowMs,
|
|
554
|
+
maxAgeMs
|
|
555
|
+
});
|
|
556
|
+
return {
|
|
557
|
+
model,
|
|
558
|
+
credentialReadiness,
|
|
559
|
+
policyAllowed,
|
|
560
|
+
availability: availabilityFor({
|
|
561
|
+
model,
|
|
562
|
+
credentialReadiness,
|
|
563
|
+
policyAllowed,
|
|
564
|
+
observation: input.observations?.[model.definitionVersion],
|
|
565
|
+
nowMs,
|
|
566
|
+
maxAgeMs
|
|
567
|
+
})
|
|
568
|
+
};
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
211
572
|
// src/sandbox/fleet.ts
|
|
212
573
|
import {
|
|
213
574
|
authorizePersonalMachineForAttempt,
|
|
@@ -2074,7 +2435,10 @@ async function resolveSessionAuthorizationActor(db, grant) {
|
|
|
2074
2435
|
}
|
|
2075
2436
|
|
|
2076
2437
|
// src/billing/limits.ts
|
|
2077
|
-
import {
|
|
2438
|
+
import {
|
|
2439
|
+
configuredStaticUsageLimits,
|
|
2440
|
+
resolveModelProviderForTurn
|
|
2441
|
+
} from "@opengeni/config";
|
|
2078
2442
|
import {
|
|
2079
2443
|
countActiveApiKeysForWorkspace,
|
|
2080
2444
|
countActiveOrganizationApiKeysForAccount,
|
|
@@ -2086,6 +2450,18 @@ import {
|
|
|
2086
2450
|
sumUsageQuantity
|
|
2087
2451
|
} from "@opengeni/db";
|
|
2088
2452
|
import { HTTPException as HTTPException2 } from "hono/http-exception";
|
|
2453
|
+
function modelFundingForAdmission(settings, model, codexBilled) {
|
|
2454
|
+
const resolvedModel = model ? resolveModelProviderForTurn(settings, model)?.model : null;
|
|
2455
|
+
const codexSubscriptionModel = resolvedModel?.credentialSource.kind === "connected_subscription" && resolvedModel.credentialSource.provider === "codex";
|
|
2456
|
+
return {
|
|
2457
|
+
// A Codex namespace/definition never bypasses credits by itself: the live
|
|
2458
|
+
// workspace credential predicate above remains authoritative. SuperGrok's
|
|
2459
|
+
// static overlay is likewise secret-free; its worker/provider admission
|
|
2460
|
+
// owns live account selection before any upstream request can occur.
|
|
2461
|
+
fundedWithoutCredits: codexBilled || resolvedModel != null && !codexSubscriptionModel && resolvedModel.cost !== "credits",
|
|
2462
|
+
countsTowardTokenCap: !codexBilled && resolvedModel != null && resolvedModel.billing.upstreamPayer === "deployment"
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2089
2465
|
async function requireLimit(deps, input) {
|
|
2090
2466
|
const decision = await checkLimit(deps, input);
|
|
2091
2467
|
if (decision.allowed) {
|
|
@@ -2102,19 +2478,22 @@ async function checkLimit(deps, input) {
|
|
|
2102
2478
|
workspaceId: input.workspaceId,
|
|
2103
2479
|
model: input.model
|
|
2104
2480
|
}) : false;
|
|
2105
|
-
const
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
const creditDecision = await checkCreditBalance(deps, input,
|
|
2481
|
+
const { fundedWithoutCredits, countsTowardTokenCap } = modelFundingForAdmission(
|
|
2482
|
+
deps.settings,
|
|
2483
|
+
input.model,
|
|
2484
|
+
codexBilled
|
|
2485
|
+
);
|
|
2486
|
+
const creditDecision = await checkCreditBalance(deps, input, fundedWithoutCredits);
|
|
2111
2487
|
if (!creditDecision.allowed) {
|
|
2112
2488
|
return creditDecision;
|
|
2113
2489
|
}
|
|
2114
2490
|
if (deps.settings.usageLimitsMode !== "static" && deps.settings.usageLimitsMode !== "managed") {
|
|
2115
2491
|
return { allowed: true };
|
|
2116
2492
|
}
|
|
2117
|
-
return await checkStaticCaps(deps, input,
|
|
2493
|
+
return await checkStaticCaps(deps, input, {
|
|
2494
|
+
fundedWithoutCredits,
|
|
2495
|
+
countsTowardTokenCap
|
|
2496
|
+
});
|
|
2118
2497
|
}
|
|
2119
2498
|
async function checkCreditBalance(deps, input, externallyBilled) {
|
|
2120
2499
|
if (externallyBilled) {
|
|
@@ -2129,9 +2508,9 @@ async function checkCreditBalance(deps, input, externallyBilled) {
|
|
|
2129
2508
|
}
|
|
2130
2509
|
return { allowed: false, code: "insufficient_credits", message: "insufficient OpenGeni credits" };
|
|
2131
2510
|
}
|
|
2132
|
-
async function checkStaticCaps(deps, input,
|
|
2511
|
+
async function checkStaticCaps(deps, input, funding) {
|
|
2133
2512
|
const limits = configuredStaticUsageLimits(deps.settings);
|
|
2134
|
-
if (limits.maxMonthlyCostMicrosPerAccount && isCostlyAction(input.action) && !
|
|
2513
|
+
if (limits.maxMonthlyCostMicrosPerAccount && isCostlyAction(input.action) && !funding.fundedWithoutCredits) {
|
|
2135
2514
|
const used = await sumUsageQuantity(deps.db, {
|
|
2136
2515
|
accountId: input.accountId,
|
|
2137
2516
|
eventType: "model.cost",
|
|
@@ -2200,7 +2579,7 @@ async function checkStaticCaps(deps, input, externallyBilled) {
|
|
|
2200
2579
|
);
|
|
2201
2580
|
}
|
|
2202
2581
|
case "tokens:consume": {
|
|
2203
|
-
if (
|
|
2582
|
+
if (!funding.countsTowardTokenCap || !limits.maxMonthlyTokensPerWorkspace || !input.workspaceId) {
|
|
2204
2583
|
return { allowed: true };
|
|
2205
2584
|
}
|
|
2206
2585
|
const used = await sumUsageQuantity(deps.db, {
|
|
@@ -7047,6 +7426,8 @@ import {
|
|
|
7047
7426
|
getSandbox as getSandbox4,
|
|
7048
7427
|
getSessionTurnXaiProviderAccountAuthoritySnapshot as getSessionTurnXaiProviderAccountAuthoritySnapshot2,
|
|
7049
7428
|
getSession as getSession3,
|
|
7429
|
+
lockActiveWorkspaceGatewayCustomModelForAdmission as lockActiveWorkspaceGatewayCustomModelForAdmission2,
|
|
7430
|
+
lockActiveWorkspaceOpenRouterCustomModelForAdmission as lockActiveWorkspaceOpenRouterCustomModelForAdmission2,
|
|
7050
7431
|
nestedPostgresSqlState as nestedPostgresSqlState2,
|
|
7051
7432
|
requireWorkspace as requireWorkspace4,
|
|
7052
7433
|
scopedKnowledgeScopeKey,
|
|
@@ -7062,10 +7443,11 @@ import { CODEX_MODEL_ID_PREFIX, isCodexBilledModel } from "@opengeni/codex";
|
|
|
7062
7443
|
import {
|
|
7063
7444
|
canonicalizeConfiguredModelId,
|
|
7064
7445
|
configuredAllowedModels,
|
|
7446
|
+
WORKSPACE_GATEWAY_MODEL_ID_PREFIX as WORKSPACE_GATEWAY_MODEL_ID_PREFIX2,
|
|
7447
|
+
WORKSPACE_OPENROUTER_MODEL_ID_PREFIX as WORKSPACE_OPENROUTER_MODEL_ID_PREFIX2,
|
|
7065
7448
|
resolveFirstPartyMcpToolPolicy,
|
|
7066
7449
|
policyProviderIdForModel,
|
|
7067
7450
|
resolveTurnExecutionPolicyV1,
|
|
7068
|
-
WORKSPACE_GATEWAY_MODEL_ID_PREFIX,
|
|
7069
7451
|
XAI_SUBSCRIPTION_MODEL_ID_PREFIX
|
|
7070
7452
|
} from "@opengeni/config";
|
|
7071
7453
|
import {
|
|
@@ -7079,15 +7461,18 @@ import {
|
|
|
7079
7461
|
SessionSpawnDenial,
|
|
7080
7462
|
ServiceTurnInitiator,
|
|
7081
7463
|
ServiceTurnInitiatorContext,
|
|
7082
|
-
evaluateWorkspaceModelPolicy,
|
|
7464
|
+
evaluateWorkspaceModelPolicy as evaluateWorkspaceModelPolicy2,
|
|
7083
7465
|
normalizeAutomaticSessionTitle,
|
|
7084
7466
|
resolveWorkspaceSessionToolDefaults as resolveWorkspaceSessionToolDefaults2,
|
|
7467
|
+
metadataWithTurnExecutionPolicyV1,
|
|
7468
|
+
readTurnExecutionPolicyV1,
|
|
7085
7469
|
stableJson as stableJson4,
|
|
7086
7470
|
SessionMcpApprovalPolicy
|
|
7087
7471
|
} from "@opengeni/contracts";
|
|
7088
7472
|
import {
|
|
7089
7473
|
createSession,
|
|
7090
7474
|
createSessionWithIdempotencyKeyResult,
|
|
7475
|
+
canonicalSessionCommandHash,
|
|
7091
7476
|
encryptVariableSetValue as encryptVariableSetValue2,
|
|
7092
7477
|
getAnySessionInGroup,
|
|
7093
7478
|
getEnrollment as getEnrollment2,
|
|
@@ -7098,10 +7483,10 @@ import {
|
|
|
7098
7483
|
listDistinctRigVersionIdsInGroup,
|
|
7099
7484
|
getSandbox as getSandbox3,
|
|
7100
7485
|
getSession as getSession2,
|
|
7486
|
+
getInitializedSessionCreateReplay,
|
|
7101
7487
|
getSessionAuthorityProjection as getSessionAuthorityProjection2,
|
|
7102
7488
|
SessionIdConflictError,
|
|
7103
7489
|
NewSessionDraftConflictError,
|
|
7104
|
-
getSessionSpawnDenialByIdempotencyKey,
|
|
7105
7490
|
getWorkspaceControlEvent,
|
|
7106
7491
|
getSessionLineage,
|
|
7107
7492
|
getSessionTurn,
|
|
@@ -7113,7 +7498,10 @@ import {
|
|
|
7113
7498
|
initializeSessionStartAtomically,
|
|
7114
7499
|
listSessionTurns,
|
|
7115
7500
|
listSessionMcpServersForChildInheritance,
|
|
7501
|
+
lockActiveWorkspaceGatewayCustomModelForAdmission,
|
|
7502
|
+
lockActiveWorkspaceOpenRouterCustomModelForAdmission,
|
|
7116
7503
|
requireSession as requireSession2,
|
|
7504
|
+
replaySubmittedHumanPromptFromBoundaryReceipt,
|
|
7117
7505
|
submitHumanPromptInTransaction,
|
|
7118
7506
|
appendSessionEventsWithLockedSessionUpdate,
|
|
7119
7507
|
updateSessionTitleWithEvent,
|
|
@@ -7998,16 +8386,43 @@ function automaticTitleForAgentChildCreate(presentation, goal, initialMessage) {
|
|
|
7998
8386
|
return null;
|
|
7999
8387
|
}
|
|
8000
8388
|
async function createAndStartSessionWithOutcome(input) {
|
|
8001
|
-
const sessionMetadata =
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8389
|
+
const sessionMetadata = metadataWithTurnExecutionPolicyV1(
|
|
8390
|
+
{
|
|
8391
|
+
...input.metadata,
|
|
8392
|
+
model: input.model,
|
|
8393
|
+
reasoningEffort: input.reasoningEffort,
|
|
8394
|
+
...input.latencyMode !== void 0 ? { latencyMode: input.latencyMode } : {}
|
|
8395
|
+
},
|
|
8396
|
+
input.turnExecutionPolicy
|
|
8397
|
+
);
|
|
8007
8398
|
const frozenCreatedByContext = freezeAgentChildAutomaticTitleInCreatorContext(
|
|
8008
8399
|
input.createdByContext,
|
|
8009
8400
|
input.initialAutomaticTitle
|
|
8010
8401
|
);
|
|
8402
|
+
const requiresActiveWorkspaceCustomModel = (input.workspaceCustomModel === true || input.workspaceGatewayCustomModel === true) && input.retainWorkspaceCustomModel !== true && input.retainWorkspaceGatewayModel !== true;
|
|
8403
|
+
const beforeCreateCommit = requiresActiveWorkspaceCustomModel || input.beforeCreateCommit ? async (tx, sessionId, context) => {
|
|
8404
|
+
if (requiresActiveWorkspaceCustomModel && context?.created !== false) {
|
|
8405
|
+
const openRouter = input.model.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX2);
|
|
8406
|
+
const upstreamModelId = input.model.slice(
|
|
8407
|
+
openRouter ? WORKSPACE_OPENROUTER_MODEL_ID_PREFIX2.length : WORKSPACE_GATEWAY_MODEL_ID_PREFIX2.length
|
|
8408
|
+
);
|
|
8409
|
+
const active = openRouter ? await lockActiveWorkspaceOpenRouterCustomModelForAdmission(tx, {
|
|
8410
|
+
accountId: input.accountId,
|
|
8411
|
+
workspaceId: input.workspaceId,
|
|
8412
|
+
upstreamModelId
|
|
8413
|
+
}) : await lockActiveWorkspaceGatewayCustomModelForAdmission(tx, {
|
|
8414
|
+
accountId: input.accountId,
|
|
8415
|
+
workspaceId: input.workspaceId,
|
|
8416
|
+
upstreamModelId
|
|
8417
|
+
});
|
|
8418
|
+
if (!active) {
|
|
8419
|
+
throw new HTTPException11(422, {
|
|
8420
|
+
message: `model is not available: ${input.model}`
|
|
8421
|
+
});
|
|
8422
|
+
}
|
|
8423
|
+
}
|
|
8424
|
+
await input.beforeCreateCommit?.(tx, sessionId);
|
|
8425
|
+
} : void 0;
|
|
8011
8426
|
if (input.createIdempotencyKey) {
|
|
8012
8427
|
const keyedResult = await createSessionWithIdempotencyKeyResult(input.db, {
|
|
8013
8428
|
...input.requestedSessionId ? { requestedSessionId: input.requestedSessionId } : {},
|
|
@@ -8050,15 +8465,23 @@ async function createAndStartSessionWithOutcome(input) {
|
|
|
8050
8465
|
maxNestedAgentDepthOverride: input.maxNestedAgentDepthOverride ?? null,
|
|
8051
8466
|
allowNestedAgentDepthIncrease: input.allowNestedAgentDepthIncrease ?? false,
|
|
8052
8467
|
subjectId: input.subjectId ?? null,
|
|
8053
|
-
...
|
|
8468
|
+
...beforeCreateCommit ? { beforeCreateCommit } : {}
|
|
8054
8469
|
});
|
|
8055
8470
|
if (keyedResult.denied) {
|
|
8056
8471
|
throw new SessionSpawnDeniedError(SessionSpawnDenial.parse(keyedResult.denial));
|
|
8057
8472
|
}
|
|
8058
8473
|
const { session: keyed, created } = keyedResult;
|
|
8059
8474
|
if (!created) {
|
|
8475
|
+
const persistedPolicy = readTurnExecutionPolicyV1(keyed.metadata);
|
|
8060
8476
|
const finished3 = await finishStartSession(
|
|
8061
|
-
keyed.temporalWorkflowId ? {
|
|
8477
|
+
keyed.temporalWorkflowId ? {
|
|
8478
|
+
...input,
|
|
8479
|
+
seedTargetSandbox: null,
|
|
8480
|
+
...persistedPolicy.kind === "valid" ? { turnExecutionPolicy: persistedPolicy.policy } : {}
|
|
8481
|
+
} : {
|
|
8482
|
+
...input,
|
|
8483
|
+
...persistedPolicy.kind === "valid" ? { turnExecutionPolicy: persistedPolicy.policy } : {}
|
|
8484
|
+
},
|
|
8062
8485
|
keyed
|
|
8063
8486
|
);
|
|
8064
8487
|
return {
|
|
@@ -8118,7 +8541,7 @@ async function createAndStartSessionWithOutcome(input) {
|
|
|
8118
8541
|
maxNestedAgentDepthOverride: input.maxNestedAgentDepthOverride ?? null,
|
|
8119
8542
|
allowNestedAgentDepthIncrease: input.allowNestedAgentDepthIncrease ?? false,
|
|
8120
8543
|
subjectId: input.subjectId ?? null,
|
|
8121
|
-
...
|
|
8544
|
+
...beforeCreateCommit ? { beforeCreateCommit } : {}
|
|
8122
8545
|
});
|
|
8123
8546
|
} catch (error) {
|
|
8124
8547
|
if (error instanceof SessionSpawnDeniedDbError) {
|
|
@@ -8237,9 +8660,6 @@ function canonicalConfiguredModel(settings, model) {
|
|
|
8237
8660
|
if (settings.supergrokSubscriptionEnabled && canonicalModel.startsWith(XAI_SUBSCRIPTION_MODEL_ID_PREFIX)) {
|
|
8238
8661
|
return canonicalModel;
|
|
8239
8662
|
}
|
|
8240
|
-
if (canonicalModel.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX)) {
|
|
8241
|
-
return canonicalModel;
|
|
8242
|
-
}
|
|
8243
8663
|
throw new HTTPException11(422, { message: `model is not available: ${model}` });
|
|
8244
8664
|
}
|
|
8245
8665
|
function assertConfiguredModel(settings, model) {
|
|
@@ -8276,7 +8696,7 @@ async function assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model
|
|
|
8276
8696
|
return;
|
|
8277
8697
|
}
|
|
8278
8698
|
const providerId = policyProviderIdForModel(settings, canonicalModel);
|
|
8279
|
-
const verdict =
|
|
8699
|
+
const verdict = evaluateWorkspaceModelPolicy2(policy, {
|
|
8280
8700
|
providerId,
|
|
8281
8701
|
modelId: canonicalModel
|
|
8282
8702
|
});
|
|
@@ -8298,91 +8718,8 @@ async function requireQueuedTurnForApi(db, workspaceId, sessionId, turnId) {
|
|
|
8298
8718
|
}
|
|
8299
8719
|
return turn;
|
|
8300
8720
|
}
|
|
8301
|
-
|
|
8302
|
-
const { db, bus, workflowClient,
|
|
8303
|
-
const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
|
|
8304
|
-
const requestedReasoningEffort = input.reasoningEffort ?? null;
|
|
8305
|
-
assertConfiguredModel(settings, requestedModel);
|
|
8306
|
-
await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, requestedModel);
|
|
8307
|
-
const sessionForModelGate = await requireSession2(db, workspaceId, sessionId);
|
|
8308
|
-
const effectiveModelForGate = requestedModel ?? sessionForModelGate.model;
|
|
8309
|
-
try {
|
|
8310
|
-
assertSessionAllowsProductModel(sessionForModelGate, effectiveModelForGate);
|
|
8311
|
-
} catch (error) {
|
|
8312
|
-
if (error instanceof CodexCompactionV2ProviderLockedError) {
|
|
8313
|
-
throw new HTTPException11(422, { message: error.message, cause: error });
|
|
8314
|
-
}
|
|
8315
|
-
throw error;
|
|
8316
|
-
}
|
|
8317
|
-
const operationKey = input.clientEventId ?? crypto.randomUUID();
|
|
8318
|
-
let result;
|
|
8319
|
-
try {
|
|
8320
|
-
result = await runIdempotentPersistenceTransaction(
|
|
8321
|
-
{
|
|
8322
|
-
stage: "session.prompt.submit",
|
|
8323
|
-
eventTypes: ["user.message", "turn.queued", "session.status.changed"],
|
|
8324
|
-
maxAttempts: 3
|
|
8325
|
-
},
|
|
8326
|
-
async () => await withWorkspaceSubjectSessionActivityRls(
|
|
8327
|
-
db,
|
|
8328
|
-
workspaceId,
|
|
8329
|
-
input.actor ?? accountId,
|
|
8330
|
-
(scoped) => submitHumanPromptInTransaction(scoped, {
|
|
8331
|
-
accountId,
|
|
8332
|
-
workspaceId,
|
|
8333
|
-
sessionId,
|
|
8334
|
-
subjectId: input.actor ?? accountId,
|
|
8335
|
-
...input.actorLabel ? { subjectLabel: input.actorLabel } : {},
|
|
8336
|
-
actor: input.commandActor ?? {
|
|
8337
|
-
type: "human",
|
|
8338
|
-
subjectId: input.actor ?? accountId
|
|
8339
|
-
},
|
|
8340
|
-
operationKey,
|
|
8341
|
-
delivery: input.delivery ?? "send",
|
|
8342
|
-
controlEtag: input.controlEtag ?? null,
|
|
8343
|
-
expectedDraftRevision: input.expectedDraftRevision ?? null,
|
|
8344
|
-
text: input.text,
|
|
8345
|
-
annotations: input.annotations ?? [],
|
|
8346
|
-
modelContext: input.modelContext ?? null,
|
|
8347
|
-
resources: input.resources,
|
|
8348
|
-
...input.composerDraftResources ? { composerDraftResources: input.composerDraftResources } : {},
|
|
8349
|
-
model: requestedModel,
|
|
8350
|
-
reasoningEffort: requestedReasoningEffort,
|
|
8351
|
-
latencyMode: input.latencyMode ?? null,
|
|
8352
|
-
reasoningEffortFallback: input.reasoningEffortFallback ?? settings.openaiReasoningEffort,
|
|
8353
|
-
turnExecutionPolicy: input.turnExecutionPolicy,
|
|
8354
|
-
source: input.origin === "operator" ? "api" : "user",
|
|
8355
|
-
...input.recordAgentRunUsage !== void 0 ? { recordAgentRunUsage: input.recordAgentRunUsage } : {},
|
|
8356
|
-
personalConnectionDelegations: input.personalConnectionDelegations ?? [],
|
|
8357
|
-
...input.personalResourceAttachment ? {
|
|
8358
|
-
personalResourceAttachment: input.personalResourceAttachment
|
|
8359
|
-
} : {},
|
|
8360
|
-
mcpCredentialUpdates: input.mcpCredentialUpdates ?? [],
|
|
8361
|
-
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs()
|
|
8362
|
-
})
|
|
8363
|
-
)
|
|
8364
|
-
);
|
|
8365
|
-
} catch (error) {
|
|
8366
|
-
if (error instanceof WorkspaceControlBusyError) {
|
|
8367
|
-
throw error;
|
|
8368
|
-
}
|
|
8369
|
-
if (error instanceof PersonalResourceAttachmentAcceptanceError) {
|
|
8370
|
-
throw new HTTPException11(
|
|
8371
|
-
error.kind === "invalid" ? 422 : error.kind === "forbidden" ? 403 : 409,
|
|
8372
|
-
{ message: error.message, cause: error }
|
|
8373
|
-
);
|
|
8374
|
-
}
|
|
8375
|
-
if (error instanceof QueueCommandConflictError || error instanceof SessionControlConflictError) {
|
|
8376
|
-
throw new HTTPException11(409, { message: error.message });
|
|
8377
|
-
}
|
|
8378
|
-
if (error instanceof Error && error.message.includes("cancelled")) {
|
|
8379
|
-
throw new HTTPException11(409, { message: error.message });
|
|
8380
|
-
}
|
|
8381
|
-
if (error instanceof Error && error.message.startsWith("Unknown session MCP server")) {
|
|
8382
|
-
throw new HTTPException11(422, { message: error.message });
|
|
8383
|
-
}
|
|
8384
|
-
throw error;
|
|
8385
|
-
}
|
|
8721
|
+
function finalizePostUserMessageTurn(input, result) {
|
|
8722
|
+
const { db, bus, workflowClient, accountId, workspaceId, sessionId } = input;
|
|
8386
8723
|
const postCommitTask = async () => {
|
|
8387
8724
|
await Promise.all([
|
|
8388
8725
|
(async () => {
|
|
@@ -8473,18 +8810,132 @@ async function postUserMessageTurn(input) {
|
|
|
8473
8810
|
replay: result.replay
|
|
8474
8811
|
};
|
|
8475
8812
|
}
|
|
8476
|
-
function
|
|
8477
|
-
const
|
|
8478
|
-
const
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8813
|
+
async function postUserMessageTurn(input) {
|
|
8814
|
+
const { db, settings, accountId, workspaceId, sessionId } = input;
|
|
8815
|
+
const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
|
|
8816
|
+
const requestedReasoningEffort = input.reasoningEffort ?? null;
|
|
8817
|
+
assertConfiguredModel(settings, requestedModel);
|
|
8818
|
+
const sessionForModelGate = await requireSession2(db, workspaceId, sessionId);
|
|
8819
|
+
const effectiveModelForGate = requestedModel ?? sessionForModelGate.model;
|
|
8820
|
+
const freshWorkspaceCustomModel = requestedModel !== null && isWorkspaceCustomModelId(settings, requestedModel) && requestedModel !== sessionForModelGate.model ? requestedModel : null;
|
|
8821
|
+
await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, effectiveModelForGate);
|
|
8822
|
+
try {
|
|
8823
|
+
assertSessionAllowsProductModel(sessionForModelGate, effectiveModelForGate);
|
|
8824
|
+
} catch (error) {
|
|
8825
|
+
if (error instanceof CodexCompactionV2ProviderLockedError) {
|
|
8826
|
+
throw new HTTPException11(422, { message: error.message, cause: error });
|
|
8827
|
+
}
|
|
8828
|
+
throw error;
|
|
8483
8829
|
}
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8830
|
+
const operationKey = input.clientEventId ?? crypto.randomUUID();
|
|
8831
|
+
let result;
|
|
8832
|
+
try {
|
|
8833
|
+
result = await runIdempotentPersistenceTransaction(
|
|
8834
|
+
{
|
|
8835
|
+
stage: "session.prompt.submit",
|
|
8836
|
+
eventTypes: ["user.message", "turn.queued", "session.status.changed"],
|
|
8837
|
+
maxAttempts: 3
|
|
8838
|
+
},
|
|
8839
|
+
async () => await withWorkspaceSubjectSessionActivityRls(
|
|
8840
|
+
db,
|
|
8841
|
+
workspaceId,
|
|
8842
|
+
input.actor ?? accountId,
|
|
8843
|
+
(scoped) => submitHumanPromptInTransaction(scoped, {
|
|
8844
|
+
accountId,
|
|
8845
|
+
workspaceId,
|
|
8846
|
+
sessionId,
|
|
8847
|
+
subjectId: input.actor ?? accountId,
|
|
8848
|
+
...input.actorLabel ? { subjectLabel: input.actorLabel } : {},
|
|
8849
|
+
actor: input.commandActor ?? {
|
|
8850
|
+
type: "human",
|
|
8851
|
+
subjectId: input.actor ?? accountId
|
|
8852
|
+
},
|
|
8853
|
+
operationKey,
|
|
8854
|
+
...input.boundaryRequestHash ? { boundaryRequestHash: input.boundaryRequestHash } : {},
|
|
8855
|
+
delivery: input.delivery ?? "send",
|
|
8856
|
+
controlEtag: input.controlEtag ?? null,
|
|
8857
|
+
expectedDraftRevision: input.expectedDraftRevision ?? null,
|
|
8858
|
+
text: input.text,
|
|
8859
|
+
annotations: input.annotations ?? [],
|
|
8860
|
+
modelContext: input.modelContext ?? null,
|
|
8861
|
+
resources: input.resources,
|
|
8862
|
+
...input.composerDraftResources ? { composerDraftResources: input.composerDraftResources } : {},
|
|
8863
|
+
model: requestedModel,
|
|
8864
|
+
reasoningEffort: requestedReasoningEffort,
|
|
8865
|
+
latencyMode: input.latencyMode ?? null,
|
|
8866
|
+
reasoningEffortFallback: input.reasoningEffortFallback ?? settings.openaiReasoningEffort,
|
|
8867
|
+
turnExecutionPolicy: input.turnExecutionPolicy,
|
|
8868
|
+
source: input.origin === "operator" ? "api" : "user",
|
|
8869
|
+
...input.recordAgentRunUsage !== void 0 ? { recordAgentRunUsage: input.recordAgentRunUsage } : {},
|
|
8870
|
+
personalConnectionDelegations: input.personalConnectionDelegations ?? [],
|
|
8871
|
+
...input.personalResourceAttachment ? {
|
|
8872
|
+
personalResourceAttachment: input.personalResourceAttachment
|
|
8873
|
+
} : {},
|
|
8874
|
+
mcpCredentialUpdates: input.mcpCredentialUpdates ?? [],
|
|
8875
|
+
...freshWorkspaceCustomModel ? {
|
|
8876
|
+
beforeFreshPromptCommit: async (tx) => {
|
|
8877
|
+
const reference = workspaceCustomModelReference(
|
|
8878
|
+
settings,
|
|
8879
|
+
freshWorkspaceCustomModel
|
|
8880
|
+
);
|
|
8881
|
+
if (!reference) {
|
|
8882
|
+
throw new Error("workspace custom model reference disappeared");
|
|
8883
|
+
}
|
|
8884
|
+
const active = reference.providerKind === "openrouter" ? await lockActiveWorkspaceOpenRouterCustomModelForAdmission(tx, {
|
|
8885
|
+
accountId,
|
|
8886
|
+
workspaceId,
|
|
8887
|
+
upstreamModelId: reference.upstreamModelId
|
|
8888
|
+
}) : await lockActiveWorkspaceGatewayCustomModelForAdmission(tx, {
|
|
8889
|
+
accountId,
|
|
8890
|
+
workspaceId,
|
|
8891
|
+
upstreamModelId: reference.upstreamModelId
|
|
8892
|
+
});
|
|
8893
|
+
if (!active) {
|
|
8894
|
+
throw new HTTPException11(422, {
|
|
8895
|
+
message: `model is not available: ${freshWorkspaceCustomModel}`
|
|
8896
|
+
});
|
|
8897
|
+
}
|
|
8898
|
+
}
|
|
8899
|
+
} : {},
|
|
8900
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs()
|
|
8901
|
+
})
|
|
8902
|
+
)
|
|
8903
|
+
);
|
|
8904
|
+
} catch (error) {
|
|
8905
|
+
if (error instanceof WorkspaceControlBusyError) {
|
|
8906
|
+
throw error;
|
|
8907
|
+
}
|
|
8908
|
+
if (error instanceof PersonalResourceAttachmentAcceptanceError) {
|
|
8909
|
+
throw new HTTPException11(
|
|
8910
|
+
error.kind === "invalid" ? 422 : error.kind === "forbidden" ? 403 : 409,
|
|
8911
|
+
{ message: error.message, cause: error }
|
|
8912
|
+
);
|
|
8913
|
+
}
|
|
8914
|
+
if (error instanceof QueueCommandConflictError || error instanceof SessionControlConflictError) {
|
|
8915
|
+
throw new HTTPException11(409, { message: error.message });
|
|
8916
|
+
}
|
|
8917
|
+
if (error instanceof Error && error.message.includes("cancelled")) {
|
|
8918
|
+
throw new HTTPException11(409, { message: error.message });
|
|
8919
|
+
}
|
|
8920
|
+
if (error instanceof Error && error.message.startsWith("Unknown session MCP server")) {
|
|
8921
|
+
throw new HTTPException11(422, { message: error.message });
|
|
8922
|
+
}
|
|
8923
|
+
throw error;
|
|
8924
|
+
}
|
|
8925
|
+
return finalizePostUserMessageTurn(input, result);
|
|
8926
|
+
}
|
|
8927
|
+
function resolveChildGoalFromAcceptedSnapshot(goal, parentGoalSnapshot) {
|
|
8928
|
+
const inheritedRootConstraints = parentGoalSnapshot.state === "none" ? [] : parentGoalSnapshot.rootConstraints;
|
|
8929
|
+
const requestedRootConstraints = goal.rootConstraints;
|
|
8930
|
+
if (requestedRootConstraints?.some((constraint) => !inheritedRootConstraints.includes(constraint))) {
|
|
8931
|
+
throw new Error(
|
|
8932
|
+
"child goal rootConstraints must be an exact subset of the calling turn's frozen root constraints"
|
|
8933
|
+
);
|
|
8934
|
+
}
|
|
8935
|
+
return {
|
|
8936
|
+
...goal,
|
|
8937
|
+
rootConstraints: requestedRootConstraints ?? inheritedRootConstraints
|
|
8938
|
+
};
|
|
8488
8939
|
}
|
|
8489
8940
|
function resolveSessionCreateVisibility(input) {
|
|
8490
8941
|
if (input.parentVisibility === "user_private") {
|
|
@@ -8501,9 +8952,56 @@ function resolveSessionCreateVisibility(input) {
|
|
|
8501
8952
|
}
|
|
8502
8953
|
return input.requestedVisibility === "private" ? "user_private" : "workspace_shared";
|
|
8503
8954
|
}
|
|
8504
|
-
async function
|
|
8505
|
-
const
|
|
8955
|
+
async function resolveWorkspaceModelBoundarySettings(deps, grant, workspaceId, modelIds, retainedProductModelId) {
|
|
8956
|
+
const retainedWorkspaceModel = retainedProductModelId?.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX2) === true || retainedProductModelId?.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX2) === true;
|
|
8957
|
+
if (deps.catalogSourceSettings) {
|
|
8958
|
+
if (!retainedWorkspaceModel) return deps.settings;
|
|
8959
|
+
}
|
|
8960
|
+
const workspaceModelIds = modelIds.filter(
|
|
8961
|
+
(modelId) => typeof modelId === "string" && (modelId.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX2) || modelId.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX2))
|
|
8962
|
+
);
|
|
8963
|
+
const needsWorkspaceResolution = deps.settings.modelCatalogSource === "database" || workspaceModelIds.length > 0;
|
|
8964
|
+
if (!needsWorkspaceResolution) return deps.settings;
|
|
8965
|
+
return (await resolveWorkspaceCatalogSettings(deps.db, deps.catalogSourceSettings ?? deps.settings, {
|
|
8966
|
+
accountId: grant.accountId,
|
|
8967
|
+
workspaceId,
|
|
8968
|
+
...retainedProductModelId !== void 0 ? { retainedProductModelId } : {}
|
|
8969
|
+
})).settings;
|
|
8970
|
+
}
|
|
8971
|
+
async function withSessionCreateUsageRecording(input) {
|
|
8972
|
+
let usageRecording = "recorded";
|
|
8973
|
+
if (input.startMode !== "realtime") {
|
|
8974
|
+
try {
|
|
8975
|
+
await recordWorkspaceUsage(input.deps, {
|
|
8976
|
+
accountId: input.grant.accountId,
|
|
8977
|
+
workspaceId: input.workspaceId,
|
|
8978
|
+
subjectId: input.grant.subjectId,
|
|
8979
|
+
eventType: "agent_run.created",
|
|
8980
|
+
quantity: 1,
|
|
8981
|
+
unit: "run",
|
|
8982
|
+
sourceResourceType: "session",
|
|
8983
|
+
sourceResourceId: input.createOutcome.session.id,
|
|
8984
|
+
sessionId: input.createOutcome.session.id,
|
|
8985
|
+
initiator: input.createOutcome.session.createdBy,
|
|
8986
|
+
initiatorContext: input.createOutcome.session.createdByContext,
|
|
8987
|
+
origin: input.origin,
|
|
8988
|
+
idempotencyKey: `agent_run.created:${input.workspaceId}:${input.createOutcome.session.id}`
|
|
8989
|
+
});
|
|
8990
|
+
} catch (error) {
|
|
8991
|
+
usageRecording = "failed";
|
|
8992
|
+
reportSessionUsageRecordingFailure(error);
|
|
8993
|
+
}
|
|
8994
|
+
}
|
|
8995
|
+
return { ...input.createOutcome, usageRecording };
|
|
8996
|
+
}
|
|
8997
|
+
async function createSessionForRequestWithOutcome(unresolvedDeps, grant, workspaceId, rawPayload, authorization, agentChildPresentation) {
|
|
8506
8998
|
const payload = CreateSessionRequest.parse(rawPayload);
|
|
8999
|
+
if (hasReservedOpenGeniSlackBotSessionMetadata(payload.metadata)) {
|
|
9000
|
+
throw new HTTPException11(422, {
|
|
9001
|
+
message: `${OPENGENI_SLACK_BOT_SESSION_METADATA_KEY2} is reserved for scheduler routing`
|
|
9002
|
+
});
|
|
9003
|
+
}
|
|
9004
|
+
const db = unresolvedDeps.db;
|
|
8507
9005
|
const visibilityProvided = hasOwnProperty(rawPayload, "visibility");
|
|
8508
9006
|
if (payload.visibility === "private" && !grant.metadata?.["sessionId"]) {
|
|
8509
9007
|
if (!authorization) {
|
|
@@ -8511,39 +9009,17 @@ async function createSessionForRequestWithOutcome(deps, grant, workspaceId, rawP
|
|
|
8511
9009
|
message: "managed human session required"
|
|
8512
9010
|
});
|
|
8513
9011
|
}
|
|
8514
|
-
await requireManagedHumanPrivateSessionCreate(
|
|
9012
|
+
await requireManagedHumanPrivateSessionCreate(unresolvedDeps, authorization, workspaceId);
|
|
8515
9013
|
if (payload.sandbox === "shared" || typeof payload.sandbox === "object") {
|
|
8516
9014
|
throw new HTTPException11(422, {
|
|
8517
9015
|
message: "Only-me sessions require their own sandbox"
|
|
8518
9016
|
});
|
|
8519
9017
|
}
|
|
8520
9018
|
}
|
|
8521
|
-
if (hasReservedOpenGeniSlackBotSessionMetadata(payload.metadata)) {
|
|
8522
|
-
throw new HTTPException11(422, {
|
|
8523
|
-
message: `${OPENGENI_SLACK_BOT_SESSION_METADATA_KEY2} is reserved for scheduler routing`
|
|
8524
|
-
});
|
|
8525
|
-
}
|
|
8526
|
-
if (payload.idempotencyKey) {
|
|
8527
|
-
const denial = await getSessionSpawnDenialByIdempotencyKey(
|
|
8528
|
-
db,
|
|
8529
|
-
workspaceId,
|
|
8530
|
-
payload.idempotencyKey
|
|
8531
|
-
);
|
|
8532
|
-
if (denial) {
|
|
8533
|
-
throw new SessionSpawnDeniedError(SessionSpawnDenial.parse(denial));
|
|
8534
|
-
}
|
|
8535
|
-
}
|
|
8536
|
-
await requireAtomicPersonalResourceAttachment(
|
|
8537
|
-
deps,
|
|
8538
|
-
authorization,
|
|
8539
|
-
workspaceId,
|
|
8540
|
-
payload.personalResourceAttachment,
|
|
8541
|
-
false
|
|
8542
|
-
);
|
|
8543
9019
|
const parentSessionId = typeof grant.metadata?.["sessionId"] === "string" ? grant.metadata["sessionId"] : null;
|
|
8544
9020
|
if (parentSessionId) {
|
|
8545
9021
|
try {
|
|
8546
|
-
await requireSessionAuthorization(
|
|
9022
|
+
await requireSessionAuthorization(unresolvedDeps, grant, {
|
|
8547
9023
|
sessionId: parentSessionId,
|
|
8548
9024
|
operation: "session.child.create",
|
|
8549
9025
|
surface: "core"
|
|
@@ -8593,6 +9069,102 @@ async function createSessionForRequestWithOutcome(deps, grant, workspaceId, rawP
|
|
|
8593
9069
|
message: "caller attempt does not belong to the parent session"
|
|
8594
9070
|
});
|
|
8595
9071
|
}
|
|
9072
|
+
const replayManagedHumanSubjectId = creationInitiator.actor ? parentCallingTurn?.initiatingHumanSubjectId ?? (parentCallingTurn?.initiator.kind === "subject" ? parentCallingTurn.initiator.subjectId : null) : authorization?.canonicalManagedHumanSession || grant.principalKind === "human_session" ? grant.subjectId : null;
|
|
9073
|
+
let retainedKeyedShellModel = null;
|
|
9074
|
+
if (payload.idempotencyKey && (effectiveVisibility !== "user_private" || replayManagedHumanSubjectId !== null)) {
|
|
9075
|
+
try {
|
|
9076
|
+
const initializedReplay = await getInitializedSessionCreateReplay(db, {
|
|
9077
|
+
accountId: grant.accountId,
|
|
9078
|
+
workspaceId,
|
|
9079
|
+
subjectId: replayManagedHumanSubjectId ?? grant.subjectId,
|
|
9080
|
+
...replayManagedHumanSubjectId ? { activeManagedHumanSubjectId: replayManagedHumanSubjectId } : {},
|
|
9081
|
+
createIdempotencyKey: payload.idempotencyKey,
|
|
9082
|
+
...payload.requestedSessionId ? { requestedSessionId: payload.requestedSessionId } : {},
|
|
9083
|
+
visibility: effectiveVisibility,
|
|
9084
|
+
variableSetIds: payload.variableSetIds ?? [],
|
|
9085
|
+
initialPersonalResourceAttachmentIntent: payload.personalResourceAttachment ?? null,
|
|
9086
|
+
deferInitialTurn: payload.startMode === "realtime"
|
|
9087
|
+
});
|
|
9088
|
+
if (initializedReplay) {
|
|
9089
|
+
if (initializedReplay.outcome === "denied") {
|
|
9090
|
+
throw new SessionSpawnDeniedError(SessionSpawnDenial.parse(initializedReplay.denial));
|
|
9091
|
+
}
|
|
9092
|
+
if (initializedReplay.outcome === "pending") {
|
|
9093
|
+
retainedKeyedShellModel = initializedReplay.session.model;
|
|
9094
|
+
} else {
|
|
9095
|
+
if (initializedReplay.workflowWakeRevision !== null) {
|
|
9096
|
+
await unresolvedDeps.workflowClient.wakeSessionWorkflow({
|
|
9097
|
+
accountId: grant.accountId,
|
|
9098
|
+
workspaceId,
|
|
9099
|
+
sessionId: initializedReplay.session.id,
|
|
9100
|
+
workflowId: initializedReplay.temporalWorkflowId,
|
|
9101
|
+
wakeRevision: initializedReplay.workflowWakeRevision
|
|
9102
|
+
});
|
|
9103
|
+
}
|
|
9104
|
+
return await withSessionCreateUsageRecording({
|
|
9105
|
+
deps: unresolvedDeps,
|
|
9106
|
+
grant,
|
|
9107
|
+
workspaceId,
|
|
9108
|
+
startMode: payload.startMode,
|
|
9109
|
+
origin: creationInitiator.actor ? "system" : "user",
|
|
9110
|
+
createOutcome: {
|
|
9111
|
+
session: initializedReplay.session,
|
|
9112
|
+
outcome: initializedReplay.changed ? "repaired" : "replayed",
|
|
9113
|
+
replay: !initializedReplay.changed,
|
|
9114
|
+
changed: initializedReplay.changed
|
|
9115
|
+
}
|
|
9116
|
+
});
|
|
9117
|
+
}
|
|
9118
|
+
}
|
|
9119
|
+
} catch (error) {
|
|
9120
|
+
if (error instanceof SessionIdConflictError) {
|
|
9121
|
+
throw new HTTPException11(409, {
|
|
9122
|
+
message: "requested session id is already in use"
|
|
9123
|
+
});
|
|
9124
|
+
}
|
|
9125
|
+
if (error instanceof SessionCreateIdempotencyConflictError) {
|
|
9126
|
+
throw new HTTPException11(409, { message: error.message, cause: error });
|
|
9127
|
+
}
|
|
9128
|
+
throw error;
|
|
9129
|
+
}
|
|
9130
|
+
}
|
|
9131
|
+
let settings = await resolveWorkspaceModelBoundarySettings(
|
|
9132
|
+
unresolvedDeps,
|
|
9133
|
+
grant,
|
|
9134
|
+
workspaceId,
|
|
9135
|
+
[payload.model],
|
|
9136
|
+
retainedKeyedShellModel
|
|
9137
|
+
);
|
|
9138
|
+
let deps = settings === unresolvedDeps.settings ? unresolvedDeps : {
|
|
9139
|
+
...unresolvedDeps,
|
|
9140
|
+
catalogSourceSettings: unresolvedDeps.catalogSourceSettings ?? unresolvedDeps.settings,
|
|
9141
|
+
settings
|
|
9142
|
+
};
|
|
9143
|
+
const { bus, workflowClient, objectStorage } = deps;
|
|
9144
|
+
await requireAtomicPersonalResourceAttachment(
|
|
9145
|
+
deps,
|
|
9146
|
+
authorization,
|
|
9147
|
+
workspaceId,
|
|
9148
|
+
payload.personalResourceAttachment,
|
|
9149
|
+
false
|
|
9150
|
+
);
|
|
9151
|
+
const inheritedModel = parentCallingTurn?.model ?? parentSession?.model ?? settings.openaiModel;
|
|
9152
|
+
const effectiveModelId = payload.model ?? inheritedModel;
|
|
9153
|
+
const effectiveCatalogSettings = await resolveWorkspaceModelBoundarySettings(
|
|
9154
|
+
deps,
|
|
9155
|
+
grant,
|
|
9156
|
+
workspaceId,
|
|
9157
|
+
[effectiveModelId],
|
|
9158
|
+
parentSession ? inheritedModel : null
|
|
9159
|
+
);
|
|
9160
|
+
if (effectiveCatalogSettings !== settings) {
|
|
9161
|
+
deps = {
|
|
9162
|
+
...deps,
|
|
9163
|
+
catalogSourceSettings: deps.catalogSourceSettings ?? settings,
|
|
9164
|
+
settings: effectiveCatalogSettings
|
|
9165
|
+
};
|
|
9166
|
+
settings = effectiveCatalogSettings;
|
|
9167
|
+
}
|
|
8596
9168
|
let effectiveGoal = payload.goal;
|
|
8597
9169
|
if (parentSession && payload.goal) {
|
|
8598
9170
|
try {
|
|
@@ -8743,8 +9315,7 @@ async function createSessionForRequestWithOutcome(deps, grant, workspaceId, rawP
|
|
|
8743
9315
|
}
|
|
8744
9316
|
channelId = channel.id;
|
|
8745
9317
|
}
|
|
8746
|
-
const
|
|
8747
|
-
const model = canonicalConfiguredModel(settings, payload.model ?? inheritedModel);
|
|
9318
|
+
const model = canonicalConfiguredModel(settings, effectiveModelId);
|
|
8748
9319
|
if (model === null || model === void 0) {
|
|
8749
9320
|
throw new Error("effective session model unexpectedly resolved to null");
|
|
8750
9321
|
}
|
|
@@ -9057,6 +9628,8 @@ async function createSessionForRequestWithOutcome(deps, grant, workspaceId, rawP
|
|
|
9057
9628
|
sessionMcpServers: sessionMcpServers.metadata,
|
|
9058
9629
|
personalConnectionDelegations,
|
|
9059
9630
|
initialPersonalResourceAttachmentIntent: payload.personalResourceAttachment ?? null,
|
|
9631
|
+
workspaceCustomModel: isWorkspaceCustomModelId(settings, model),
|
|
9632
|
+
retainWorkspaceCustomModel: parentSession !== null && model === inheritedModel,
|
|
9060
9633
|
...xaiProviderAccountAuthoritySnapshot ? { xaiProviderAccountAuthoritySnapshot } : {},
|
|
9061
9634
|
parentSessionId,
|
|
9062
9635
|
createIdempotencyKey: payload.idempotencyKey ?? null,
|
|
@@ -9118,30 +9691,14 @@ async function createSessionForRequestWithOutcome(deps, grant, workspaceId, rawP
|
|
|
9118
9691
|
}
|
|
9119
9692
|
throw error;
|
|
9120
9693
|
}
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
quantity: 1,
|
|
9130
|
-
unit: "run",
|
|
9131
|
-
sourceResourceType: "session",
|
|
9132
|
-
sourceResourceId: createOutcome.session.id,
|
|
9133
|
-
sessionId: createOutcome.session.id,
|
|
9134
|
-
initiator: createOutcome.session.createdBy,
|
|
9135
|
-
initiatorContext: createOutcome.session.createdByContext,
|
|
9136
|
-
origin: creationInitiator.actor ? "system" : "user",
|
|
9137
|
-
idempotencyKey: `agent_run.created:${workspaceId}:${createOutcome.session.id}`
|
|
9138
|
-
});
|
|
9139
|
-
} catch (error) {
|
|
9140
|
-
usageRecording = "failed";
|
|
9141
|
-
reportSessionUsageRecordingFailure(error);
|
|
9142
|
-
}
|
|
9143
|
-
}
|
|
9144
|
-
return { ...createOutcome, usageRecording };
|
|
9694
|
+
return await withSessionCreateUsageRecording({
|
|
9695
|
+
deps,
|
|
9696
|
+
grant,
|
|
9697
|
+
workspaceId,
|
|
9698
|
+
startMode: payload.startMode,
|
|
9699
|
+
origin: creationInitiator.actor ? "system" : "user",
|
|
9700
|
+
createOutcome
|
|
9701
|
+
});
|
|
9145
9702
|
}
|
|
9146
9703
|
function reportSessionUsageRecordingFailure(_error) {
|
|
9147
9704
|
console.warn(
|
|
@@ -9156,163 +9713,294 @@ function reportSessionUsageRecordingFailure(_error) {
|
|
|
9156
9713
|
async function createSessionForRequest(deps, grant, workspaceId, rawPayload, authorization) {
|
|
9157
9714
|
return (await createSessionForRequestWithOutcome(deps, grant, workspaceId, rawPayload, authorization)).session;
|
|
9158
9715
|
}
|
|
9716
|
+
function sessionPromptBoundaryRequestHash(input) {
|
|
9717
|
+
return `prompt-boundary-v1:${canonicalSessionCommandHash({
|
|
9718
|
+
delivery: input.delivery,
|
|
9719
|
+
controlEtag: input.controlEtag,
|
|
9720
|
+
expectedDraftRevision: input.expectedDraftRevision,
|
|
9721
|
+
text: input.text,
|
|
9722
|
+
annotations: input.annotations,
|
|
9723
|
+
modelContext: input.modelContext,
|
|
9724
|
+
resources: input.resources,
|
|
9725
|
+
composerDraftResourcesProvided: input.composerDraftResources !== void 0,
|
|
9726
|
+
composerDraftResources: input.composerDraftResources ?? [],
|
|
9727
|
+
model: input.model,
|
|
9728
|
+
reasoningEffort: input.reasoningEffort,
|
|
9729
|
+
latencyMode: input.latencyMode,
|
|
9730
|
+
source: input.source,
|
|
9731
|
+
mcpCredentialUpdates: input.mcpCredentialUpdates,
|
|
9732
|
+
connectionAuthorities: input.connectionAuthorities ?? [],
|
|
9733
|
+
personalResourceAttachment: input.personalResourceAttachment ?? null,
|
|
9734
|
+
...input.commandActor.type === "service" ? {
|
|
9735
|
+
serviceInitiator: {
|
|
9736
|
+
subjectId: input.commandActor.subjectId,
|
|
9737
|
+
subjectLabel: input.commandActor.subjectLabel ?? null,
|
|
9738
|
+
context: input.commandActor.context ?? {}
|
|
9739
|
+
}
|
|
9740
|
+
} : {}
|
|
9741
|
+
})}`;
|
|
9742
|
+
}
|
|
9159
9743
|
async function acceptSessionUserMessageWithOutcome(deps, grant, workspaceId, sessionId, input) {
|
|
9160
|
-
const {
|
|
9744
|
+
const { db, bus, workflowClient, objectStorage } = deps;
|
|
9161
9745
|
const delegatedServiceInitiator = serviceInitiatorForGrant(grant);
|
|
9746
|
+
const delivery = input.delivery ?? "send";
|
|
9747
|
+
const source = delegatedServiceInitiator || input.origin === "operator" ? "api" : "user";
|
|
9748
|
+
const commandActor = delegatedServiceInitiator ? {
|
|
9749
|
+
type: "service",
|
|
9750
|
+
subjectId: delegatedServiceInitiator.initiator.subjectId,
|
|
9751
|
+
...delegatedServiceInitiator.initiator.label ? { subjectLabel: delegatedServiceInitiator.initiator.label } : {},
|
|
9752
|
+
context: delegatedServiceInitiator.context
|
|
9753
|
+
} : { type: "human", subjectId: grant.subjectId };
|
|
9162
9754
|
await requireSessionAuthorization(deps, grant, {
|
|
9163
9755
|
sessionId,
|
|
9164
|
-
operation:
|
|
9756
|
+
operation: delivery === "steer" ? "session.steer" : "session.append",
|
|
9165
9757
|
surface: "core"
|
|
9166
9758
|
});
|
|
9167
|
-
await requireAtomicPersonalResourceAttachment(
|
|
9168
|
-
deps,
|
|
9169
|
-
input.authorization,
|
|
9170
|
-
workspaceId,
|
|
9171
|
-
input.personalResourceAttachment,
|
|
9172
|
-
true
|
|
9173
|
-
);
|
|
9174
|
-
const existingSession = await requireSession2(db, workspaceId, sessionId);
|
|
9175
|
-
const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
|
|
9176
|
-
const effectiveModel = canonicalConfiguredModel(settings, requestedModel ?? existingSession.model) ?? null;
|
|
9177
|
-
if (effectiveModel === null) {
|
|
9178
|
-
throw new Error("effective follow-up model unexpectedly resolved to null");
|
|
9179
|
-
}
|
|
9180
|
-
try {
|
|
9181
|
-
assertSessionAllowsProductModel(existingSession, effectiveModel);
|
|
9182
|
-
} catch (error) {
|
|
9183
|
-
if (error instanceof CodexCompactionV2ProviderLockedError) {
|
|
9184
|
-
throw new HTTPException11(422, { message: error.message, cause: error });
|
|
9185
|
-
}
|
|
9186
|
-
throw error;
|
|
9187
|
-
}
|
|
9188
|
-
const sessionReasoningEffort = existingSession.reasoningEffort;
|
|
9189
|
-
const effectiveReasoningEffort = input.reasoningEffort ?? sessionReasoningEffort;
|
|
9190
|
-
const sessionLatencyMode = existingSession.latencyMode;
|
|
9191
|
-
const effectiveLatencyMode = input.latencyMode ?? sessionLatencyMode;
|
|
9192
|
-
const turnExecutionPolicy = resolveTurnExecutionPolicyV1(settings, {
|
|
9193
|
-
modelId: effectiveModel,
|
|
9194
|
-
requestedModelId: input.model ?? null,
|
|
9195
|
-
modelSource: input.model == null ? "session" : "explicit",
|
|
9196
|
-
reasoningEffort: effectiveReasoningEffort,
|
|
9197
|
-
reasoningSource: input.reasoningEffort == null ? "session" : "explicit",
|
|
9198
|
-
latencyMode: effectiveLatencyMode,
|
|
9199
|
-
latencyModeSource: input.latencyMode == null ? "session" : "explicit"
|
|
9200
|
-
});
|
|
9201
9759
|
const requestedResources = normalizeResources(input.resources ?? []);
|
|
9202
9760
|
const composerDraftResources = input.composerDraftResources ? normalizeResources(input.composerDraftResources) : void 0;
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
);
|
|
9208
|
-
if (unacceptedDraftResource) {
|
|
9209
|
-
throw new HTTPException11(422, {
|
|
9210
|
-
message: "composer draft resources must be included in the accepted resource set"
|
|
9211
|
-
});
|
|
9212
|
-
}
|
|
9213
|
-
}
|
|
9214
|
-
const annotations = await validateSubmittedTimelineAnnotations(
|
|
9215
|
-
db,
|
|
9216
|
-
workspaceId,
|
|
9217
|
-
sessionId,
|
|
9218
|
-
input.annotations ?? []
|
|
9219
|
-
);
|
|
9220
|
-
await requireLimit(deps, {
|
|
9221
|
-
accountId: grant.accountId,
|
|
9222
|
-
workspaceId,
|
|
9223
|
-
action: "agent_run:create",
|
|
9224
|
-
quantity: 1,
|
|
9225
|
-
model: effectiveModel
|
|
9226
|
-
});
|
|
9227
|
-
if (requestedResources.some((resource) => resource.kind === "file") && !objectStorage) {
|
|
9228
|
-
throw new HTTPException11(503, {
|
|
9229
|
-
message: "object storage is not configured"
|
|
9230
|
-
});
|
|
9231
|
-
}
|
|
9232
|
-
await validateFileResources(
|
|
9233
|
-
db,
|
|
9234
|
-
grant.accountId,
|
|
9235
|
-
workspaceId,
|
|
9236
|
-
grant.subjectId,
|
|
9237
|
-
requestedResources
|
|
9238
|
-
);
|
|
9239
|
-
await validateGitHubRepositorySelection(db, workspaceId, [
|
|
9240
|
-
...existingSession.resources,
|
|
9241
|
-
...requestedResources
|
|
9242
|
-
]);
|
|
9243
|
-
const mcpCredentialUpdates = validateSessionMcpCredentialUpdates({
|
|
9244
|
-
settings,
|
|
9245
|
-
grant,
|
|
9246
|
-
session: existingSession,
|
|
9247
|
-
updates: input.mcpCredentialUpdates ?? []
|
|
9248
|
-
});
|
|
9249
|
-
const connectionDelegationSource = personalConnectionDelegationSourceForGrant(grant);
|
|
9250
|
-
const inheritedPersonalConnectionDelegations = connectionDelegationSource.kind === "turn" ? await getSessionTurnPersonalConnectionDelegations2(
|
|
9251
|
-
db,
|
|
9252
|
-
workspaceId,
|
|
9253
|
-
connectionDelegationSource.sessionId,
|
|
9254
|
-
connectionDelegationSource.turnId
|
|
9255
|
-
) : null;
|
|
9256
|
-
const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(
|
|
9257
|
-
db,
|
|
9258
|
-
workspaceId,
|
|
9259
|
-
settings,
|
|
9260
|
-
inheritedPersonalConnectionDelegations ? {
|
|
9261
|
-
personalConnectionDelegations: inheritedPersonalConnectionDelegations
|
|
9262
|
-
} : { subjectId: grant.subjectId }
|
|
9263
|
-
);
|
|
9264
|
-
const personalConnectionDelegations = await freezePersonalConnectionDelegations({
|
|
9265
|
-
db,
|
|
9266
|
-
workspaceId,
|
|
9267
|
-
settings: runtimeSettings,
|
|
9268
|
-
tools: existingSession.tools,
|
|
9269
|
-
resources: [...existingSession.resources, ...requestedResources],
|
|
9270
|
-
source: connectionDelegationSource,
|
|
9271
|
-
targetSessionId: sessionId,
|
|
9272
|
-
googleDrivePublicationEnabled: existingSession.firstPartyMcpTools.includes("editable_artifact_export") && existingSession.firstPartyMcpTools.includes("editable_artifact_export_status") && (!existingSession.firstPartyMcpPermissions?.length || existingSession.firstPartyMcpPermissions.includes("artifacts:read") && existingSession.firstPartyMcpPermissions.includes("artifacts:publish")),
|
|
9273
|
-
atlassianEnabled: existingSession.firstPartyMcpTools.some((tool) => tool.startsWith("atlassian_")) && (!existingSession.firstPartyMcpPermissions?.length || existingSession.firstPartyMcpPermissions.includes("connections:read")),
|
|
9274
|
-
...input.connectionAuthorities ? { authoritySelections: input.connectionAuthorities } : {}
|
|
9275
|
-
});
|
|
9276
|
-
const { accepted, turn, draft, receipt: receipt2, routing, interruptionCount, replay } = await postUserMessageTurn({
|
|
9277
|
-
db,
|
|
9278
|
-
bus,
|
|
9279
|
-
workflowClient,
|
|
9280
|
-
settings,
|
|
9281
|
-
accountId: grant.accountId,
|
|
9282
|
-
workspaceId,
|
|
9283
|
-
sessionId,
|
|
9761
|
+
const boundaryRequestHash = input.clientEventId ? sessionPromptBoundaryRequestHash({
|
|
9762
|
+
delivery,
|
|
9763
|
+
controlEtag: input.controlEtag ?? null,
|
|
9764
|
+
expectedDraftRevision: input.expectedDraftRevision ?? null,
|
|
9284
9765
|
text: input.text,
|
|
9285
|
-
annotations,
|
|
9766
|
+
annotations: input.annotations ?? [],
|
|
9286
9767
|
modelContext: input.modelContext ?? null,
|
|
9287
9768
|
resources: requestedResources,
|
|
9288
9769
|
...composerDraftResources ? { composerDraftResources } : {},
|
|
9289
9770
|
model: input.model ?? null,
|
|
9290
9771
|
reasoningEffort: input.reasoningEffort ?? null,
|
|
9291
9772
|
latencyMode: input.latencyMode ?? null,
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
personalConnectionDelegations,
|
|
9773
|
+
source,
|
|
9774
|
+
mcpCredentialUpdates: input.mcpCredentialUpdates ?? [],
|
|
9775
|
+
...input.connectionAuthorities ? { connectionAuthorities: input.connectionAuthorities } : {},
|
|
9296
9776
|
...input.personalResourceAttachment ? { personalResourceAttachment: input.personalResourceAttachment } : {},
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9305
|
-
|
|
9306
|
-
|
|
9777
|
+
commandActor
|
|
9778
|
+
}) : null;
|
|
9779
|
+
if (input.clientEventId && boundaryRequestHash) {
|
|
9780
|
+
const replay = await withWorkspaceSubjectSessionActivityRls(
|
|
9781
|
+
db,
|
|
9782
|
+
workspaceId,
|
|
9783
|
+
grant.subjectId,
|
|
9784
|
+
async (scopedDb) => await replaySubmittedHumanPromptFromBoundaryReceipt(scopedDb, {
|
|
9785
|
+
workspaceId,
|
|
9786
|
+
sessionId,
|
|
9787
|
+
subjectId: grant.subjectId,
|
|
9788
|
+
actor: commandActor,
|
|
9789
|
+
operationKey: input.clientEventId,
|
|
9790
|
+
delivery,
|
|
9791
|
+
boundaryRequestHash,
|
|
9792
|
+
expectedDraftRevision: input.expectedDraftRevision ?? null
|
|
9793
|
+
})
|
|
9794
|
+
);
|
|
9795
|
+
if (replay) {
|
|
9796
|
+
return finalizePostUserMessageTurn(
|
|
9797
|
+
{
|
|
9798
|
+
db,
|
|
9799
|
+
bus,
|
|
9800
|
+
workflowClient,
|
|
9801
|
+
accountId: grant.accountId,
|
|
9802
|
+
workspaceId,
|
|
9803
|
+
sessionId,
|
|
9804
|
+
delivery,
|
|
9805
|
+
...deps.schedulePromptPostCommit ? { schedulePostCommit: deps.schedulePromptPostCommit } : {}
|
|
9806
|
+
},
|
|
9807
|
+
replay
|
|
9808
|
+
);
|
|
9809
|
+
}
|
|
9810
|
+
}
|
|
9811
|
+
try {
|
|
9812
|
+
await requireAtomicPersonalResourceAttachment(
|
|
9813
|
+
deps,
|
|
9814
|
+
input.authorization,
|
|
9815
|
+
workspaceId,
|
|
9816
|
+
input.personalResourceAttachment,
|
|
9817
|
+
true
|
|
9818
|
+
);
|
|
9819
|
+
const existingSession = await requireSession2(db, workspaceId, sessionId);
|
|
9820
|
+
const settings = await resolveWorkspaceModelBoundarySettings(
|
|
9821
|
+
deps,
|
|
9822
|
+
grant,
|
|
9823
|
+
workspaceId,
|
|
9824
|
+
[input.model ?? existingSession.model],
|
|
9825
|
+
existingSession.model
|
|
9826
|
+
);
|
|
9827
|
+
if (settings !== deps.settings) {
|
|
9828
|
+
deps = {
|
|
9829
|
+
...deps,
|
|
9830
|
+
catalogSourceSettings: deps.catalogSourceSettings ?? deps.settings,
|
|
9831
|
+
settings
|
|
9832
|
+
};
|
|
9833
|
+
}
|
|
9834
|
+
const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
|
|
9835
|
+
const effectiveModel = canonicalConfiguredModel(settings, requestedModel ?? existingSession.model) ?? null;
|
|
9836
|
+
if (effectiveModel === null) {
|
|
9837
|
+
throw new Error("effective follow-up model unexpectedly resolved to null");
|
|
9838
|
+
}
|
|
9839
|
+
await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, requestedModel);
|
|
9840
|
+
try {
|
|
9841
|
+
assertSessionAllowsProductModel(existingSession, effectiveModel);
|
|
9842
|
+
} catch (error) {
|
|
9843
|
+
if (error instanceof CodexCompactionV2ProviderLockedError) {
|
|
9844
|
+
throw new HTTPException11(422, { message: error.message, cause: error });
|
|
9307
9845
|
}
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
|
|
9315
|
-
|
|
9846
|
+
throw error;
|
|
9847
|
+
}
|
|
9848
|
+
const sessionReasoningEffort = existingSession.reasoningEffort;
|
|
9849
|
+
const effectiveReasoningEffort = input.reasoningEffort ?? sessionReasoningEffort;
|
|
9850
|
+
const sessionLatencyMode = existingSession.latencyMode;
|
|
9851
|
+
const effectiveLatencyMode = input.latencyMode ?? sessionLatencyMode;
|
|
9852
|
+
const turnExecutionPolicy = resolveTurnExecutionPolicyV1(settings, {
|
|
9853
|
+
modelId: effectiveModel,
|
|
9854
|
+
requestedModelId: input.model ?? null,
|
|
9855
|
+
modelSource: input.model == null ? "session" : "explicit",
|
|
9856
|
+
reasoningEffort: effectiveReasoningEffort,
|
|
9857
|
+
reasoningSource: input.reasoningEffort == null ? "session" : "explicit",
|
|
9858
|
+
latencyMode: effectiveLatencyMode,
|
|
9859
|
+
latencyModeSource: input.latencyMode == null ? "session" : "explicit"
|
|
9860
|
+
});
|
|
9861
|
+
if (composerDraftResources) {
|
|
9862
|
+
const acceptedResources = new Set(requestedResources.map((resource) => stableJson4(resource)));
|
|
9863
|
+
const unacceptedDraftResource = composerDraftResources.find(
|
|
9864
|
+
(resource) => !acceptedResources.has(stableJson4(resource))
|
|
9865
|
+
);
|
|
9866
|
+
if (unacceptedDraftResource) {
|
|
9867
|
+
throw new HTTPException11(422, {
|
|
9868
|
+
message: "composer draft resources must be included in the accepted resource set"
|
|
9869
|
+
});
|
|
9870
|
+
}
|
|
9871
|
+
}
|
|
9872
|
+
const annotations = await validateSubmittedTimelineAnnotations(
|
|
9873
|
+
db,
|
|
9874
|
+
workspaceId,
|
|
9875
|
+
sessionId,
|
|
9876
|
+
input.annotations ?? []
|
|
9877
|
+
);
|
|
9878
|
+
await requireLimit(deps, {
|
|
9879
|
+
accountId: grant.accountId,
|
|
9880
|
+
workspaceId,
|
|
9881
|
+
action: "agent_run:create",
|
|
9882
|
+
quantity: 1,
|
|
9883
|
+
model: effectiveModel
|
|
9884
|
+
});
|
|
9885
|
+
if (requestedResources.some((resource) => resource.kind === "file") && !objectStorage) {
|
|
9886
|
+
throw new HTTPException11(503, {
|
|
9887
|
+
message: "object storage is not configured"
|
|
9888
|
+
});
|
|
9889
|
+
}
|
|
9890
|
+
await validateFileResources(
|
|
9891
|
+
db,
|
|
9892
|
+
grant.accountId,
|
|
9893
|
+
workspaceId,
|
|
9894
|
+
grant.subjectId,
|
|
9895
|
+
requestedResources
|
|
9896
|
+
);
|
|
9897
|
+
await validateGitHubRepositorySelection(db, workspaceId, [
|
|
9898
|
+
...existingSession.resources,
|
|
9899
|
+
...requestedResources
|
|
9900
|
+
]);
|
|
9901
|
+
const mcpCredentialUpdates = validateSessionMcpCredentialUpdates({
|
|
9902
|
+
settings,
|
|
9903
|
+
grant,
|
|
9904
|
+
session: existingSession,
|
|
9905
|
+
updates: input.mcpCredentialUpdates ?? []
|
|
9906
|
+
});
|
|
9907
|
+
const connectionDelegationSource = personalConnectionDelegationSourceForGrant(grant);
|
|
9908
|
+
const inheritedPersonalConnectionDelegations = connectionDelegationSource.kind === "turn" ? await getSessionTurnPersonalConnectionDelegations2(
|
|
9909
|
+
db,
|
|
9910
|
+
workspaceId,
|
|
9911
|
+
connectionDelegationSource.sessionId,
|
|
9912
|
+
connectionDelegationSource.turnId
|
|
9913
|
+
) : null;
|
|
9914
|
+
const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(
|
|
9915
|
+
db,
|
|
9916
|
+
workspaceId,
|
|
9917
|
+
settings,
|
|
9918
|
+
inheritedPersonalConnectionDelegations ? {
|
|
9919
|
+
personalConnectionDelegations: inheritedPersonalConnectionDelegations
|
|
9920
|
+
} : { subjectId: grant.subjectId }
|
|
9921
|
+
);
|
|
9922
|
+
const personalConnectionDelegations = await freezePersonalConnectionDelegations({
|
|
9923
|
+
db,
|
|
9924
|
+
workspaceId,
|
|
9925
|
+
settings: runtimeSettings,
|
|
9926
|
+
tools: existingSession.tools,
|
|
9927
|
+
resources: [...existingSession.resources, ...requestedResources],
|
|
9928
|
+
source: connectionDelegationSource,
|
|
9929
|
+
targetSessionId: sessionId,
|
|
9930
|
+
googleDrivePublicationEnabled: existingSession.firstPartyMcpTools.includes("editable_artifact_export") && existingSession.firstPartyMcpTools.includes("editable_artifact_export_status") && (!existingSession.firstPartyMcpPermissions?.length || existingSession.firstPartyMcpPermissions.includes("artifacts:read") && existingSession.firstPartyMcpPermissions.includes("artifacts:publish")),
|
|
9931
|
+
atlassianEnabled: existingSession.firstPartyMcpTools.some((tool) => tool.startsWith("atlassian_")) && (!existingSession.firstPartyMcpPermissions?.length || existingSession.firstPartyMcpPermissions.includes("connections:read")),
|
|
9932
|
+
...input.connectionAuthorities ? { authoritySelections: input.connectionAuthorities } : {}
|
|
9933
|
+
});
|
|
9934
|
+
const { accepted, turn, draft, receipt: receipt2, routing, interruptionCount, replay } = await postUserMessageTurn({
|
|
9935
|
+
db,
|
|
9936
|
+
bus,
|
|
9937
|
+
workflowClient,
|
|
9938
|
+
settings,
|
|
9939
|
+
accountId: grant.accountId,
|
|
9940
|
+
workspaceId,
|
|
9941
|
+
sessionId,
|
|
9942
|
+
text: input.text,
|
|
9943
|
+
annotations,
|
|
9944
|
+
modelContext: input.modelContext ?? null,
|
|
9945
|
+
resources: requestedResources,
|
|
9946
|
+
...composerDraftResources ? { composerDraftResources } : {},
|
|
9947
|
+
model: input.model ?? null,
|
|
9948
|
+
reasoningEffort: input.reasoningEffort ?? null,
|
|
9949
|
+
latencyMode: input.latencyMode ?? null,
|
|
9950
|
+
reasoningEffortFallback: sessionReasoningEffort,
|
|
9951
|
+
turnExecutionPolicy,
|
|
9952
|
+
mcpCredentialUpdates,
|
|
9953
|
+
personalConnectionDelegations,
|
|
9954
|
+
...input.personalResourceAttachment ? { personalResourceAttachment: input.personalResourceAttachment } : {},
|
|
9955
|
+
delivery,
|
|
9956
|
+
origin: source === "api" ? "operator" : "human",
|
|
9957
|
+
actor: grant.subjectId,
|
|
9958
|
+
...grant.subjectLabel ? { actorLabel: grant.subjectLabel } : {},
|
|
9959
|
+
commandActor,
|
|
9960
|
+
...boundaryRequestHash ? { boundaryRequestHash } : {},
|
|
9961
|
+
...input.controlEtag !== void 0 ? { controlEtag: input.controlEtag } : {},
|
|
9962
|
+
...input.expectedDraftRevision !== void 0 ? { expectedDraftRevision: input.expectedDraftRevision } : {},
|
|
9963
|
+
...input.clientEventId ? { clientEventId: input.clientEventId } : {},
|
|
9964
|
+
recordAgentRunUsage: true,
|
|
9965
|
+
...deps.schedulePromptPostCommit ? { schedulePostCommit: deps.schedulePromptPostCommit } : {}
|
|
9966
|
+
});
|
|
9967
|
+
return { accepted, turn, draft, receipt: receipt2, routing, interruptionCount, replay };
|
|
9968
|
+
} catch (error) {
|
|
9969
|
+
if (input.clientEventId && boundaryRequestHash) {
|
|
9970
|
+
const replay = await withWorkspaceSubjectSessionActivityRls(
|
|
9971
|
+
db,
|
|
9972
|
+
workspaceId,
|
|
9973
|
+
grant.subjectId,
|
|
9974
|
+
async (scopedDb) => await replaySubmittedHumanPromptFromBoundaryReceipt(scopedDb, {
|
|
9975
|
+
workspaceId,
|
|
9976
|
+
sessionId,
|
|
9977
|
+
subjectId: grant.subjectId,
|
|
9978
|
+
actor: commandActor,
|
|
9979
|
+
operationKey: input.clientEventId,
|
|
9980
|
+
delivery,
|
|
9981
|
+
boundaryRequestHash,
|
|
9982
|
+
expectedDraftRevision: input.expectedDraftRevision ?? null,
|
|
9983
|
+
serializeOperation: true
|
|
9984
|
+
})
|
|
9985
|
+
);
|
|
9986
|
+
if (replay) {
|
|
9987
|
+
return finalizePostUserMessageTurn(
|
|
9988
|
+
{
|
|
9989
|
+
db,
|
|
9990
|
+
bus,
|
|
9991
|
+
workflowClient,
|
|
9992
|
+
accountId: grant.accountId,
|
|
9993
|
+
workspaceId,
|
|
9994
|
+
sessionId,
|
|
9995
|
+
delivery,
|
|
9996
|
+
...deps.schedulePromptPostCommit ? { schedulePostCommit: deps.schedulePromptPostCommit } : {}
|
|
9997
|
+
},
|
|
9998
|
+
replay
|
|
9999
|
+
);
|
|
10000
|
+
}
|
|
10001
|
+
}
|
|
10002
|
+
throw error;
|
|
10003
|
+
}
|
|
9316
10004
|
}
|
|
9317
10005
|
async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, input) {
|
|
9318
10006
|
const { accepted, turn, receipt: receipt2, routing, interruptionCount, replay } = await acceptSessionUserMessageWithOutcome(deps, grant, workspaceId, sessionId, input);
|
|
@@ -9637,6 +10325,26 @@ function scheduledTaskToolsProvided(rawPayload) {
|
|
|
9637
10325
|
agentConfig && typeof agentConfig === "object" && Object.prototype.hasOwnProperty.call(agentConfig, "tools")
|
|
9638
10326
|
);
|
|
9639
10327
|
}
|
|
10328
|
+
function workspaceCustomModelCommitGuard(input) {
|
|
10329
|
+
const reference = workspaceCustomModelReference(input.settings, input.modelId);
|
|
10330
|
+
if (!reference) return void 0;
|
|
10331
|
+
return async (tx) => {
|
|
10332
|
+
const active = reference.providerKind === "openrouter" ? await lockActiveWorkspaceOpenRouterCustomModelForAdmission2(tx, {
|
|
10333
|
+
accountId: input.accountId,
|
|
10334
|
+
workspaceId: input.workspaceId,
|
|
10335
|
+
upstreamModelId: reference.upstreamModelId
|
|
10336
|
+
}) : await lockActiveWorkspaceGatewayCustomModelForAdmission2(tx, {
|
|
10337
|
+
accountId: input.accountId,
|
|
10338
|
+
workspaceId: input.workspaceId,
|
|
10339
|
+
upstreamModelId: reference.upstreamModelId
|
|
10340
|
+
});
|
|
10341
|
+
if (!active) {
|
|
10342
|
+
throw new HTTPException12(422, {
|
|
10343
|
+
message: `model is not available: ${input.modelId}`
|
|
10344
|
+
});
|
|
10345
|
+
}
|
|
10346
|
+
};
|
|
10347
|
+
}
|
|
9640
10348
|
function scheduledConnectionSurfaceEligibility(settings, target) {
|
|
9641
10349
|
const tools = target?.firstPartyMcpTools ?? resolveFirstPartyMcpToolPolicy2(settings).default;
|
|
9642
10350
|
const permissions = target?.firstPartyMcpPermissions?.length ? target.firstPartyMcpPermissions : DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2;
|
|
@@ -9728,6 +10436,12 @@ async function createValidatedScheduledTask(input) {
|
|
|
9728
10436
|
workspaceId: input.grant.workspaceId,
|
|
9729
10437
|
subjectId: input.grant.subjectId
|
|
9730
10438
|
});
|
|
10439
|
+
const beforeCreateCommit = !knowledgeAction && input.payload.runMode !== "existing_session" ? workspaceCustomModelCommitGuard({
|
|
10440
|
+
settings: input.settings,
|
|
10441
|
+
accountId: input.grant.accountId,
|
|
10442
|
+
workspaceId: input.grant.workspaceId,
|
|
10443
|
+
modelId: agentConfig.model ?? input.settings.openaiModel
|
|
10444
|
+
}) : void 0;
|
|
9731
10445
|
return await withScheduledTaskAuthorityWriteErrors(
|
|
9732
10446
|
() => createScheduledTask(input.db, {
|
|
9733
10447
|
id,
|
|
@@ -9749,7 +10463,8 @@ async function createValidatedScheduledTask(input) {
|
|
|
9749
10463
|
targetSessionId: target?.id ?? null,
|
|
9750
10464
|
variableSetId: input.payload.variableSetId ?? null,
|
|
9751
10465
|
rigId: input.payload.rigId ?? null,
|
|
9752
|
-
metadata: input.payload.metadata
|
|
10466
|
+
metadata: input.payload.metadata,
|
|
10467
|
+
...beforeCreateCommit ? { beforeCreateCommit } : {}
|
|
9753
10468
|
})
|
|
9754
10469
|
);
|
|
9755
10470
|
}
|
|
@@ -10075,6 +10790,15 @@ async function validatedScheduledTaskUpdate(input) {
|
|
|
10075
10790
|
const nextAgentConfig = update.agentConfig ?? input.existing.agentConfig;
|
|
10076
10791
|
const authorityTargetChanged = nextRunMode !== input.existing.runMode || nextTargetSessionId !== input.existing.targetSessionId || input.payload.variableSetId !== void 0 && input.payload.variableSetId !== input.existing.variableSetId || input.payload.rigId !== void 0 && input.payload.rigId !== input.existing.rigId;
|
|
10077
10792
|
const materialExecutionChange = authorityTargetChanged || input.payload.connectionAuthorities !== void 0 || !isDeepStrictEqual(nextAgentConfig, input.existing.agentConfig) || input.payload.action !== void 0 && !isDeepStrictEqual(input.payload.action, input.existing.action) || input.payload.schedule !== void 0 && !isDeepStrictEqual(input.payload.schedule, input.existing.schedule) || input.payload.overlapPolicy !== void 0 && input.payload.overlapPolicy !== input.existing.overlapPolicy || input.payload.metadata !== void 0 && !isDeepStrictEqual(input.payload.metadata, input.existing.metadata) || input.existing.status === "paused" && input.payload.status === "active";
|
|
10793
|
+
if (materialExecutionChange && nextRunMode !== "existing_session") {
|
|
10794
|
+
const beforeUpdateCommit = workspaceCustomModelCommitGuard({
|
|
10795
|
+
settings: input.settings,
|
|
10796
|
+
accountId: input.existing.accountId,
|
|
10797
|
+
workspaceId: input.existing.workspaceId,
|
|
10798
|
+
modelId: nextAgentConfig.model ?? input.settings.openaiModel
|
|
10799
|
+
});
|
|
10800
|
+
if (beforeUpdateCommit) update.beforeUpdateCommit = beforeUpdateCommit;
|
|
10801
|
+
}
|
|
10078
10802
|
const existingXaiAuthority = await getScheduledTaskXaiProviderAccountAuthoritySnapshot(
|
|
10079
10803
|
input.db,
|
|
10080
10804
|
input.existing.workspaceId,
|
|
@@ -14575,6 +15299,7 @@ export {
|
|
|
14575
15299
|
MEMORY_SLACK_PROJECTION_MAX_UTF8_BYTES,
|
|
14576
15300
|
MEMORY_SLACK_PROJECTION_VERSION,
|
|
14577
15301
|
MEMORY_SLACK_SUMMARY_MAX_UTF8_BYTES,
|
|
15302
|
+
MODEL_CREDENTIAL_READINESS_OBSERVATION_MAX_AGE_MS,
|
|
14578
15303
|
ManagedAuthActorLeaseOutcomeUnknownError,
|
|
14579
15304
|
MathEditableArtifactOutboxRandom,
|
|
14580
15305
|
OPENGENI_PR_REVIEW_AGENT_INSTRUCTIONS,
|
|
@@ -14777,6 +15502,9 @@ export {
|
|
|
14777
15502
|
isTerminalVideoGenerationState,
|
|
14778
15503
|
isTrustedScheduledSlackBotSession,
|
|
14779
15504
|
isUserMember,
|
|
15505
|
+
isWorkspaceCustomModelId,
|
|
15506
|
+
isWorkspaceGatewayCustomModelId,
|
|
15507
|
+
isWorkspaceOpenRouterCustomModelId,
|
|
14780
15508
|
issueManagedHumanUserResourceGrant,
|
|
14781
15509
|
legacySandboxRuntimeFromPacks,
|
|
14782
15510
|
listCapabilityPacks,
|
|
@@ -14797,6 +15525,7 @@ export {
|
|
|
14797
15525
|
mergeResourceRefs,
|
|
14798
15526
|
mergeRigDefaultVariableSetEnvironment,
|
|
14799
15527
|
mergeToolRefs,
|
|
15528
|
+
modelFundingForAdmission,
|
|
14800
15529
|
moveHumanQueuePrompt,
|
|
14801
15530
|
nativeConnectionCapabilityRecommendations,
|
|
14802
15531
|
normalizeConversationActor,
|
|
@@ -14879,6 +15608,7 @@ export {
|
|
|
14879
15608
|
requireVariableSetEncryption,
|
|
14880
15609
|
requireVariableSetForApi,
|
|
14881
15610
|
resolveCapabilityPack,
|
|
15611
|
+
resolveCatalogSettings,
|
|
14882
15612
|
resolveChildGoalFromAcceptedSnapshot,
|
|
14883
15613
|
resolveCodexAppsCredentialIdForRun,
|
|
14884
15614
|
resolveFikenDefaultCompanySlug,
|
|
@@ -14891,7 +15621,9 @@ export {
|
|
|
14891
15621
|
resolveSessionSandboxRuntime,
|
|
14892
15622
|
resolveSessionToolPolicy,
|
|
14893
15623
|
resolveSkillImport,
|
|
15624
|
+
resolveWorkspaceCatalogSettings,
|
|
14894
15625
|
resolveWorkspaceLegacyRuntimePacks,
|
|
15626
|
+
resolveWorkspaceModelSelection,
|
|
14895
15627
|
restoreScheduledTask,
|
|
14896
15628
|
retainedProcessBackgroundSettlement,
|
|
14897
15629
|
revokeManagedHumanUserResourceGrant,
|
|
@@ -14978,6 +15710,7 @@ export {
|
|
|
14978
15710
|
withScheduledTaskAuthorityWriteErrors,
|
|
14979
15711
|
withWorkspaceDefaultMcpTools,
|
|
14980
15712
|
workflowIdForSession,
|
|
15713
|
+
workspaceCustomModelReference,
|
|
14981
15714
|
workspaceSessionToolPolicyDefaultServerIds,
|
|
14982
15715
|
workspaceSessionToolPolicyServerIds,
|
|
14983
15716
|
wrapChannelABoxWithRouting
|