@opengeni/worker-bundle 1.0.2-canary.37191796234001 → 1.0.2
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-turn/quiescence.d.ts +3 -3
- package/dist/activities/agent-turn/sandbox-runtime.d.ts +1 -1
- package/dist/activities/agent-turn/stream-attempt.d.ts +1 -1
- package/dist/activities/mcp-account-routes.d.ts +2 -21
- package/dist/activities/sandbox-lease.d.ts +5 -1
- package/dist/{activities-control-7UP475T4.js → activities-control-BNPTRTOE.js} +137 -8
- package/dist/activities-control-BNPTRTOE.js.map +1 -0
- package/dist/{activities-turn-FTJTSIVC.js → activities-turn-5LGZOSVU.js} +19 -96
- package/dist/activities-turn-5LGZOSVU.js.map +1 -0
- package/dist/{chunk-ZEKFFMAY.js → chunk-LJX7Z2KP.js} +28 -11
- package/dist/chunk-LJX7Z2KP.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +21 -21
- package/src/activities/agent-turn/admission.ts +2 -2
- package/src/activities/agent-turn/codex-plan-entitlement.ts +3 -3
- package/src/activities/agent-turn/errors.ts +2 -2
- package/src/activities/agent-turn/failure-settlement.ts +1 -1
- package/src/activities/agent-turn/model-usage.ts +1 -1
- package/src/activities/agent-turn/quiescence.ts +4 -3
- package/src/activities/agent-turn/sandbox-runtime.ts +3 -2
- package/src/activities/agent-turn/skill-install.ts +1 -1
- package/src/activities/agent-turn/stream-attempt.ts +11 -1
- package/src/activities/goals.ts +2 -2
- package/src/activities/image-generation-operation.ts +1 -1
- package/src/activities/mcp-account-routes.ts +2 -124
- package/src/activities/sandbox-lease.ts +158 -3
- package/src/activities/scheduled-tasks.ts +3 -3
- package/src/github-rest-mcp.ts +1 -1
- package/src/pr-review-credentials.ts +1 -1
- package/src/sandbox-routing.ts +18 -1
- package/dist/activities-control-7UP475T4.js.map +0 -1
- package/dist/activities-turn-FTJTSIVC.js.map +0 -1
- package/dist/chunk-ZEKFFMAY.js.map +0 -1
|
@@ -175,7 +175,7 @@ export declare class MandatoryHistoryPersistenceError extends Error {
|
|
|
175
175
|
}
|
|
176
176
|
export declare function runMandatoryHistoryPersistenceStep<T>(stage: MandatoryHistoryPersistenceStage, operation: () => Promise<T>): Promise<T>;
|
|
177
177
|
export type OpStreamFinalizer = {
|
|
178
|
-
finalizeOpStreamOps(): Promise<void>;
|
|
178
|
+
finalizeOpStreamOps(toolCallIds?: readonly string[]): Promise<void>;
|
|
179
179
|
};
|
|
180
|
-
/** Release
|
|
181
|
-
export declare function finalizeDurableTurnOpStreams(sessions: readonly unknown[], fallback: OpStreamFinalizer | null): Promise<void>;
|
|
180
|
+
/** Release only durably recorded tool results, or the complete durable turn. */
|
|
181
|
+
export declare function finalizeDurableTurnOpStreams(sessions: readonly unknown[], fallback: OpStreamFinalizer | null, toolCallIds?: readonly string[]): Promise<void>;
|
|
@@ -36,7 +36,7 @@ export declare function preemptSandboxTurnForDeadlineRotation(input: {
|
|
|
36
36
|
export declare function createSandboxTurnRuntime(deps: SandboxTurnRuntimeDeps): {
|
|
37
37
|
releaseLateSandbox: (sandbox: ResumedTurnSandbox) => Promise<void>;
|
|
38
38
|
requireResolvedSandboxForMutation: (message: string) => ResumedTurnSandbox;
|
|
39
|
-
finalizeTurnOpStreamOps: () => Promise<void>;
|
|
39
|
+
finalizeTurnOpStreamOps: (toolCallIds?: readonly string[]) => Promise<void>;
|
|
40
40
|
onHomeSandboxRebound: (rebound: {
|
|
41
41
|
established: EstablishedSandboxSession;
|
|
42
42
|
leaseEpoch: number;
|
|
@@ -49,7 +49,7 @@ export type TurnStreamAttemptDeps = {
|
|
|
49
49
|
toolResultSpill: ToolResultSpill;
|
|
50
50
|
claimedResult: ClaimedResult;
|
|
51
51
|
flushRuntimeBatcher: () => Promise<void>;
|
|
52
|
-
finalizeTurnOpStreamOps: () => Promise<void>;
|
|
52
|
+
finalizeTurnOpStreamOps: (toolCallIds?: readonly string[]) => Promise<void>;
|
|
53
53
|
runWorkspaceMutationForSandbox: <T>(sandbox: ResumedTurnSandbox, operation: string, mutation: () => Promise<T>, observePhase?: (measurement: {
|
|
54
54
|
phase: "admission" | "provider" | "settlement" | "snapshot_wait";
|
|
55
55
|
outcome: "completed" | "failed";
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { McpConnectionAccountBinding, ToolRef, ToolAuthNeededPayload } from "@opengeni/contracts";
|
|
3
|
-
import type { ApiIntegrationRuntime } from "@opengeni/db";
|
|
1
|
+
import type { McpConnectionAccountBinding, ToolAuthNeededPayload } from "@opengeni/contracts";
|
|
4
2
|
export declare function accountRouteAuthNeededPayload(payload: ToolAuthNeededPayload, bindings: readonly McpConnectionAccountBinding[] | null | undefined): ToolAuthNeededPayload;
|
|
5
|
-
|
|
6
|
-
* identities, never an alternate way to gain admission to a connector. */
|
|
7
|
-
export declare function expandMcpAccountRoutes(input: {
|
|
8
|
-
settings: Settings;
|
|
9
|
-
tools: ToolRef[];
|
|
10
|
-
bindings: readonly McpConnectionAccountBinding[] | null | undefined;
|
|
11
|
-
}): {
|
|
12
|
-
settings: Settings;
|
|
13
|
-
tools: ToolRef[];
|
|
14
|
-
accountLabels: ReadonlyMap<string, string>;
|
|
15
|
-
};
|
|
16
|
-
/** Each adapter closes over its own immutable credential ref and authority
|
|
17
|
-
* generation. Sharing a provider transport never shares a credential resolver. */
|
|
18
|
-
export declare function expandApiIntegrationAccountRoutes(input: {
|
|
19
|
-
integrations: readonly ApiIntegrationRuntime[];
|
|
20
|
-
bindings: readonly McpConnectionAccountBinding[] | null | undefined;
|
|
21
|
-
tools: readonly ToolRef[];
|
|
22
|
-
}): ApiIntegrationRuntime[];
|
|
3
|
+
export { expandMcpAccountRoutes, expandApiIntegrationAccountRoutes } from "@opengeni/core";
|
|
@@ -171,7 +171,11 @@ export declare function createSandboxLeaseActivities(services: () => Promise<Act
|
|
|
171
171
|
* adoption. A successor enrollment connection is intentionally irrelevant: no
|
|
172
172
|
* query or cancellation is ever rebound to it. */
|
|
173
173
|
export declare function reconcileConnectedMachineBackgroundCommands(db: ActivityServices["db"], settings: ActivityServices["settings"], observability: ActivityServices["observability"], bus: ActivityServices["bus"], controlRpcOverride?: ControlRpc): Promise<void>;
|
|
174
|
-
export declare function replayConnectedCommandOutput(client: Pick<OpStreamExecClient, "readExisting">, opId: string, terminalKnown: boolean, capture: Parameters<OpStreamExecClient["readExisting"]>[2]): Promise<
|
|
174
|
+
export declare function replayConnectedCommandOutput(client: Pick<OpStreamExecClient, "readExisting">, opId: string, terminalKnown: boolean, capture: Parameters<OpStreamExecClient["readExisting"]>[2]): Promise<Awaited<ReturnType<OpStreamExecClient["readExisting"]>>>;
|
|
175
|
+
/** Drain the durable terminal-output obligation independently of the launching
|
|
176
|
+
* attempt or model completion notice. Existing terminal rows receive no inferred
|
|
177
|
+
* receipt: they must replay and capture all retained bytes before any final ACK. */
|
|
178
|
+
export declare function reconcileConnectedCommandOutputReleases(db: ActivityServices["db"], settings: ActivityServices["settings"], observability: ActivityServices["observability"], bus: ActivityServices["bus"], controlRpcOverride?: ControlRpc): Promise<void>;
|
|
175
179
|
export declare function probeConnectedMachineBackgroundCommand(claim: ConnectedMachineBackgroundCommandClaim, controlRpc: ControlRpc, controlTimeoutMs: number, observedAt?: Date): Promise<ConnectedMachineBackgroundCommandProof | null>;
|
|
176
180
|
export declare function connectedCommandProofFromStatus(status: OpStatus, observedAt: Date): ConnectedMachineBackgroundCommandProof | null;
|
|
177
181
|
type RetainedProcessDeferralOutcome = Extract<RetainedProcessProbeResult, {
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
warnDrainSnapshotFailure,
|
|
36
36
|
withFirstPartyTools,
|
|
37
37
|
workflowIdForSession
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-LJX7Z2KP.js";
|
|
39
39
|
import {
|
|
40
40
|
inspectOpenSandboxKubernetesInventory,
|
|
41
41
|
recordActiveUserGauges,
|
|
@@ -2810,9 +2810,12 @@ import {
|
|
|
2810
2810
|
settleRetainedProcess
|
|
2811
2811
|
} from "@opengeni/db";
|
|
2812
2812
|
import {
|
|
2813
|
+
claimConnectedCommandOutputReleases,
|
|
2813
2814
|
claimConnectedMachineSessionBackgroundCommands,
|
|
2814
2815
|
deferConnectedMachineBackgroundCommandReconciliation,
|
|
2815
|
-
recordConnectedMachineBackgroundCommandProof
|
|
2816
|
+
recordConnectedMachineBackgroundCommandProof,
|
|
2817
|
+
recordConnectedCommandOutputConsumption,
|
|
2818
|
+
settleConnectedCommandOutputReleaseClaim
|
|
2816
2819
|
} from "@opengeni/db/session-background-commands";
|
|
2817
2820
|
import { sandboxWarmRateMicrosPerSecond } from "@opengeni/config";
|
|
2818
2821
|
import { appendSessionCommandOutput } from "@opengeni/db/session-command-output";
|
|
@@ -3137,6 +3140,7 @@ function createSandboxLeaseActivities(services, options = {}) {
|
|
|
3137
3140
|
const rotationsRequested = input.rotationsRequested;
|
|
3138
3141
|
let modalOrphansTerminated = 0;
|
|
3139
3142
|
await reconcileConnectedMachineBackgroundCommands(db, settings, observability, service.bus);
|
|
3143
|
+
await reconcileConnectedCommandOutputReleases(db, settings, observability, service.bus);
|
|
3140
3144
|
try {
|
|
3141
3145
|
await reconcileModalProviderCreates(
|
|
3142
3146
|
db,
|
|
@@ -3458,6 +3462,7 @@ async function reconcileConnectedMachineBackgroundCommands(db, settings, observa
|
|
|
3458
3462
|
);
|
|
3459
3463
|
await forEachWithConcurrency(claims, SANDBOX_MAINTENANCE_ITEM_CONCURRENCY, async (claim) => {
|
|
3460
3464
|
let proof = claim.proof;
|
|
3465
|
+
let outputReplay = null;
|
|
3461
3466
|
const connectionKey = JSON.stringify([
|
|
3462
3467
|
claim.controlWorkspaceId,
|
|
3463
3468
|
claim.enrollmentId,
|
|
@@ -3513,7 +3518,7 @@ async function reconcileConnectedMachineBackgroundCommands(db, settings, observa
|
|
|
3513
3518
|
journal: { attachGeneration: () => String(Date.now()), persistSettled: () => {
|
|
3514
3519
|
} }
|
|
3515
3520
|
});
|
|
3516
|
-
await replayConnectedCommandOutput(
|
|
3521
|
+
outputReplay = await replayConnectedCommandOutput(
|
|
3517
3522
|
client,
|
|
3518
3523
|
claim.opId,
|
|
3519
3524
|
Boolean(proof),
|
|
@@ -3571,6 +3576,15 @@ async function reconcileConnectedMachineBackgroundCommands(db, settings, observa
|
|
|
3571
3576
|
if (!settlement.settled) {
|
|
3572
3577
|
throw new Error("Connected command settlement lost its exact claim or proof");
|
|
3573
3578
|
}
|
|
3579
|
+
const receipt = outputReplay?.outputReceipt ?? (outputReplay?.status === "running" ? outputReplay.terminal?.outputReceipt : void 0);
|
|
3580
|
+
const terminal = outputReplay?.status === "completed" ? outputReplay : outputReplay?.terminal;
|
|
3581
|
+
if (proof.outcome === "exited" && receipt && terminal) {
|
|
3582
|
+
await recordConnectedCommandOutputConsumption(db, {
|
|
3583
|
+
...claim,
|
|
3584
|
+
receipt,
|
|
3585
|
+
exitCode: terminal.outcome.response.exitCode
|
|
3586
|
+
});
|
|
3587
|
+
}
|
|
3574
3588
|
if (settlement.events.length > 0) {
|
|
3575
3589
|
try {
|
|
3576
3590
|
await bus.publish(claim.workspaceId, claim.sessionId, settlement.events);
|
|
@@ -3599,13 +3613,128 @@ async function replayConnectedCommandOutput(client, opId, terminalKnown, capture
|
|
|
3599
3613
|
while (true) {
|
|
3600
3614
|
const before = capturedThrough;
|
|
3601
3615
|
const replay = await client.readExisting(opId, terminalKnown ? 5e3 : 250, capture);
|
|
3602
|
-
if (!terminalKnown || replay.status === "completed" || replay.terminal) return;
|
|
3616
|
+
if (!terminalKnown || replay.status === "completed" || replay.terminal) return replay;
|
|
3603
3617
|
capturedThrough = BigInt(replay.replaySequence);
|
|
3604
3618
|
if (capturedThrough === before) {
|
|
3605
3619
|
throw new Error("Connected command terminal output replay has not reached its exit frontier");
|
|
3606
3620
|
}
|
|
3607
3621
|
}
|
|
3608
3622
|
}
|
|
3623
|
+
async function reconcileConnectedCommandOutputReleases(db, settings, observability, bus, controlRpcOverride) {
|
|
3624
|
+
const dueBefore = /* @__PURE__ */ new Date();
|
|
3625
|
+
const deadline = Date.now() + settings.sandboxLeaseReaperPeriodMs;
|
|
3626
|
+
const controlRpc = controlRpcOverride ?? new NatsControlRpc(async () => bus.getRequestConnection());
|
|
3627
|
+
do {
|
|
3628
|
+
let claims;
|
|
3629
|
+
try {
|
|
3630
|
+
claims = await claimConnectedCommandOutputReleases(db, {
|
|
3631
|
+
claimId: crypto.randomUUID(),
|
|
3632
|
+
dueBefore,
|
|
3633
|
+
limit: CONNECTED_COMMAND_RECONCILIATION_LIMIT,
|
|
3634
|
+
claimTtlMs: CONNECTED_COMMAND_RECONCILIATION_CLAIM_TTL_MS
|
|
3635
|
+
});
|
|
3636
|
+
} catch (error) {
|
|
3637
|
+
recordConnectedCommandReconciliation(observability, "claim_failed");
|
|
3638
|
+
observability.warn("sandbox reaper: connected-command output claim failed", {
|
|
3639
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3640
|
+
});
|
|
3641
|
+
return;
|
|
3642
|
+
}
|
|
3643
|
+
await forEachWithConcurrency(claims, SANDBOX_MAINTENANCE_ITEM_CONCURRENCY, async (claim) => {
|
|
3644
|
+
try {
|
|
3645
|
+
if (!bus.getOpStreamConnection)
|
|
3646
|
+
throw new Error("Connected command output transport unavailable");
|
|
3647
|
+
const rpcSubject = subjectFor(
|
|
3648
|
+
claim.controlWorkspaceId,
|
|
3649
|
+
claim.enrollmentId,
|
|
3650
|
+
claim.connectionInstanceId
|
|
3651
|
+
);
|
|
3652
|
+
const controlTimeoutMs = Math.min(
|
|
3653
|
+
settings.sandboxSelfhostedControlTimeoutMs,
|
|
3654
|
+
RETAINED_PROCESS_PROVIDER_PROBE_TIMEOUT_MS
|
|
3655
|
+
);
|
|
3656
|
+
const client = new OpStreamExecClient({
|
|
3657
|
+
workspaceId: claim.controlWorkspaceId,
|
|
3658
|
+
agentId: claim.enrollmentId,
|
|
3659
|
+
connectionInstanceId: claim.connectionInstanceId,
|
|
3660
|
+
epoch: 0,
|
|
3661
|
+
controlRpc,
|
|
3662
|
+
rpcSubject,
|
|
3663
|
+
transport: new NatsOpStreamTransport(async () => bus.getOpStreamConnection?.() ?? null),
|
|
3664
|
+
controlTimeoutMs,
|
|
3665
|
+
retryClock: defaultSelfhostedRetryClock,
|
|
3666
|
+
journal: {
|
|
3667
|
+
attachGeneration: () => String(Date.now()),
|
|
3668
|
+
persistSettled: () => {
|
|
3669
|
+
throw new Error("Background output release requires its database receipt");
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
});
|
|
3673
|
+
let receipt = claim.receipt;
|
|
3674
|
+
if (!receipt) {
|
|
3675
|
+
const status = await querySelfhostedOp({
|
|
3676
|
+
controlRpc,
|
|
3677
|
+
rpcSubject,
|
|
3678
|
+
opId: claim.opId,
|
|
3679
|
+
controlTimeoutMs
|
|
3680
|
+
});
|
|
3681
|
+
if (status.state === OpState.OP_STATE_LOST) {
|
|
3682
|
+
if (!await settleConnectedCommandOutputReleaseClaim(db, {
|
|
3683
|
+
claim,
|
|
3684
|
+
outcome: "unavailable",
|
|
3685
|
+
retryAfterMs: 0
|
|
3686
|
+
}))
|
|
3687
|
+
throw new Error("Connected command output loss no longer owns its exact claim");
|
|
3688
|
+
recordConnectedCommandReconciliation(observability, "output_unavailable");
|
|
3689
|
+
return;
|
|
3690
|
+
}
|
|
3691
|
+
if (status.state !== OpState.OP_STATE_COMPLETE)
|
|
3692
|
+
throw new Error("Terminal command output returned a live operation");
|
|
3693
|
+
const replay = await replayConnectedCommandOutput(
|
|
3694
|
+
client,
|
|
3695
|
+
claim.opId,
|
|
3696
|
+
true,
|
|
3697
|
+
async (frames) => captureConnectedCommandOutput(db, claim, bus)(claim.commandId, frames)
|
|
3698
|
+
);
|
|
3699
|
+
const terminal = replay.status === "completed" ? replay : replay.terminal;
|
|
3700
|
+
receipt = replay.outputReceipt ?? (replay.status === "running" ? replay.terminal?.outputReceipt : void 0) ?? null;
|
|
3701
|
+
if (!terminal || !receipt)
|
|
3702
|
+
throw new Error("Connected command output replay has no complete custody receipt");
|
|
3703
|
+
await recordConnectedCommandOutputConsumption(db, {
|
|
3704
|
+
...claim,
|
|
3705
|
+
receipt,
|
|
3706
|
+
exitCode: terminal.outcome.response.exitCode
|
|
3707
|
+
});
|
|
3708
|
+
}
|
|
3709
|
+
const outcome = await client.releaseCapturedOutput(claim.opId, receipt);
|
|
3710
|
+
if (!await settleConnectedCommandOutputReleaseClaim(db, {
|
|
3711
|
+
claim,
|
|
3712
|
+
outcome,
|
|
3713
|
+
retryAfterMs: outcome === "published" ? settings.sandboxLeaseReaperPeriodMs : 0
|
|
3714
|
+
}))
|
|
3715
|
+
throw new Error("Connected command output release no longer owns its exact claim");
|
|
3716
|
+
recordConnectedCommandReconciliation(
|
|
3717
|
+
observability,
|
|
3718
|
+
outcome === "published" ? "output_ack_published" : "output_released"
|
|
3719
|
+
);
|
|
3720
|
+
} catch (error) {
|
|
3721
|
+
await settleConnectedCommandOutputReleaseClaim(db, {
|
|
3722
|
+
claim,
|
|
3723
|
+
outcome: "retry",
|
|
3724
|
+
retryAfterMs: Math.min(
|
|
3725
|
+
5 * 6e4,
|
|
3726
|
+
Math.max(settings.sandboxLeaseReaperPeriodMs, 3e4) * 2 ** Math.min(4, claim.reconcileAttempts - 1)
|
|
3727
|
+
)
|
|
3728
|
+
}).catch(() => false);
|
|
3729
|
+
observability.warn("sandbox reaper: connected-command output release deferred", {
|
|
3730
|
+
commandId: claim.commandId,
|
|
3731
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3732
|
+
});
|
|
3733
|
+
}
|
|
3734
|
+
});
|
|
3735
|
+
if (claims.length < CONNECTED_COMMAND_RECONCILIATION_LIMIT) break;
|
|
3736
|
+
} while (Date.now() < deadline);
|
|
3737
|
+
}
|
|
3609
3738
|
async function probeConnectedMachineBackgroundCommand(claim, controlRpc, controlTimeoutMs, observedAt = /* @__PURE__ */ new Date()) {
|
|
3610
3739
|
const input = {
|
|
3611
3740
|
controlRpc,
|
|
@@ -6142,7 +6271,7 @@ function createScheduledTaskActivities(services) {
|
|
|
6142
6271
|
) : null;
|
|
6143
6272
|
const slackBotMetadata = slackBotConnection ? openGeniSlackBotMetadata(slackBotConnection.metadata) : null;
|
|
6144
6273
|
if (slackBotConnection && !slackBotMetadata) {
|
|
6145
|
-
throw new Error("
|
|
6274
|
+
throw new Error("Opengeni Slack bot connection metadata is invalid");
|
|
6146
6275
|
}
|
|
6147
6276
|
const xaiAuthoritySubjectId = taskXaiProviderAccountAuthoritySnapshot.scope === "user" && task.createdBy.kind === "subject" ? task.createdBy.subjectId : null;
|
|
6148
6277
|
if (taskXaiProviderAccountAuthoritySnapshot.scope === "user" && !xaiAuthoritySubjectId) {
|
|
@@ -6575,7 +6704,7 @@ function createScheduledTaskActivities(services) {
|
|
|
6575
6704
|
}
|
|
6576
6705
|
if (scheduledSlackBotConnectionId(session.metadata) !== (task.agentConfig.slackBotConnectionId ?? null)) {
|
|
6577
6706
|
throw new Error(
|
|
6578
|
-
"scheduled alert occurrence
|
|
6707
|
+
"scheduled alert occurrence Opengeni Slack bot binding does not match its canonical session"
|
|
6579
6708
|
);
|
|
6580
6709
|
}
|
|
6581
6710
|
}
|
|
@@ -7037,7 +7166,7 @@ function assertReusableSessionBindingMatches(session, task) {
|
|
|
7037
7166
|
if (scheduledSlackBotConnectionId(session.metadata) !== (task.agentConfig.slackBotConnectionId ?? null)) {
|
|
7038
7167
|
throw new ScheduledRunTerminalAuthorityError(
|
|
7039
7168
|
"scheduled_reusable_binding_changed",
|
|
7040
|
-
"scheduled task
|
|
7169
|
+
"scheduled task Opengeni Slack bot binding does not match its reusable session"
|
|
7041
7170
|
);
|
|
7042
7171
|
}
|
|
7043
7172
|
}
|
|
@@ -8668,4 +8797,4 @@ export {
|
|
|
8668
8797
|
createControlActivities,
|
|
8669
8798
|
createControlActivitiesFromServices
|
|
8670
8799
|
};
|
|
8671
|
-
//# sourceMappingURL=activities-control-
|
|
8800
|
+
//# sourceMappingURL=activities-control-BNPTRTOE.js.map
|