@opengeni/worker-bundle 2.2.0 → 2.2.1-canary.36927100590001
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/activities/agent-run-admission.d.ts +3 -1
- package/dist/activities/agent-turn/admission.d.ts +24 -3
- package/dist/activities/agent-turn/agent-build.d.ts +1 -0
- package/dist/activities/agent-turn/claude-usage-observer.d.ts +13 -1
- package/dist/activities/agent-turn/compaction-prep.d.ts +20 -0
- package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
- package/dist/activities/agent-turn/final-reply.d.ts +18 -0
- package/dist/activities/agent-turn/governance-model.d.ts +6 -0
- package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
- package/dist/activities/agent-turn/run-credentials.d.ts +4 -0
- package/dist/activities/agent-turn/sandbox-establish.d.ts +1 -0
- package/dist/activities/agent-turn/session-title.d.ts +3 -1
- package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
- package/dist/activities/agent-turn/turn-context.d.ts +1 -0
- package/dist/activities/automations.d.ts +3 -1
- package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
- package/dist/activities/goals.d.ts +8 -0
- package/dist/activities/run-credentials.d.ts +4 -2
- package/dist/activities/scheduled-tasks.d.ts +4 -35
- package/dist/activities/types.d.ts +4 -1
- package/dist/activities/workspace-capture.d.ts +2 -0
- package/dist/{activities-control-MHNA3CYV.js → activities-control-4F2A734B.js} +502 -133
- package/dist/activities-control-4F2A734B.js.map +1 -0
- package/dist/activities-control.d.ts +30 -0
- package/dist/{activities-turn-FQ5OO2WW.js → activities-turn-TESOIOEX.js} +696 -251
- package/dist/activities-turn-TESOIOEX.js.map +1 -0
- package/dist/activities.d.ts +30 -0
- package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
- package/dist/{chunk-RZAAGRFQ.js → chunk-4PJTUBWQ.js} +220 -88
- package/dist/chunk-4PJTUBWQ.js.map +1 -0
- package/dist/{chunk-IJZU752L.js → chunk-YG27NEMX.js} +34 -1
- package/dist/chunk-YG27NEMX.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +46 -24
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +16 -1
- package/dist/sandbox-resume.d.ts +4 -1
- package/dist/workflow-bundle.js +89 -21
- package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
- package/dist/workflows/scheduled-tasks.d.ts +4 -0
- package/dist/workflows.d.ts +1 -0
- package/package.json +21 -20
- package/src/activities/agent-run-admission.ts +17 -1
- package/src/activities/agent-turn/admission.ts +64 -1
- package/src/activities/agent-turn/agent-build.ts +24 -3
- package/src/activities/agent-turn/claim.ts +69 -15
- package/src/activities/agent-turn/claude-usage-observer.ts +33 -1
- package/src/activities/agent-turn/compaction-prep.ts +67 -16
- package/src/activities/agent-turn/credential-restriction.ts +14 -0
- package/src/activities/agent-turn/errors.ts +55 -0
- package/src/activities/agent-turn/failure-settlement.ts +26 -6
- package/src/activities/agent-turn/final-reply.ts +46 -0
- package/src/activities/agent-turn/governance-model.ts +12 -0
- package/src/activities/agent-turn/model-call-admission.ts +94 -0
- package/src/activities/agent-turn/run-credentials.ts +20 -3
- package/src/activities/agent-turn/run.ts +44 -5
- package/src/activities/agent-turn/sandbox-establish.ts +9 -5
- package/src/activities/agent-turn/session-title.ts +8 -2
- package/src/activities/agent-turn/stream-attempt.ts +144 -38
- package/src/activities/agent-turn/tool-environment.ts +55 -39
- package/src/activities/agent-turn/turn-context.ts +1 -0
- package/src/activities/automations.ts +78 -4
- package/src/activities/browser-deadline-checkpoint.ts +279 -0
- package/src/activities/capabilities.ts +52 -14
- package/src/activities/goals.ts +95 -98
- package/src/activities/knowledge-indexing.ts +29 -0
- package/src/activities/open-suffix-resume.ts +2 -1
- package/src/activities/run-credentials.ts +22 -16
- package/src/activities/sandbox-lease.ts +22 -0
- package/src/activities/scheduled-tasks.ts +172 -38
- package/src/activities/site-auth-maintenance.ts +1 -0
- package/src/activities/types.ts +4 -0
- package/src/activities/workspace-capture.ts +13 -2
- package/src/activities/workspace-credential-provider.ts +12 -0
- package/src/activities-control.ts +2 -0
- package/src/activities.ts +3 -0
- package/src/browser-deadline-checkpoint-contract.ts +5 -0
- package/src/index.ts +53 -25
- package/src/observability-metrics.ts +55 -1
- package/src/sandbox-resume.ts +23 -8
- package/src/sandbox-routing.ts +4 -2
- package/src/workflows/browser-deadline-checkpoint.ts +50 -0
- package/src/workflows/scheduled-tasks.ts +26 -13
- package/src/workflows.ts +4 -0
- package/dist/activities-control-MHNA3CYV.js.map +0 -1
- package/dist/activities-turn-FQ5OO2WW.js.map +0 -1
- package/dist/chunk-IJZU752L.js.map +0 -1
- package/dist/chunk-RZAAGRFQ.js.map +0 -1
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
INCIDENT_TELEMETRY_AUTHORITY_FENCE_LINEAGE_KEY,
|
|
10
10
|
MAX_AUTOMATIC_PROVIDER_RECOVERIES,
|
|
11
|
+
agentRunAdmissionDenial,
|
|
11
12
|
assertReusableSessionRevivable,
|
|
12
13
|
captureConnectedCommandOutput,
|
|
13
14
|
createCodexCapacityActivities,
|
|
@@ -33,10 +34,12 @@ import {
|
|
|
33
34
|
warnDrainSnapshotFailure,
|
|
34
35
|
withFirstPartyTools,
|
|
35
36
|
workflowIdForSession
|
|
36
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-4PJTUBWQ.js";
|
|
37
38
|
import {
|
|
38
39
|
inspectOpenSandboxKubernetesInventory,
|
|
40
|
+
recordActiveUserGauges,
|
|
39
41
|
recordCreditBalanceGauges,
|
|
42
|
+
recordCreditGrantGauges,
|
|
40
43
|
recordCreditMicros,
|
|
41
44
|
recordExpiredDrainingSandboxLeaseGauges,
|
|
42
45
|
recordOpenSandboxKubernetesInventoryGauges,
|
|
@@ -57,7 +60,7 @@ import {
|
|
|
57
60
|
recordVerifiedSignupTrialSwitchGauge,
|
|
58
61
|
recordWorkerDeathRecoveryMetrics,
|
|
59
62
|
runtimeMetricsHooksForObservability
|
|
60
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-YG27NEMX.js";
|
|
61
64
|
import "./chunk-PZ5AY32C.js";
|
|
62
65
|
|
|
63
66
|
// src/activities/knowledge-indexing.ts
|
|
@@ -67,8 +70,10 @@ import {
|
|
|
67
70
|
applyCreditDebitAfterUse,
|
|
68
71
|
appendKnowledgeIndexChunks,
|
|
69
72
|
claimKnowledgeIndexJobs,
|
|
73
|
+
checkWorkspaceAllowance,
|
|
70
74
|
completeKnowledgeIndexJob,
|
|
71
75
|
continueKnowledgeIndexJob,
|
|
76
|
+
creditDebitAttributionMetadata,
|
|
72
77
|
deferKnowledgeIndexJob,
|
|
73
78
|
freezeKnowledgeIndexBillingMode,
|
|
74
79
|
getBillingBalance,
|
|
@@ -213,6 +218,14 @@ function createKnowledgeIndexingActivities(services, resolveDocumentServices) {
|
|
|
213
218
|
return;
|
|
214
219
|
}
|
|
215
220
|
const paid = frozenPolicy.mode === "credits";
|
|
221
|
+
if (paid && claim.billingAttribution.kind === "unknown") {
|
|
222
|
+
observability.warn("Paid Knowledge indexing awaits initiating attribution", {
|
|
223
|
+
errorCode: "knowledge_index_attribution_unavailable"
|
|
224
|
+
});
|
|
225
|
+
await deferKnowledgeIndexJob(lockedDb, claim);
|
|
226
|
+
result.deferred++;
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
216
229
|
if (paid && current.nextIndex === 0) {
|
|
217
230
|
const balance = await getBillingBalance(lockedDb, claim.accountId);
|
|
218
231
|
if (balance.balanceMicros <= 0) {
|
|
@@ -221,6 +234,18 @@ function createKnowledgeIndexingActivities(services, resolveDocumentServices) {
|
|
|
221
234
|
return;
|
|
222
235
|
}
|
|
223
236
|
}
|
|
237
|
+
if (paid) {
|
|
238
|
+
const refusal = await checkWorkspaceAllowance(lockedDb, {
|
|
239
|
+
accountId: claim.accountId,
|
|
240
|
+
workspaceId: current.billingWorkspaceId,
|
|
241
|
+
subjectId: claim.billingAttribution.kind === "turn" || claim.billingAttribution.kind === "human" ? claim.billingAttribution.initiatingHumanSubjectId : null
|
|
242
|
+
});
|
|
243
|
+
if (refusal) {
|
|
244
|
+
await deferKnowledgeIndexJob(lockedDb, claim);
|
|
245
|
+
result.deferred++;
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
224
249
|
if (settings.usageLimitsMode === "static" || settings.usageLimitsMode === "managed") {
|
|
225
250
|
const limit = configuredStaticUsageLimits(settings).maxDocumentIndexedChunksPerWorkspace;
|
|
226
251
|
if (limit) {
|
|
@@ -319,6 +344,7 @@ function createKnowledgeIndexingActivities(services, resolveDocumentServices) {
|
|
|
319
344
|
sourceId: claim.revisionId,
|
|
320
345
|
idempotencyKey: `knowledge.embedding:${claim.revisionId}:${claim.generation}:${current.nextIndex}`,
|
|
321
346
|
metadata: {
|
|
347
|
+
...creditDebitAttributionMetadata(claim.billingAttribution),
|
|
322
348
|
model: claim.model,
|
|
323
349
|
bytes,
|
|
324
350
|
chunks: chunks.length,
|
|
@@ -444,6 +470,240 @@ function cleanupErrorCategory(error) {
|
|
|
444
470
|
return typeof code === "string" && SAFE_PROVIDER_ERROR_CODES.has(code) ? code : "unknown";
|
|
445
471
|
}
|
|
446
472
|
|
|
473
|
+
// src/activities/browser-deadline-checkpoint.ts
|
|
474
|
+
import { Context } from "@temporalio/activity";
|
|
475
|
+
import {
|
|
476
|
+
environmentsEncryptionKeyBytes,
|
|
477
|
+
resolveFirstPartyDelegationSecret
|
|
478
|
+
} from "@opengeni/config";
|
|
479
|
+
import { BROWSER_STATE_ARTIFACT_CONTENT_TYPE } from "@opengeni/contracts";
|
|
480
|
+
import {
|
|
481
|
+
browserDeadlineCheckpoint,
|
|
482
|
+
clearSuspendedBrowserSessionController,
|
|
483
|
+
commitBrowserSessionSuspension,
|
|
484
|
+
dispatchBrowserSessionOperation,
|
|
485
|
+
failBrowserSessionSuspension,
|
|
486
|
+
listBrowserDeadlineCheckpoints,
|
|
487
|
+
readLease,
|
|
488
|
+
releaseLeaseHolder,
|
|
489
|
+
withRlsContext
|
|
490
|
+
} from "@opengeni/db";
|
|
491
|
+
import { deriveBrowserControllerAdminToken } from "@opengeni/interaction/browser-controller-authority";
|
|
492
|
+
import {
|
|
493
|
+
browserStateArtifactAad,
|
|
494
|
+
browserStateManifestDigest,
|
|
495
|
+
browserStateObjectKey,
|
|
496
|
+
deriveBrowserStateDataKey,
|
|
497
|
+
wrapBrowserStateDataKey
|
|
498
|
+
} from "@opengeni/interaction/browser-state-authority";
|
|
499
|
+
import {
|
|
500
|
+
BrowserControlClient,
|
|
501
|
+
BrowserControlRequestError,
|
|
502
|
+
createSandboxClientForBackend,
|
|
503
|
+
deserializeSandboxSessionStateEnvelope,
|
|
504
|
+
resumeExactSandboxSession
|
|
505
|
+
} from "@opengeni/runtime";
|
|
506
|
+
var UPLOAD_CLEANUP_GRACE_MS = 24 * 60 * 6e4;
|
|
507
|
+
function heartbeat() {
|
|
508
|
+
try {
|
|
509
|
+
Context.current().heartbeat();
|
|
510
|
+
} catch {
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
async function withActivityHeartbeat(run) {
|
|
514
|
+
heartbeat();
|
|
515
|
+
const timer = setInterval(heartbeat, 5e3);
|
|
516
|
+
try {
|
|
517
|
+
return await run();
|
|
518
|
+
} finally {
|
|
519
|
+
clearInterval(timer);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
async function resumeCheckpointController({
|
|
523
|
+
target,
|
|
524
|
+
lease,
|
|
525
|
+
settings,
|
|
526
|
+
controllerRoot
|
|
527
|
+
}) {
|
|
528
|
+
const provider = createSandboxClientForBackend("modal", settings);
|
|
529
|
+
const envelope = lease.resumeState;
|
|
530
|
+
const state = await deserializeSandboxSessionStateEnvelope(
|
|
531
|
+
provider,
|
|
532
|
+
envelope.sessionState ?? lease.resumeState,
|
|
533
|
+
target.instanceId
|
|
534
|
+
);
|
|
535
|
+
const resumed = await resumeExactSandboxSession(provider, "modal", state, target.instanceId);
|
|
536
|
+
return new BrowserControlClient(resumed.session, {
|
|
537
|
+
adminToken: deriveBrowserControllerAdminToken({
|
|
538
|
+
rootSecret: controllerRoot,
|
|
539
|
+
accountId: target.accountId,
|
|
540
|
+
workspaceId: target.workspaceId,
|
|
541
|
+
placement: { kind: "sandbox_group", sandboxGroupId: target.sandboxGroupId },
|
|
542
|
+
placementInstanceId: target.instanceId
|
|
543
|
+
})
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
function createBrowserDeadlineCheckpointActivities(services, connectController = resumeCheckpointController) {
|
|
547
|
+
return {
|
|
548
|
+
async listDueBrowserCheckpoints() {
|
|
549
|
+
return await withActivityHeartbeat(async () => {
|
|
550
|
+
const { db, settings, objectStorage } = await services();
|
|
551
|
+
if (!settings.sandboxOwnershipEnabled || !objectStorage || !resolveFirstPartyDelegationSecret(settings))
|
|
552
|
+
return [];
|
|
553
|
+
const root = environmentsEncryptionKeyBytes(settings);
|
|
554
|
+
if (!root) return [];
|
|
555
|
+
root.fill(0);
|
|
556
|
+
return await listBrowserDeadlineCheckpoints(db);
|
|
557
|
+
});
|
|
558
|
+
},
|
|
559
|
+
async checkpointBrowserBeforeDeadline(target) {
|
|
560
|
+
return await withActivityHeartbeat(async () => {
|
|
561
|
+
const { db, settings, objectStorage } = await services();
|
|
562
|
+
const rootKey = environmentsEncryptionKeyBytes(settings);
|
|
563
|
+
const controllerRoot = resolveFirstPartyDelegationSecret(settings);
|
|
564
|
+
if (!rootKey || !objectStorage || !controllerRoot) {
|
|
565
|
+
rootKey?.fill(0);
|
|
566
|
+
throw new Error("browser deadline checkpoint storage or encryption is unavailable");
|
|
567
|
+
}
|
|
568
|
+
let dataKey = null;
|
|
569
|
+
let aad = null;
|
|
570
|
+
let timer = null;
|
|
571
|
+
try {
|
|
572
|
+
const claim = await browserDeadlineCheckpoint(db, target, { prepare: true, touch: true });
|
|
573
|
+
if (!claim) return { status: "skipped" };
|
|
574
|
+
let pulseRunning = false;
|
|
575
|
+
let authorityLost = false;
|
|
576
|
+
const pulse = async () => {
|
|
577
|
+
if (pulseRunning) return;
|
|
578
|
+
pulseRunning = true;
|
|
579
|
+
try {
|
|
580
|
+
if (!await browserDeadlineCheckpoint(db, target, { touch: true }))
|
|
581
|
+
authorityLost = true;
|
|
582
|
+
} finally {
|
|
583
|
+
pulseRunning = false;
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
timer = setInterval(() => {
|
|
587
|
+
void pulse().catch(() => void 0);
|
|
588
|
+
}, 5e3);
|
|
589
|
+
const lease = await readLease(db, target.workspaceId, target.sandboxGroupId);
|
|
590
|
+
if (!lease || lease.instanceId !== target.instanceId || lease.leaseEpoch !== target.leaseEpoch || !lease.resumeState) {
|
|
591
|
+
throw new Error("browser deadline checkpoint placement changed");
|
|
592
|
+
}
|
|
593
|
+
const placement = {
|
|
594
|
+
kind: "sandbox_group",
|
|
595
|
+
sandboxGroupId: target.sandboxGroupId
|
|
596
|
+
};
|
|
597
|
+
const client = await connectController({ target, lease, settings, controllerRoot });
|
|
598
|
+
if (authorityLost || !await browserDeadlineCheckpoint(db, target, { touch: true })) {
|
|
599
|
+
throw new Error("browser deadline checkpoint authority changed");
|
|
600
|
+
}
|
|
601
|
+
if (claim.state !== "completed") {
|
|
602
|
+
const scope = { ...target, operationId: claim.operationId };
|
|
603
|
+
const objectKey = browserStateObjectKey(target.workspaceId, claim.operationId);
|
|
604
|
+
dataKey = deriveBrowserStateDataKey(rootKey, { ...scope, objectKey });
|
|
605
|
+
aad = browserStateArtifactAad({ ...scope, objectKey });
|
|
606
|
+
await dispatchBrowserSessionOperation(db, {
|
|
607
|
+
...scope,
|
|
608
|
+
deadlineTarget: target,
|
|
609
|
+
stateUpload: {
|
|
610
|
+
objectKey,
|
|
611
|
+
cleanupAfter: new Date(Date.now() + UPLOAD_CLEANUP_GRACE_MS)
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
const signed = await objectStorage.createPutUrl({
|
|
615
|
+
key: objectKey,
|
|
616
|
+
contentType: BROWSER_STATE_ARTIFACT_CONTENT_TYPE,
|
|
617
|
+
audience: "sandbox"
|
|
618
|
+
});
|
|
619
|
+
const receipt = await client.captureState({
|
|
620
|
+
...scope,
|
|
621
|
+
objectKey,
|
|
622
|
+
afterCapture: "stop",
|
|
623
|
+
dataKey,
|
|
624
|
+
aad,
|
|
625
|
+
upload: {
|
|
626
|
+
url: signed.url,
|
|
627
|
+
requiredHeaders: signed.requiredHeaders,
|
|
628
|
+
expiresAt: signed.expiresAt.toISOString()
|
|
629
|
+
}
|
|
630
|
+
}).catch(async (error) => {
|
|
631
|
+
if (error instanceof BrowserControlRequestError && (error.error.code === "outcome_unknown" || !error.error.retryable)) {
|
|
632
|
+
await failBrowserSessionSuspension(db, { ...scope, error: error.error });
|
|
633
|
+
}
|
|
634
|
+
throw error;
|
|
635
|
+
});
|
|
636
|
+
if (authorityLost) throw new Error("browser deadline checkpoint authority changed");
|
|
637
|
+
const portable = receipt.manifest.profileCrypto !== "platform_bound";
|
|
638
|
+
await commitBrowserSessionSuspension(db, {
|
|
639
|
+
...scope,
|
|
640
|
+
deadlineTarget: target,
|
|
641
|
+
artifact: {
|
|
642
|
+
kind: "chromium_profile",
|
|
643
|
+
format: receipt.format,
|
|
644
|
+
objectKey,
|
|
645
|
+
artifactDigest: receipt.artifactDigest,
|
|
646
|
+
contentDigest: receipt.contentDigest,
|
|
647
|
+
manifestDigest: browserStateManifestDigest(receipt.manifest),
|
|
648
|
+
sizeBytes: receipt.sizeBytes,
|
|
649
|
+
encryptedDataKey: wrapBrowserStateDataKey(rootKey, dataKey, {
|
|
650
|
+
...scope,
|
|
651
|
+
objectKey,
|
|
652
|
+
artifactDigest: receipt.artifactDigest,
|
|
653
|
+
contentDigest: receipt.contentDigest
|
|
654
|
+
}),
|
|
655
|
+
materialization: {
|
|
656
|
+
portability: portable ? "portable" : "placement_bound",
|
|
657
|
+
reason: portable ? null : "Profile encryption depends on the source operating-system credential store.",
|
|
658
|
+
platform: receipt.manifest.platform,
|
|
659
|
+
architecture: receipt.manifest.architecture,
|
|
660
|
+
engine: receipt.manifest.engine,
|
|
661
|
+
engineVersion: receipt.manifest.engineVersion,
|
|
662
|
+
driverId: receipt.manifest.driverId,
|
|
663
|
+
driverSchemaVersion: receipt.manifest.driverSchemaVersion,
|
|
664
|
+
profileCrypto: receipt.manifest.profileCrypto,
|
|
665
|
+
providerId: null,
|
|
666
|
+
placement: portable ? null : placement
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
await client.endSession(target, { removeState: true }).catch((error) => {
|
|
672
|
+
if (!(error instanceof BrowserControlRequestError && error.status === 404)) throw error;
|
|
673
|
+
});
|
|
674
|
+
await withRlsContext(
|
|
675
|
+
db,
|
|
676
|
+
target,
|
|
677
|
+
async (tx) => {
|
|
678
|
+
if ((await browserDeadlineCheckpoint(tx, target))?.state !== "completed") {
|
|
679
|
+
throw new Error("browser deadline checkpoint cleanup authority changed");
|
|
680
|
+
}
|
|
681
|
+
await clearSuspendedBrowserSessionController(tx, {
|
|
682
|
+
...target,
|
|
683
|
+
expectedControllerGeneration: target.controllerGeneration
|
|
684
|
+
});
|
|
685
|
+
await releaseLeaseHolder(tx, {
|
|
686
|
+
...target,
|
|
687
|
+
kind: "interaction",
|
|
688
|
+
holderId: `browser-session:${target.browserSessionId}`,
|
|
689
|
+
idleGraceMs: settings.sandboxIdleGraceMs
|
|
690
|
+
});
|
|
691
|
+
},
|
|
692
|
+
void 0,
|
|
693
|
+
"none"
|
|
694
|
+
);
|
|
695
|
+
return { status: "suspended" };
|
|
696
|
+
} finally {
|
|
697
|
+
if (timer) clearInterval(timer);
|
|
698
|
+
dataKey?.fill(0);
|
|
699
|
+
aad?.fill(0);
|
|
700
|
+
rootKey.fill(0);
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
|
|
447
707
|
// src/activities/automations.ts
|
|
448
708
|
import {
|
|
449
709
|
resolveTurnExecutionPolicyV1,
|
|
@@ -451,88 +711,31 @@ import {
|
|
|
451
711
|
WORKSPACE_OPENROUTER_MODEL_ID_PREFIX
|
|
452
712
|
} from "@opengeni/config";
|
|
453
713
|
import {
|
|
714
|
+
agentConfigMayResolve,
|
|
715
|
+
applySessionAgentConfigWriteThrough,
|
|
454
716
|
assertWorkspaceModelPolicyAllows,
|
|
455
717
|
canonicalConfiguredModel,
|
|
718
|
+
resolveSessionAgentConfigForCreate,
|
|
456
719
|
createAndStartSessionWithOutcome,
|
|
457
720
|
recordWorkspaceUsage,
|
|
458
721
|
resolveCatalogSettings,
|
|
459
|
-
resolveWorkspaceCatalogSettings
|
|
722
|
+
resolveWorkspaceCatalogSettings,
|
|
723
|
+
isDeveloperSetupDelegatedPermissionAllowed
|
|
460
724
|
} from "@opengeni/core";
|
|
461
725
|
import {
|
|
462
726
|
AutomationAuthorityRevokedError,
|
|
463
727
|
assertAutomationRunAuthorityInTransaction,
|
|
464
728
|
claimAutomationRun,
|
|
465
|
-
settleAutomationRun
|
|
729
|
+
settleAutomationRun,
|
|
730
|
+
requireWorkspace
|
|
466
731
|
} from "@opengeni/db";
|
|
467
732
|
import { SessionSkills } from "@opengeni/contracts";
|
|
468
|
-
|
|
469
|
-
// src/activities/agent-run-admission.ts
|
|
470
|
-
import { configuredStaticUsageLimits as configuredStaticUsageLimits2 } from "@opengeni/config";
|
|
471
|
-
import { modelFundingForAdmission } from "@opengeni/core";
|
|
472
|
-
import { getBillingBalance as getBillingBalance2, isCodexBilledTurn, sumUsageQuantity as sumUsageQuantity2 } from "@opengeni/db";
|
|
473
|
-
async function agentRunAdmissionDenial(services, input) {
|
|
474
|
-
const codexBilled = await isCodexBilledTurn({
|
|
475
|
-
db: services.db,
|
|
476
|
-
settings: services.settings,
|
|
477
|
-
workspaceId: input.workspaceId,
|
|
478
|
-
model: input.model
|
|
479
|
-
});
|
|
480
|
-
const externallyBilled = modelFundingForAdmission(
|
|
481
|
-
services.settings,
|
|
482
|
-
input.model,
|
|
483
|
-
codexBilled
|
|
484
|
-
).fundedWithoutCredits;
|
|
485
|
-
if (!externallyBilled && (services.settings.billingMode === "stripe" || services.settings.usageLimitsMode === "managed")) {
|
|
486
|
-
if (services.entitlements) {
|
|
487
|
-
const decision = await services.entitlements.admitRun({
|
|
488
|
-
accountId: input.accountId,
|
|
489
|
-
workspaceId: input.workspaceId,
|
|
490
|
-
action: "agent_run:create",
|
|
491
|
-
quantity: input.requestedAgentRuns
|
|
492
|
-
});
|
|
493
|
-
if (!decision.allowed) return "insufficient_credits";
|
|
494
|
-
} else {
|
|
495
|
-
const balance = await getBillingBalance2(services.db, input.accountId);
|
|
496
|
-
if (balance.balanceMicros <= 0) return "insufficient_credits";
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
if (services.settings.usageLimitsMode !== "static" && services.settings.usageLimitsMode !== "managed") {
|
|
500
|
-
return null;
|
|
501
|
-
}
|
|
502
|
-
const limits = configuredStaticUsageLimits2(services.settings);
|
|
503
|
-
if (!externallyBilled && limits.maxMonthlyCostMicrosPerAccount) {
|
|
504
|
-
const used = await sumUsageQuantity2(services.db, {
|
|
505
|
-
accountId: input.accountId,
|
|
506
|
-
eventType: "model.cost",
|
|
507
|
-
since: startOfUtcMonth()
|
|
508
|
-
});
|
|
509
|
-
if (used >= limits.maxMonthlyCostMicrosPerAccount) {
|
|
510
|
-
return "monthly_model_cost_limit";
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
if (limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
514
|
-
const used = await sumUsageQuantity2(services.db, {
|
|
515
|
-
workspaceId: input.workspaceId,
|
|
516
|
-
eventType: "agent_run.created",
|
|
517
|
-
since: startOfUtcMonth()
|
|
518
|
-
});
|
|
519
|
-
if (used + input.requestedAgentRuns > limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
520
|
-
return "monthly_agent_run_limit";
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
return null;
|
|
524
|
-
}
|
|
525
|
-
function startOfUtcMonth() {
|
|
526
|
-
const now = /* @__PURE__ */ new Date();
|
|
527
|
-
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// src/activities/automations.ts
|
|
531
733
|
function createAutomationActivities(services, options = {}) {
|
|
532
734
|
const claim = options.claim ?? claimAutomationRun;
|
|
533
735
|
const settle = options.settle ?? settleAutomationRun;
|
|
534
736
|
const assertAuthority = options.assertAuthority ?? assertAutomationRunAuthorityInTransaction;
|
|
535
737
|
const createSession2 = options.createSession ?? createAndStartSessionWithOutcome;
|
|
738
|
+
const readWorkspace = options.readWorkspace ?? requireWorkspace;
|
|
536
739
|
const admit = options.admit ?? agentRunAdmissionDenial;
|
|
537
740
|
const assertModelPolicy = options.assertModelPolicy ?? assertWorkspaceModelPolicyAllows;
|
|
538
741
|
const recordUsage = options.recordUsage ?? recordWorkspaceUsage;
|
|
@@ -577,6 +780,17 @@ function createAutomationActivities(services, options = {}) {
|
|
|
577
780
|
return { action: "skipped", reason: "accepted_execution_mismatch" };
|
|
578
781
|
}
|
|
579
782
|
const template = accepted.sessionTemplate;
|
|
783
|
+
if (template.credentialRestriction === "developer_setup" && template.firstPartyMcpPermissions.some(
|
|
784
|
+
(permission) => !isDeveloperSetupDelegatedPermissionAllowed(permission)
|
|
785
|
+
)) {
|
|
786
|
+
await settle(service.db, {
|
|
787
|
+
workspaceId: input.workspaceId,
|
|
788
|
+
runId: run.id,
|
|
789
|
+
status: "failed",
|
|
790
|
+
errorCode: "credential_restriction_violation"
|
|
791
|
+
});
|
|
792
|
+
return { action: "failed", reason: "credential_restriction_violation" };
|
|
793
|
+
}
|
|
580
794
|
const requestedModel = template.model ?? deploymentCatalogSettings.openaiModel;
|
|
581
795
|
const catalogSettings = requestedModel.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX) || requestedModel.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX) ? (await resolveWorkspaceCatalogSettings(service.db, catalogSourceSettings, {
|
|
582
796
|
accountId: input.accountId,
|
|
@@ -629,7 +843,42 @@ function createAutomationActivities(services, options = {}) {
|
|
|
629
843
|
reason: "interactive_compute_not_allowed"
|
|
630
844
|
};
|
|
631
845
|
}
|
|
632
|
-
|
|
846
|
+
let agentWriteThrough;
|
|
847
|
+
try {
|
|
848
|
+
const workspaceSettings = agentConfigMayResolve(catalogSettings, template.agent) ? (await readWorkspace(service.db, input.workspaceId)).settings : {};
|
|
849
|
+
const resolution = resolveSessionAgentConfigForCreate({
|
|
850
|
+
settings: catalogSettings,
|
|
851
|
+
creator: "automation",
|
|
852
|
+
request: template.agent,
|
|
853
|
+
instructions: template.instructions ?? void 0,
|
|
854
|
+
workspaceSettings,
|
|
855
|
+
parent: null,
|
|
856
|
+
goal: false
|
|
857
|
+
});
|
|
858
|
+
const written = applySessionAgentConfigWriteThrough({
|
|
859
|
+
config: resolution.config,
|
|
860
|
+
firstPartyMcpTools: template.firstPartyMcpTools,
|
|
861
|
+
tools: template.tools,
|
|
862
|
+
toolPolicy: { mode: "explicit", inheritedFromSessionId: null },
|
|
863
|
+
productServerIds: template.tools.map((tool) => tool.id)
|
|
864
|
+
});
|
|
865
|
+
agentWriteThrough = {
|
|
866
|
+
config: resolution.config,
|
|
867
|
+
instructions: resolution.instructions,
|
|
868
|
+
firstPartyMcpTools: written.firstPartyMcpTools,
|
|
869
|
+
tools: written.tools
|
|
870
|
+
};
|
|
871
|
+
} catch (error) {
|
|
872
|
+
if (!isUnprocessableEntity(error)) throw error;
|
|
873
|
+
await settle(service.db, {
|
|
874
|
+
workspaceId: input.workspaceId,
|
|
875
|
+
runId: run.id,
|
|
876
|
+
status: "failed",
|
|
877
|
+
errorCode: "dispatch_failed"
|
|
878
|
+
});
|
|
879
|
+
return { action: "failed", reason: "dispatch_failed" };
|
|
880
|
+
}
|
|
881
|
+
const resolvedTurnExecutionPolicy = resolveTurnExecutionPolicyV1(catalogSettings, {
|
|
633
882
|
modelId: model,
|
|
634
883
|
requestedModelId: template.model,
|
|
635
884
|
modelSource: template.model ? "explicit" : "deployment",
|
|
@@ -638,6 +887,10 @@ function createAutomationActivities(services, options = {}) {
|
|
|
638
887
|
latencyMode: "standard",
|
|
639
888
|
latencyModeSource: "deployment"
|
|
640
889
|
});
|
|
890
|
+
const turnExecutionPolicy = template.credentialRestriction ? {
|
|
891
|
+
...resolvedTurnExecutionPolicy,
|
|
892
|
+
credentialRestriction: template.credentialRestriction
|
|
893
|
+
} : resolvedTurnExecutionPolicy;
|
|
641
894
|
const created = await createSession2({
|
|
642
895
|
db: service.db,
|
|
643
896
|
bus: service.bus,
|
|
@@ -661,10 +914,11 @@ function createAutomationActivities(services, options = {}) {
|
|
|
661
914
|
workspaceId: input.workspaceId,
|
|
662
915
|
initialMessage: accepted.initialMessage,
|
|
663
916
|
surface: "automation",
|
|
917
|
+
metrics: service.observability,
|
|
664
918
|
resources: template.resources,
|
|
665
919
|
skills: SessionSkills.parse(template.skills),
|
|
666
920
|
bundledSkillIds: template.bundledSkillIds,
|
|
667
|
-
tools:
|
|
921
|
+
tools: agentWriteThrough.tools,
|
|
668
922
|
toolPolicy: { mode: "explicit", inheritedFromSessionId: null },
|
|
669
923
|
model,
|
|
670
924
|
reasoningEffort,
|
|
@@ -683,10 +937,11 @@ function createAutomationActivities(services, options = {}) {
|
|
|
683
937
|
label: accepted.serviceLabel
|
|
684
938
|
},
|
|
685
939
|
createdByContext: accepted.provenance,
|
|
686
|
-
instructions: template.instructions,
|
|
940
|
+
instructions: agentWriteThrough.instructions ?? template.instructions,
|
|
687
941
|
policyRole: template.policyRole,
|
|
688
942
|
firstPartyMcpPermissions: template.firstPartyMcpPermissions,
|
|
689
|
-
firstPartyMcpTools:
|
|
943
|
+
firstPartyMcpTools: agentWriteThrough.firstPartyMcpTools,
|
|
944
|
+
...agentWriteThrough.config ? { agentConfig: agentWriteThrough.config } : {},
|
|
690
945
|
retainWorkspaceCustomModel: model.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX) || model.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX),
|
|
691
946
|
createIdempotencyKey: `automation-run:${run.id}`,
|
|
692
947
|
subjectId: accepted.serviceSubjectId
|
|
@@ -1069,7 +1324,7 @@ import {
|
|
|
1069
1324
|
markSandboxCheckpointArtifactDeletePending,
|
|
1070
1325
|
recordWarmingSandboxCreated,
|
|
1071
1326
|
registerSandboxCheckpointArtifact,
|
|
1072
|
-
releaseLeaseHolder,
|
|
1327
|
+
releaseLeaseHolder as releaseLeaseHolder2,
|
|
1073
1328
|
touchLeaseHolder,
|
|
1074
1329
|
updateRigChangeStatus,
|
|
1075
1330
|
SandboxCheckpointArtifactRegistrationConflictError
|
|
@@ -1217,7 +1472,7 @@ function createRigVerificationActivityLifecycle(context = currentActivityContext
|
|
|
1217
1472
|
Math.max(1, startToCloseTimeoutMs - reserveMs)
|
|
1218
1473
|
);
|
|
1219
1474
|
}
|
|
1220
|
-
const
|
|
1475
|
+
const heartbeat2 = () => {
|
|
1221
1476
|
if (!context) return;
|
|
1222
1477
|
try {
|
|
1223
1478
|
context.heartbeat({
|
|
@@ -1230,13 +1485,13 @@ function createRigVerificationActivityLifecycle(context = currentActivityContext
|
|
|
1230
1485
|
if (!controller.signal.aborted) controller.abort(error);
|
|
1231
1486
|
}
|
|
1232
1487
|
};
|
|
1233
|
-
|
|
1488
|
+
heartbeat2();
|
|
1234
1489
|
const heartbeatTimeoutMs = context?.info.heartbeatTimeoutMs;
|
|
1235
1490
|
const heartbeatIntervalMs = typeof heartbeatTimeoutMs === "number" && heartbeatTimeoutMs > 0 ? Math.min(
|
|
1236
1491
|
RIG_VERIFICATION_HEARTBEAT_MAX_INTERVAL_MS,
|
|
1237
1492
|
Math.max(RIG_VERIFICATION_HEARTBEAT_MIN_INTERVAL_MS, Math.floor(heartbeatTimeoutMs / 3))
|
|
1238
1493
|
) : RIG_VERIFICATION_HEARTBEAT_MAX_INTERVAL_MS;
|
|
1239
|
-
const heartbeatTimer = context ? setInterval(
|
|
1494
|
+
const heartbeatTimer = context ? setInterval(heartbeat2, heartbeatIntervalMs) : null;
|
|
1240
1495
|
if (heartbeatTimer && "unref" in heartbeatTimer && typeof heartbeatTimer.unref === "function") {
|
|
1241
1496
|
heartbeatTimer.unref();
|
|
1242
1497
|
}
|
|
@@ -1321,7 +1576,7 @@ var defaultOwnershipDependencies = {
|
|
|
1321
1576
|
recordCreated: recordWarmingSandboxCreated,
|
|
1322
1577
|
commitWarm: commitWarmingToWarm,
|
|
1323
1578
|
touchHolder: touchLeaseHolder,
|
|
1324
|
-
releaseHolder:
|
|
1579
|
+
releaseHolder: releaseLeaseHolder2,
|
|
1325
1580
|
failWarming: failWarmingToCold,
|
|
1326
1581
|
markWarmLost: markWarmLeaseInstanceLost,
|
|
1327
1582
|
serialize: serializeEstablishedSandboxEnvelope,
|
|
@@ -2418,7 +2673,7 @@ function retainedProcessDeadlineRetryMs(process, lease, settings, retryAfterMs,
|
|
|
2418
2673
|
// src/activities/sandbox-lease.ts
|
|
2419
2674
|
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
2420
2675
|
import { requestRetainedProcessDeadlineCancellation } from "@opengeni/db/retained-provider-commands";
|
|
2421
|
-
import { Context } from "@temporalio/activity";
|
|
2676
|
+
import { Context as Context2 } from "@temporalio/activity";
|
|
2422
2677
|
import { OpLostReason, OpState } from "@opengeni/agent-proto";
|
|
2423
2678
|
import {
|
|
2424
2679
|
accrueWarmSeconds,
|
|
@@ -2439,6 +2694,8 @@ import {
|
|
|
2439
2694
|
deferRetainedProcessReconciliation,
|
|
2440
2695
|
forceDrainOverLimitViewerOnlyBoxes,
|
|
2441
2696
|
listCreditBalancesByAccount,
|
|
2697
|
+
countActiveUsers,
|
|
2698
|
+
readCreditGrantTotals,
|
|
2442
2699
|
readVerifiedSignupTrialSwitch,
|
|
2443
2700
|
listLegacyModalCheckpointSlots,
|
|
2444
2701
|
listLiveModalSandboxLeaseAttributions,
|
|
@@ -2454,7 +2711,7 @@ import {
|
|
|
2454
2711
|
registerSandboxCheckpointArtifact as registerSandboxCheckpointArtifact2,
|
|
2455
2712
|
recordRetainedProcessReconciliationProof,
|
|
2456
2713
|
replaceWorkspaceArchiveCaptureAfterProof,
|
|
2457
|
-
readLease,
|
|
2714
|
+
readLease as readLease2,
|
|
2458
2715
|
readWorkspaceArchiveCapturePreflight,
|
|
2459
2716
|
reapExpiredSessionListSnapshots,
|
|
2460
2717
|
reapStaleLeaseHoldersGlobal,
|
|
@@ -2482,9 +2739,9 @@ import {
|
|
|
2482
2739
|
disposeWorkspaceArchive,
|
|
2483
2740
|
cancelSelfhostedOp,
|
|
2484
2741
|
assertConsistentSandboxProviderIdentity,
|
|
2485
|
-
createSandboxClientForBackend,
|
|
2742
|
+
createSandboxClientForBackend as createSandboxClientForBackend2,
|
|
2486
2743
|
deleteModalCheckpointSnapshot as deleteModalCheckpointSnapshot2,
|
|
2487
|
-
deserializeSandboxSessionStateEnvelope,
|
|
2744
|
+
deserializeSandboxSessionStateEnvelope as deserializeSandboxSessionStateEnvelope2,
|
|
2488
2745
|
establishSandboxSessionFromEnvelope as establishSandboxSessionFromEnvelope2,
|
|
2489
2746
|
inspectModalSandboxLifecycle,
|
|
2490
2747
|
isExecSessionLostBanner,
|
|
@@ -2503,7 +2760,7 @@ import {
|
|
|
2503
2760
|
findModalProviderCreateReceipt,
|
|
2504
2761
|
resolveModalCheckpointProviderBindingForSession,
|
|
2505
2762
|
querySelfhostedOp,
|
|
2506
|
-
resumeExactSandboxSession,
|
|
2763
|
+
resumeExactSandboxSession as resumeExactSandboxSession2,
|
|
2507
2764
|
sandboxProviderContinuityForState,
|
|
2508
2765
|
sandboxBackendForSdkBackendId,
|
|
2509
2766
|
sandboxProviderInstanceIdFromEnvelope,
|
|
@@ -2562,18 +2819,18 @@ async function awaitProviderCaptureWithLatePublication(input) {
|
|
|
2562
2819
|
function startSandboxReaperHeartbeat(details) {
|
|
2563
2820
|
let context;
|
|
2564
2821
|
try {
|
|
2565
|
-
context =
|
|
2822
|
+
context = Context2.current();
|
|
2566
2823
|
} catch {
|
|
2567
2824
|
return () => void 0;
|
|
2568
2825
|
}
|
|
2569
|
-
const
|
|
2826
|
+
const heartbeat2 = () => {
|
|
2570
2827
|
try {
|
|
2571
2828
|
context.heartbeat({ ...details, heartbeatAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
2572
2829
|
} catch {
|
|
2573
2830
|
}
|
|
2574
2831
|
};
|
|
2575
|
-
|
|
2576
|
-
const timer = setInterval(
|
|
2832
|
+
heartbeat2();
|
|
2833
|
+
const timer = setInterval(heartbeat2, SANDBOX_REAPER_ACTIVITY_HEARTBEAT_INTERVAL_MS);
|
|
2577
2834
|
if ("unref" in timer && typeof timer.unref === "function") timer.unref();
|
|
2578
2835
|
return () => clearInterval(timer);
|
|
2579
2836
|
}
|
|
@@ -2596,7 +2853,7 @@ function sandboxDrainCaptureId(operationId, attempt) {
|
|
|
2596
2853
|
}
|
|
2597
2854
|
function sandboxDrainActivityAttempt() {
|
|
2598
2855
|
try {
|
|
2599
|
-
const attempt =
|
|
2856
|
+
const attempt = Context2.current().info.attempt;
|
|
2600
2857
|
return Number.isSafeInteger(attempt) && attempt > 0 ? attempt : 1;
|
|
2601
2858
|
} catch {
|
|
2602
2859
|
return 1;
|
|
@@ -2611,7 +2868,7 @@ function createSandboxLeaseActivities(services, options = {}) {
|
|
|
2611
2868
|
lease,
|
|
2612
2869
|
observability,
|
|
2613
2870
|
persistArchive,
|
|
2614
|
-
|
|
2871
|
+
createSandboxClientForBackend2,
|
|
2615
2872
|
terminateModalSandboxById,
|
|
2616
2873
|
providerCaptureRequestId,
|
|
2617
2874
|
captureDisposition,
|
|
@@ -2729,7 +2986,7 @@ function createSandboxLeaseActivities(services, options = {}) {
|
|
|
2729
2986
|
);
|
|
2730
2987
|
return { status: drainedCold ? "terminated" : "skipped" };
|
|
2731
2988
|
} catch (error) {
|
|
2732
|
-
const lease = await
|
|
2989
|
+
const lease = await readLease2(db, row.workspaceId, row.sandboxGroupId).catch(() => null);
|
|
2733
2990
|
const details = {
|
|
2734
2991
|
sandboxLeaseKey: sandboxLeaseTelemetryKey(row.workspaceId, row.sandboxGroupId),
|
|
2735
2992
|
workspaceId: row.workspaceId,
|
|
@@ -3441,7 +3698,7 @@ async function reconcileTerminalRetainedProcesses(db, settings, observability, p
|
|
|
3441
3698
|
}
|
|
3442
3699
|
}
|
|
3443
3700
|
if (observation === null) {
|
|
3444
|
-
const lease = await
|
|
3701
|
+
const lease = await readLease2(db, process.workspaceId, process.sandboxGroupId).catch(
|
|
3445
3702
|
() => null
|
|
3446
3703
|
);
|
|
3447
3704
|
const currentLeaseIdentityMatches = Boolean(lease) && lease.id === process.leaseId && lease.leaseEpoch === process.leaseEpoch && lease.backend === process.providerBackend && lease.instanceId === process.providerInstanceId && process.routeTargetId === null;
|
|
@@ -3650,7 +3907,7 @@ async function reconcileTerminalRetainedProcesses(db, settings, observability, p
|
|
|
3650
3907
|
async function deferRetainedProcessClaim(db, settings, observability, process, expected, claimId, outcome, outputBacklog = false) {
|
|
3651
3908
|
const deferral = retainedProcessReconciliationDeferral(settings, process, outcome, outputBacklog);
|
|
3652
3909
|
try {
|
|
3653
|
-
const lease = process.providerBackend === "modal" && process.routeTargetId === null ? await
|
|
3910
|
+
const lease = process.providerBackend === "modal" && process.routeTargetId === null ? await readLease2(db, process.workspaceId, process.sandboxGroupId) : null;
|
|
3654
3911
|
await deferRetainedProcessReconciliation(db, {
|
|
3655
3912
|
accountId: process.accountId,
|
|
3656
3913
|
workspaceId: process.workspaceId,
|
|
@@ -3799,7 +4056,7 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
|
|
|
3799
4056
|
}
|
|
3800
4057
|
let client;
|
|
3801
4058
|
try {
|
|
3802
|
-
client =
|
|
4059
|
+
client = createSandboxClientForBackend2(process.providerBackend, settings);
|
|
3803
4060
|
} catch {
|
|
3804
4061
|
return { status: "deferred", reason: "provider_error" };
|
|
3805
4062
|
}
|
|
@@ -3809,7 +4066,7 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
|
|
|
3809
4066
|
const envelopeSessionState = lease.resumeState.sessionState ?? lease.resumeState;
|
|
3810
4067
|
let resumedState;
|
|
3811
4068
|
try {
|
|
3812
|
-
resumedState = await
|
|
4069
|
+
resumedState = await deserializeSandboxSessionStateEnvelope2(
|
|
3813
4070
|
client,
|
|
3814
4071
|
envelopeSessionState,
|
|
3815
4072
|
process.providerInstanceId
|
|
@@ -3823,7 +4080,7 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
|
|
|
3823
4080
|
let session;
|
|
3824
4081
|
try {
|
|
3825
4082
|
const resumed = await withRetainedProcessProbeTimeout(
|
|
3826
|
-
|
|
4083
|
+
resumeExactSandboxSession2(
|
|
3827
4084
|
client,
|
|
3828
4085
|
process.providerBackend,
|
|
3829
4086
|
resumedState,
|
|
@@ -4133,6 +4390,24 @@ async function refreshQueueLeaseAndCreditGauges(db, settings, observability, ins
|
|
|
4133
4390
|
});
|
|
4134
4391
|
}
|
|
4135
4392
|
})(),
|
|
4393
|
+
(async () => {
|
|
4394
|
+
try {
|
|
4395
|
+
recordActiveUserGauges(observability, await countActiveUsers(db));
|
|
4396
|
+
} catch (error) {
|
|
4397
|
+
observability.warn("sandbox reaper: active-user gauge refresh failed", {
|
|
4398
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4399
|
+
});
|
|
4400
|
+
}
|
|
4401
|
+
})(),
|
|
4402
|
+
(async () => {
|
|
4403
|
+
try {
|
|
4404
|
+
recordCreditGrantGauges(observability, await readCreditGrantTotals(db));
|
|
4405
|
+
} catch (error) {
|
|
4406
|
+
observability.warn("sandbox reaper: credit-grant gauge refresh failed", {
|
|
4407
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4408
|
+
});
|
|
4409
|
+
}
|
|
4410
|
+
})(),
|
|
4136
4411
|
(async () => {
|
|
4137
4412
|
recordVerifiedSignupTrialDeploymentFlagGauge(
|
|
4138
4413
|
observability,
|
|
@@ -4335,7 +4610,7 @@ function sandboxDrainReason(lease) {
|
|
|
4335
4610
|
}
|
|
4336
4611
|
async function terminateDrainableBox(db, settings, row, observability, terminateBox, probeDrainableProvider, attempt, objectStorage) {
|
|
4337
4612
|
const { accountId } = await rlsContextForWorkspace(db, row.workspaceId);
|
|
4338
|
-
const lease = await
|
|
4613
|
+
const lease = await readLease2(db, row.workspaceId, row.sandboxGroupId);
|
|
4339
4614
|
if (!lease) {
|
|
4340
4615
|
return false;
|
|
4341
4616
|
}
|
|
@@ -4699,7 +4974,7 @@ function providerDrainLogIdentity(lease, backend) {
|
|
|
4699
4974
|
instanceId: lease.instanceId
|
|
4700
4975
|
};
|
|
4701
4976
|
}
|
|
4702
|
-
async function terminateProviderBox(settings, lease, observability, persistArchive, createClientForBackend =
|
|
4977
|
+
async function terminateProviderBox(settings, lease, observability, persistArchive, createClientForBackend = createSandboxClientForBackend2, terminateModalById = terminateModalSandboxById, providerCaptureRequestId, captureDisposition = "capture_required", claimedCapturePolicy, diskBackedArchives = false, releaseFailedCapture, workspaceId, beforeProviderStop) {
|
|
4703
4978
|
const durableBackendId = lease.resumeBackendId ?? lease.backend;
|
|
4704
4979
|
const backend = sandboxBackendForSdkBackendId(durableBackendId) ?? durableBackendId;
|
|
4705
4980
|
const logIdentity = providerDrainLogIdentity(lease, backend);
|
|
@@ -4801,7 +5076,7 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
|
|
|
4801
5076
|
throw new Error(`sandbox backend ${backend} cannot resume a drainable provider box`);
|
|
4802
5077
|
}
|
|
4803
5078
|
const envelopeSessionState = lease.resumeState.sessionState ?? lease.resumeState;
|
|
4804
|
-
const resumedState = await
|
|
5079
|
+
const resumedState = await deserializeSandboxSessionStateEnvelope2(
|
|
4805
5080
|
client,
|
|
4806
5081
|
envelopeSessionState,
|
|
4807
5082
|
lease.instanceId
|
|
@@ -4810,7 +5085,7 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
|
|
|
4810
5085
|
throw new Error(`sandbox backend ${backend} returned no resumable provider state`);
|
|
4811
5086
|
}
|
|
4812
5087
|
const continuity = sandboxProviderContinuityForState(backend, resumedState, lease.instanceId);
|
|
4813
|
-
const resumed = await
|
|
5088
|
+
const resumed = await resumeExactSandboxSession2(
|
|
4814
5089
|
client,
|
|
4815
5090
|
backend,
|
|
4816
5091
|
resumedState,
|
|
@@ -4970,9 +5245,11 @@ import {
|
|
|
4970
5245
|
SessionAgentAccess,
|
|
4971
5246
|
SessionMemoryScope,
|
|
4972
5247
|
normalizeAutomaticSessionTitle,
|
|
5248
|
+
metadataWithTurnExecutionPolicyV1,
|
|
4973
5249
|
scheduledOccurrencePayloadUtf8Bytes,
|
|
4974
5250
|
stableJson,
|
|
4975
|
-
TurnExecutionPolicyV1
|
|
5251
|
+
TurnExecutionPolicyV1,
|
|
5252
|
+
AgentConfigError
|
|
4976
5253
|
} from "@opengeni/contracts";
|
|
4977
5254
|
import {
|
|
4978
5255
|
openGeniSlackBotMetadata,
|
|
@@ -4990,7 +5267,12 @@ import {
|
|
|
4990
5267
|
scheduledConnectionTools,
|
|
4991
5268
|
settingsWithEnabledCapabilityMcpServers,
|
|
4992
5269
|
settingsWithSessionMcpServerMetadata,
|
|
4993
|
-
swapActiveSandbox
|
|
5270
|
+
swapActiveSandbox,
|
|
5271
|
+
agentConfigMayResolve as agentConfigMayResolve2,
|
|
5272
|
+
applySessionAgentConfigWriteThrough as applySessionAgentConfigWriteThrough2,
|
|
5273
|
+
resolveSessionAgentConfigForCreate as resolveSessionAgentConfigForCreate2,
|
|
5274
|
+
recordSessionCreated,
|
|
5275
|
+
recordUserMessageAccepted
|
|
4994
5276
|
} from "@opengeni/core";
|
|
4995
5277
|
import {
|
|
4996
5278
|
addSessionSystemUpdateWithSourceMutation,
|
|
@@ -5017,6 +5299,7 @@ import {
|
|
|
5017
5299
|
getNestedAgentDepthDeploymentPolicy,
|
|
5018
5300
|
getSessionByCreateIdempotencyKey,
|
|
5019
5301
|
getSessionCreationExecutionPolicy,
|
|
5302
|
+
metadataWithAgentConfigCreateIdentity,
|
|
5020
5303
|
getVariableSet,
|
|
5021
5304
|
isCodexBilledModel,
|
|
5022
5305
|
initializeSessionStartAtomically,
|
|
@@ -5027,7 +5310,7 @@ import {
|
|
|
5027
5310
|
recordUsageEvent as recordUsageEvent2,
|
|
5028
5311
|
requireScheduledTaskIncidentAuthorityInTransaction,
|
|
5029
5312
|
requireSession,
|
|
5030
|
-
requireWorkspace,
|
|
5313
|
+
requireWorkspace as requireWorkspace2,
|
|
5031
5314
|
settleScheduledTaskRunInTransaction,
|
|
5032
5315
|
SessionSpawnDeniedDbError,
|
|
5033
5316
|
updateSessionTitleWithEvent,
|
|
@@ -5040,7 +5323,7 @@ import {
|
|
|
5040
5323
|
resolveFirstPartyMcpToolPolicy,
|
|
5041
5324
|
resolveTurnExecutionPolicyV1 as resolveTurnExecutionPolicyV12
|
|
5042
5325
|
} from "@opengeni/config";
|
|
5043
|
-
import { Context as
|
|
5326
|
+
import { Context as Context3 } from "@temporalio/activity";
|
|
5044
5327
|
import { createHash as createHash3 } from "crypto";
|
|
5045
5328
|
|
|
5046
5329
|
// src/scheduled-alert-occurrence.ts
|
|
@@ -5156,13 +5439,21 @@ function canonicalLabels(value) {
|
|
|
5156
5439
|
}
|
|
5157
5440
|
|
|
5158
5441
|
// src/activities/scheduled-tasks.ts
|
|
5442
|
+
function scheduledTaskRunExecutionPolicy(policy, input, creatorRestriction) {
|
|
5443
|
+
return creatorRestriction === "developer_setup" || input.triggerType !== "scheduled" && input.credentialRestriction === "developer_setup" ? { ...policy, credentialRestriction: "developer_setup" } : policy;
|
|
5444
|
+
}
|
|
5445
|
+
function scheduledSessionExecutionPolicyMetadata(policy, creatorRestriction) {
|
|
5446
|
+
if (policy === void 0 || policy === null) return {};
|
|
5447
|
+
const acceptedPolicy = TurnExecutionPolicyV1.parse(policy);
|
|
5448
|
+
return creatorRestriction === "developer_setup" && acceptedPolicy.credentialRestriction === "developer_setup" ? metadataWithTurnExecutionPolicyV1({}, acceptedPolicy) : {};
|
|
5449
|
+
}
|
|
5159
5450
|
function scheduledTaskRunProducerKey(input, suppliedActivityIdentity) {
|
|
5160
5451
|
if (input.producerKey) return input.producerKey;
|
|
5161
5452
|
if (input.triggerType !== "scheduled") return input.agentRunUsageIdempotencyKey;
|
|
5162
5453
|
let info = suppliedActivityIdentity;
|
|
5163
5454
|
if (!info) {
|
|
5164
5455
|
try {
|
|
5165
|
-
info =
|
|
5456
|
+
info = Context3.current().info;
|
|
5166
5457
|
} catch {
|
|
5167
5458
|
throw new Error(
|
|
5168
5459
|
"scheduled task delivery without a producer key requires a Temporal activity execution"
|
|
@@ -5181,6 +5472,13 @@ function scheduledTaskGeneratedSessionCreateIdempotencyKey(producerKey) {
|
|
|
5181
5472
|
const digest = createHash3("sha256").update("scheduled-task-run\0", "utf8").update(producerKey, "utf8").digest("hex");
|
|
5182
5473
|
return `scheduled-task-run:${digest}`;
|
|
5183
5474
|
}
|
|
5475
|
+
function recordScheduledSessionCreated(observability) {
|
|
5476
|
+
recordSessionCreated(observability, {
|
|
5477
|
+
surface: "scheduled",
|
|
5478
|
+
createdByKind: "service",
|
|
5479
|
+
parentSessionId: null
|
|
5480
|
+
});
|
|
5481
|
+
}
|
|
5184
5482
|
function scheduledTaskSessionTitle(taskName) {
|
|
5185
5483
|
return normalizeAutomaticSessionTitle(taskName) ?? "Scheduled run";
|
|
5186
5484
|
}
|
|
@@ -5255,6 +5553,7 @@ function createScheduledTaskActivities(services) {
|
|
|
5255
5553
|
try {
|
|
5256
5554
|
return await recoverBoundScheduledTaskDispatch({
|
|
5257
5555
|
db,
|
|
5556
|
+
observability: baseService.observability,
|
|
5258
5557
|
bus,
|
|
5259
5558
|
settings: settings2,
|
|
5260
5559
|
wakeSessionWorkflow,
|
|
@@ -5377,13 +5676,46 @@ function createScheduledTaskActivities(services) {
|
|
|
5377
5676
|
const reasoningEffort = task.agentConfig.reasoningEffort ?? resolvedDefault?.reasoningEffort ?? settings.openaiReasoningEffort;
|
|
5378
5677
|
let sandboxBackend = task.agentConfig.sandboxBackend ?? settings.sandboxBackend;
|
|
5379
5678
|
let sandboxOs = "linux";
|
|
5380
|
-
|
|
5679
|
+
let taskTools = withFirstPartyTools(settings, task.agentConfig.tools);
|
|
5381
5680
|
const creatorPolicy = await getScheduledTaskCreatorPolicy(db, task.workspaceId, task.id);
|
|
5382
|
-
|
|
5681
|
+
let firstPartyMcpTools = withScheduledSlackBotPostingTools(
|
|
5383
5682
|
creatorPolicy?.firstPartyMcpTools ? allowedFirstPartyMcpToolsForSession(settings, creatorPolicy.firstPartyMcpTools) : resolveFirstPartyMcpToolPolicy(settings).default,
|
|
5384
5683
|
task.agentConfig,
|
|
5385
5684
|
resolveFirstPartyMcpToolPolicy(settings).allowed
|
|
5386
5685
|
);
|
|
5686
|
+
let resolvedAgentConfig = null;
|
|
5687
|
+
let resolvedAgentInstructions;
|
|
5688
|
+
try {
|
|
5689
|
+
const agentResolution = resolveSessionAgentConfigForCreate2({
|
|
5690
|
+
settings,
|
|
5691
|
+
creator: "scheduled",
|
|
5692
|
+
request: task.agentConfig.agent,
|
|
5693
|
+
instructions: void 0,
|
|
5694
|
+
workspaceSettings: agentConfigMayResolve2(settings, task.agentConfig.agent) ? (await requireWorkspace2(db, task.workspaceId)).settings : {},
|
|
5695
|
+
parent: null,
|
|
5696
|
+
goal: task.agentConfig.goal !== void 0
|
|
5697
|
+
});
|
|
5698
|
+
resolvedAgentConfig = agentResolution.config;
|
|
5699
|
+
resolvedAgentInstructions = agentResolution.instructions;
|
|
5700
|
+
const written = applySessionAgentConfigWriteThrough2({
|
|
5701
|
+
config: resolvedAgentConfig,
|
|
5702
|
+
firstPartyMcpTools,
|
|
5703
|
+
tools: taskTools,
|
|
5704
|
+
toolPolicy: { mode: "explicit", inheritedFromSessionId: null },
|
|
5705
|
+
productServerIds: task.agentConfig.tools.map((tool) => tool.id)
|
|
5706
|
+
});
|
|
5707
|
+
firstPartyMcpTools = written.firstPartyMcpTools;
|
|
5708
|
+
taskTools = written.tools;
|
|
5709
|
+
} catch (error) {
|
|
5710
|
+
const status = error instanceof Error ? error.status : void 0;
|
|
5711
|
+
if (!(error instanceof Error) || status !== 422) throw error;
|
|
5712
|
+
const notEnabled = error.cause instanceof AgentConfigError && error.cause.code === "agent_config_not_enabled";
|
|
5713
|
+
return await refuseAdmission(
|
|
5714
|
+
"scheduled_authority_unavailable",
|
|
5715
|
+
notEnabled,
|
|
5716
|
+
`scheduled agent configuration is not admissible: ${error.message}`
|
|
5717
|
+
);
|
|
5718
|
+
}
|
|
5387
5719
|
const firstPartyMcpPermissions = creatorPolicy?.firstPartyMcpPermissions ? [...creatorPolicy.firstPartyMcpPermissions] : [...DEFAULT_FIRST_PARTY_MCP_PERMISSIONS];
|
|
5388
5720
|
const connectionSettings = await settingsWithEnabledCapabilityMcpServers(
|
|
5389
5721
|
db,
|
|
@@ -5488,7 +5820,7 @@ function createScheduledTaskActivities(services) {
|
|
|
5488
5820
|
);
|
|
5489
5821
|
}
|
|
5490
5822
|
const generatedSessionDepthPolicy = generatedTarget ? await (async () => {
|
|
5491
|
-
const workspace = await
|
|
5823
|
+
const workspace = await requireWorkspace2(db, task.workspaceId);
|
|
5492
5824
|
const deployment = await getNestedAgentDepthDeploymentPolicy(db);
|
|
5493
5825
|
const taskOverride = task.agentConfig.maxNestedAgentDepth ?? null;
|
|
5494
5826
|
const workspaceOverride = typeof workspace.settings.maxNestedAgentDepth === "number" ? workspace.settings.maxNestedAgentDepth : null;
|
|
@@ -5699,7 +6031,8 @@ function createScheduledTaskActivities(services) {
|
|
|
5699
6031
|
accountId: task.accountId,
|
|
5700
6032
|
workspaceId: task.workspaceId,
|
|
5701
6033
|
model: targetSessionExecution?.model ?? model,
|
|
5702
|
-
requestedAgentRuns: input.agentRunUsageIdempotencyKey ? 0 : 1
|
|
6034
|
+
requestedAgentRuns: input.agentRunUsageIdempotencyKey ? 0 : 1,
|
|
6035
|
+
initiatingHumanSubjectId: causalHumanSubjectId
|
|
5703
6036
|
}
|
|
5704
6037
|
);
|
|
5705
6038
|
if (admissionDenial) {
|
|
@@ -5722,15 +6055,19 @@ function createScheduledTaskActivities(services) {
|
|
|
5722
6055
|
);
|
|
5723
6056
|
}
|
|
5724
6057
|
} : void 0;
|
|
5725
|
-
const turnExecutionPolicy =
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
6058
|
+
const turnExecutionPolicy = scheduledTaskRunExecutionPolicy(
|
|
6059
|
+
resolveTurnExecutionPolicyV12(settings, {
|
|
6060
|
+
modelId: acceptedModel,
|
|
6061
|
+
requestedModelId: generatedTarget && task.agentConfig.model ? task.agentConfig.model : null,
|
|
6062
|
+
modelSource: generatedTarget ? task.agentConfig.model ? "explicit" : "deployment" : "session",
|
|
6063
|
+
reasoningEffort: acceptedReasoningEffort,
|
|
6064
|
+
reasoningSource: generatedTarget ? task.agentConfig.reasoningEffort ? "explicit" : "deployment" : "session",
|
|
6065
|
+
latencyMode: acceptedLatencyMode,
|
|
6066
|
+
latencyModeSource: generatedTarget ? "deployment" : "session"
|
|
6067
|
+
}),
|
|
6068
|
+
input,
|
|
6069
|
+
creatorPolicy?.credentialRestriction
|
|
6070
|
+
);
|
|
5734
6071
|
const deferredEvents = [];
|
|
5735
6072
|
const executeDispatch = async (dispatchDb, deferPublications) => {
|
|
5736
6073
|
const admittedRunId = crypto.randomUUID();
|
|
@@ -5752,6 +6089,10 @@ function createScheduledTaskActivities(services) {
|
|
|
5752
6089
|
resolvedTools: taskTools,
|
|
5753
6090
|
resolvedFirstPartyMcpTools: firstPartyMcpTools,
|
|
5754
6091
|
resolvedFirstPartyMcpPermissions: firstPartyMcpPermissions,
|
|
6092
|
+
...resolvedAgentConfig ? {
|
|
6093
|
+
resolvedAgentConfig,
|
|
6094
|
+
...resolvedAgentInstructions !== void 0 ? { resolvedAgentInstructions } : {}
|
|
6095
|
+
} : {},
|
|
5755
6096
|
resolvedVariableSet: acceptedVariableSet ? { id: acceptedVariableSet.id, generation: acceptedVariableSet.generation } : null,
|
|
5756
6097
|
resolvedRig: acceptedRig?.activeVersion ? {
|
|
5757
6098
|
id: acceptedRig.id,
|
|
@@ -5928,6 +6269,8 @@ function createScheduledTaskActivities(services) {
|
|
|
5928
6269
|
tools: taskTools,
|
|
5929
6270
|
firstPartyMcpTools,
|
|
5930
6271
|
firstPartyMcpPermissions,
|
|
6272
|
+
...resolvedAgentConfig ? { agentConfig: resolvedAgentConfig } : {},
|
|
6273
|
+
...resolvedAgentInstructions !== void 0 ? { instructions: resolvedAgentInstructions } : {},
|
|
5931
6274
|
...creatorSessionPolicy,
|
|
5932
6275
|
...task.agentConfig.knowledgeSource?.destination.kind === "personal" ? {
|
|
5933
6276
|
visibility: "user_private",
|
|
@@ -5935,6 +6278,10 @@ function createScheduledTaskActivities(services) {
|
|
|
5935
6278
|
} : {},
|
|
5936
6279
|
metadata: {
|
|
5937
6280
|
...taskMetadata,
|
|
6281
|
+
...scheduledSessionExecutionPolicyMetadata(
|
|
6282
|
+
turnExecutionPolicy,
|
|
6283
|
+
creatorPolicy?.credentialRestriction
|
|
6284
|
+
),
|
|
5938
6285
|
model,
|
|
5939
6286
|
reasoningEffort,
|
|
5940
6287
|
scheduledTaskId: task.id,
|
|
@@ -6024,6 +6371,7 @@ function createScheduledTaskActivities(services) {
|
|
|
6024
6371
|
}
|
|
6025
6372
|
session = created.session;
|
|
6026
6373
|
sessionCreated = created.created;
|
|
6374
|
+
if (sessionCreated) recordScheduledSessionCreated(baseService.observability);
|
|
6027
6375
|
if (!sessionCreated) {
|
|
6028
6376
|
await bindScheduledTaskRunSessionInTransaction(dispatchDb, {
|
|
6029
6377
|
accountId: task.accountId,
|
|
@@ -6259,6 +6607,9 @@ function createScheduledTaskActivities(services) {
|
|
|
6259
6607
|
run: { ...run, status: "skipped", error }
|
|
6260
6608
|
};
|
|
6261
6609
|
}
|
|
6610
|
+
if (scheduledUpdate.added) {
|
|
6611
|
+
recordUserMessageAccepted(baseService.observability, { surface: "scheduled" });
|
|
6612
|
+
}
|
|
6262
6613
|
if (scheduledUpdate.added && scheduledUpdate.events.length > 0) {
|
|
6263
6614
|
if (deferPublications) {
|
|
6264
6615
|
deferredEvents.push({
|
|
@@ -6383,6 +6734,9 @@ function createScheduledTaskActivities(services) {
|
|
|
6383
6734
|
run: { ...run, status: "skipped", error }
|
|
6384
6735
|
};
|
|
6385
6736
|
}
|
|
6737
|
+
if (bundled.added) {
|
|
6738
|
+
recordUserMessageAccepted(baseService.observability, { surface: "scheduled" });
|
|
6739
|
+
}
|
|
6386
6740
|
if (bundled.added && bundled.events.length > 0) {
|
|
6387
6741
|
if (deferPublications) {
|
|
6388
6742
|
deferredEvents.push({
|
|
@@ -6724,6 +7078,7 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
6724
7078
|
throw new Error("scheduled run is not an exact queued recovery");
|
|
6725
7079
|
}
|
|
6726
7080
|
const generatedSession = task.runMode === "new_session_per_run" || task.runMode === "reusable_session" && task.reusableSessionId === null;
|
|
7081
|
+
const recoveredCreatorPolicy = generatedSession ? await getScheduledTaskCreatorPolicy(input.db, task.workspaceId, task.id) : null;
|
|
6727
7082
|
const frozenSlack = input.acceptedExecution.resolvedSlackBotConnection;
|
|
6728
7083
|
if (frozenSlack) {
|
|
6729
7084
|
const currentSlack = await requireOpenGeniSlackBotConnection(
|
|
@@ -6783,11 +7138,6 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
6783
7138
|
}
|
|
6784
7139
|
const taskMetadata = { ...task.agentConfig.metadata };
|
|
6785
7140
|
delete taskMetadata[OPENGENI_SLACK_BOT_SESSION_METADATA_KEY];
|
|
6786
|
-
const recoveredCreatorPolicy = await getScheduledTaskCreatorPolicy(
|
|
6787
|
-
input.db,
|
|
6788
|
-
task.workspaceId,
|
|
6789
|
-
task.id
|
|
6790
|
-
);
|
|
6791
7141
|
const created = await createSessionWithIdempotencyKeyResult(input.db, {
|
|
6792
7142
|
accountId: task.accountId,
|
|
6793
7143
|
workspaceId: task.workspaceId,
|
|
@@ -6797,6 +7147,8 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
6797
7147
|
tools: input.acceptedExecution.resolvedTools,
|
|
6798
7148
|
firstPartyMcpTools: input.acceptedExecution.resolvedFirstPartyMcpTools,
|
|
6799
7149
|
firstPartyMcpPermissions: input.acceptedExecution.resolvedFirstPartyMcpPermissions,
|
|
7150
|
+
...input.acceptedExecution.resolvedAgentConfig ? { agentConfig: input.acceptedExecution.resolvedAgentConfig } : {},
|
|
7151
|
+
...input.acceptedExecution.resolvedAgentInstructions !== void 0 ? { instructions: input.acceptedExecution.resolvedAgentInstructions } : {},
|
|
6800
7152
|
...scheduledCreatorSessionPolicyInput(recoveredCreatorPolicy?.sessionPolicy ?? null),
|
|
6801
7153
|
...task.agentConfig.knowledgeSource?.destination.kind === "personal" ? {
|
|
6802
7154
|
visibility: "user_private",
|
|
@@ -6804,6 +7156,10 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
6804
7156
|
} : {},
|
|
6805
7157
|
metadata: {
|
|
6806
7158
|
...taskMetadata,
|
|
7159
|
+
...scheduledSessionExecutionPolicyMetadata(
|
|
7160
|
+
input.acceptedExecution.turnExecutionPolicy,
|
|
7161
|
+
recoveredCreatorPolicy?.credentialRestriction
|
|
7162
|
+
),
|
|
6807
7163
|
model: input.acceptedExecution.resolvedModel,
|
|
6808
7164
|
reasoningEffort: input.acceptedExecution.resolvedReasoningEffort,
|
|
6809
7165
|
scheduledTaskId: task.id,
|
|
@@ -6856,6 +7212,7 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
6856
7212
|
});
|
|
6857
7213
|
if (created.denied) throw new SessionSpawnDeniedDbError(created.denial);
|
|
6858
7214
|
session = created.session;
|
|
7215
|
+
if (created.created) recordScheduledSessionCreated(input.observability);
|
|
6859
7216
|
if (!created.created) {
|
|
6860
7217
|
await bindScheduledTaskRunSessionInTransaction(input.db, {
|
|
6861
7218
|
accountId: task.accountId,
|
|
@@ -6919,21 +7276,28 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
6919
7276
|
);
|
|
6920
7277
|
const expectedTaskMetadata = { ...task.agentConfig.metadata };
|
|
6921
7278
|
delete expectedTaskMetadata[OPENGENI_SLACK_BOT_SESSION_METADATA_KEY];
|
|
6922
|
-
const expectedMetadata =
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
7279
|
+
const expectedMetadata = metadataWithAgentConfigCreateIdentity(
|
|
7280
|
+
{
|
|
7281
|
+
...expectedTaskMetadata,
|
|
7282
|
+
...scheduledSessionExecutionPolicyMetadata(
|
|
7283
|
+
input.acceptedExecution.turnExecutionPolicy,
|
|
7284
|
+
recoveredCreatorPolicy?.credentialRestriction
|
|
7285
|
+
),
|
|
7286
|
+
model: input.acceptedExecution.resolvedModel,
|
|
7287
|
+
reasoningEffort: input.acceptedExecution.resolvedReasoningEffort,
|
|
7288
|
+
scheduledTaskId: task.id,
|
|
7289
|
+
scheduledTaskRunMode: task.runMode,
|
|
7290
|
+
...task.agentConfig.goal ? { scheduledTaskGoal: task.agentConfig.goal } : {},
|
|
7291
|
+
scheduledTaskRunId: canonicalGeneratedRunId,
|
|
7292
|
+
...frozenSlack ? { [OPENGENI_SLACK_BOT_SESSION_METADATA_KEY]: frozenSlack.id } : {}
|
|
7293
|
+
},
|
|
7294
|
+
input.acceptedExecution.resolvedAgentConfig
|
|
7295
|
+
);
|
|
7296
|
+
if (session.createIdempotencyKey !== expectedCreateKey || session.initialMessage !== task.agentConfig.prompt || session.instructions !== (input.acceptedExecution.resolvedAgentInstructions ?? null) || session.policyRole !== null || stableJson(session.skills) !== "[]" || stableJson(session.toolPolicy) !== stableJson({ mode: "explicit", inheritedFromSessionId: null }) || session.toolPolicyVersion !== 1 || session.mcpServers.length !== 0 || session.parentSessionId !== null || session.rootSessionId !== session.id || session.nestedAgentDepth !== 0 || session.effectiveMaxNestedAgentDepth !== generatedBinding.effectiveMaxNestedAgentDepth || session.nestedAgentDepthPolicySource !== generatedBinding.nestedAgentDepthPolicySource || session.nestedAgentDepthPolicySessionId !== (generatedBinding.nestedAgentDepthPolicySource === "session" ? session.id : null) || session.sandboxGroupId !== session.id || session.channelId !== null || session.codexCompactionMode !== generatedBinding.codexCompactionMode || stableJson(session.metadata) !== stableJson(expectedMetadata) || session.createdBy.kind !== "service" || session.createdBy.subjectId !== "scheduler" || stableJson(session.createdByContext) !== stableJson({
|
|
6933
7297
|
label: "OpenGeni scheduler",
|
|
6934
7298
|
scheduledTaskId: task.id,
|
|
6935
7299
|
scheduledTaskRunId: canonicalGeneratedRunId
|
|
6936
|
-
}) || task.runMode === "new_session_per_run" && input.acceptedExecution.alertOccurrenceLabels === null && (session.metadata.scheduledTaskRunId !== input.run.id || session.createdByContext.scheduledTaskRunId !== input.run.id) || creationPolicy?.model !== input.acceptedExecution.resolvedModel || creationPolicy.reasoningEffort !== input.acceptedExecution.resolvedReasoningEffort || creationPolicy.latencyMode !== input.acceptedExecution.resolvedLatencyMode || session.sandboxBackend !== input.acceptedExecution.resolvedSandboxBackend || session.sandboxOs !== input.acceptedExecution.resolvedSandboxOs || session.activeSandboxId !== (task.agentConfig.machineTarget?.targetSandboxId ?? null) || stableJson(session.resources) !== stableJson(task.agentConfig.resources) || stableJson(session.tools) !== stableJson(input.acceptedExecution.resolvedTools) || stableJson(session.firstPartyMcpTools) !== stableJson(input.acceptedExecution.resolvedFirstPartyMcpTools) || stableJson(session.firstPartyMcpPermissions) !== stableJson(input.acceptedExecution.resolvedFirstPartyMcpPermissions) || session.maxNestedAgentDepthOverride !== (task.agentConfig.maxNestedAgentDepth ?? null) || (session.variableSetId ?? null) !== (input.acceptedExecution.resolvedVariableSet?.id ?? null) || (session.rigId ?? null) !== (input.acceptedExecution.resolvedRig?.id ?? null) || (session.rigVersionId ?? null) !== (input.acceptedExecution.resolvedRig?.versionId ?? null) || scheduledSlackBotConnectionId(session.metadata) !== (frozenSlack?.id ?? null)) {
|
|
7300
|
+
}) || task.runMode === "new_session_per_run" && input.acceptedExecution.alertOccurrenceLabels === null && (session.metadata.scheduledTaskRunId !== input.run.id || session.createdByContext.scheduledTaskRunId !== input.run.id) || creationPolicy?.model !== input.acceptedExecution.resolvedModel || creationPolicy.reasoningEffort !== input.acceptedExecution.resolvedReasoningEffort || creationPolicy.latencyMode !== input.acceptedExecution.resolvedLatencyMode || session.sandboxBackend !== input.acceptedExecution.resolvedSandboxBackend || session.sandboxOs !== input.acceptedExecution.resolvedSandboxOs || session.activeSandboxId !== (task.agentConfig.machineTarget?.targetSandboxId ?? null) || stableJson(session.resources) !== stableJson(task.agentConfig.resources) || stableJson(session.tools) !== stableJson(input.acceptedExecution.resolvedTools) || stableJson(session.firstPartyMcpTools) !== stableJson(input.acceptedExecution.resolvedFirstPartyMcpTools) || stableJson(session.firstPartyMcpPermissions) !== stableJson(input.acceptedExecution.resolvedFirstPartyMcpPermissions) || stableJson(session.agent) !== stableJson(input.acceptedExecution.resolvedAgentConfig ?? null) || session.maxNestedAgentDepthOverride !== (task.agentConfig.maxNestedAgentDepth ?? null) || (session.variableSetId ?? null) !== (input.acceptedExecution.resolvedVariableSet?.id ?? null) || (session.rigId ?? null) !== (input.acceptedExecution.resolvedRig?.id ?? null) || (session.rigVersionId ?? null) !== (input.acceptedExecution.resolvedRig?.versionId ?? null) || scheduledSlackBotConnectionId(session.metadata) !== (frozenSlack?.id ?? null)) {
|
|
6937
7301
|
throw new ScheduledRunTerminalAuthorityError(
|
|
6938
7302
|
"scheduled_generated_session_changed",
|
|
6939
7303
|
"scheduled generated session differs from accepted execution"
|
|
@@ -7072,6 +7436,9 @@ async function recoverBoundScheduledTaskDispatch(input) {
|
|
|
7072
7436
|
if (scheduledUpdate.reason === "session_cancelled" || scheduledUpdate.reason === "session_not_idle") {
|
|
7073
7437
|
return { action: "blocked", reason: "scheduled_run_terminal" };
|
|
7074
7438
|
}
|
|
7439
|
+
if (scheduledUpdate.added) {
|
|
7440
|
+
recordUserMessageAccepted(input.observability, { surface: "scheduled" });
|
|
7441
|
+
}
|
|
7075
7442
|
if (scheduledUpdate.added && scheduledUpdate.events.length > 0) {
|
|
7076
7443
|
await publishDurableSessionEvents(
|
|
7077
7444
|
input.bus,
|
|
@@ -7327,6 +7694,7 @@ async function dispatchMaintenanceSession(service, maintenance, dependencies) {
|
|
|
7327
7694
|
initialMessage: maintenancePrompt(maintenance),
|
|
7328
7695
|
// OpenGeni's own periodic check: no human or product surface entered it.
|
|
7329
7696
|
surface: "system",
|
|
7697
|
+
metrics: service.observability,
|
|
7330
7698
|
resources: [],
|
|
7331
7699
|
tools: [{ kind: "mcp", id: "opengeni" }],
|
|
7332
7700
|
toolPolicy: { mode: "explicit", inheritedFromSessionId: null },
|
|
@@ -7998,6 +8366,7 @@ function createControlActivitiesFromServices(services, resolveDocumentServices)
|
|
|
7998
8366
|
...createCodexCapacityActivities(services),
|
|
7999
8367
|
...createRigVerificationActivities(services),
|
|
8000
8368
|
...createBrowserStateArtifactMaintenanceActivities(services),
|
|
8369
|
+
...createBrowserDeadlineCheckpointActivities(services),
|
|
8001
8370
|
...createFileUploadReaperActivities(services),
|
|
8002
8371
|
...createRetainedScreenshotMaintenanceActivities(services),
|
|
8003
8372
|
...createWorkflowWakeActivities(services),
|
|
@@ -8019,4 +8388,4 @@ export {
|
|
|
8019
8388
|
createControlActivities,
|
|
8020
8389
|
createControlActivitiesFromServices
|
|
8021
8390
|
};
|
|
8022
|
-
//# sourceMappingURL=activities-control-
|
|
8391
|
+
//# sourceMappingURL=activities-control-4F2A734B.js.map
|