@opengeni/core 2.5.3 → 2.6.3-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/access/index.d.ts +24 -0
- package/dist/canonical-human-identities.js +2 -2
- package/dist/{chunk-ZVZJTMSV.js → chunk-OF65T3PM.js} +2 -2
- package/dist/{chunk-YGOMUGYS.js → chunk-QO5GVFFO.js} +17 -8
- package/dist/{chunk-YGOMUGYS.js.map → chunk-QO5GVFFO.js.map} +1 -1
- package/dist/domain/company-brain-governed-writes.d.ts +15 -6
- package/dist/domain/company-profile-agent-admin.d.ts +3 -2
- package/dist/domain/environments.d.ts +1 -1
- package/dist/domain/memory-slack-delivery.d.ts +4 -1
- package/dist/domain/personal-connection-delegations.d.ts +1 -0
- package/dist/domain/pr-review.d.ts +1 -1
- package/dist/domain/scheduled-tasks.d.ts +12 -0
- package/dist/domain/sessions.d.ts +14 -1
- package/dist/domain/workspace-members.d.ts +8 -1
- package/dist/index.js +686 -380
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-sets.d.ts +18 -0
- package/dist/managed-auth-session-sets.js +3 -1
- package/dist/sandbox/fleet.d.ts +6 -4
- package/dist/sandbox/routing.d.ts +7 -2
- package/dist/sandbox/runtime-settings.d.ts +17 -1
- package/package.json +10 -10
- package/src/access/index.ts +140 -5
- package/src/application/user-resource-grants.ts +31 -2
- package/src/billing/limits.ts +5 -2
- package/src/domain/company-brain-governed-writes.ts +29 -13
- package/src/domain/company-profile-agent-admin.ts +3 -2
- package/src/domain/environments.ts +6 -34
- package/src/domain/memory-slack-delivery.ts +30 -0
- package/src/domain/personal-connection-delegations.ts +40 -7
- package/src/domain/remember.ts +5 -6
- package/src/domain/scheduled-tasks.ts +94 -0
- package/src/domain/sessions.ts +117 -9
- package/src/domain/workspace-members.ts +34 -2
- package/src/managed-auth-session-sets.ts +38 -11
- package/src/sandbox/fleet.ts +20 -17
- package/src/sandbox/routing.ts +18 -4
- package/src/sandbox/runtime-settings.ts +32 -0
- /package/dist/{chunk-ZVZJTMSV.js.map → chunk-OF65T3PM.js.map} +0 -0
package/src/sandbox/fleet.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// apps/api/src/sandbox/fleet.ts — the FLEET service backing the fleet MCP tools
|
|
2
2
|
// (M7): list / attach / swap / run_on / provision over the heterogeneous fleet
|
|
3
|
-
// (the session's
|
|
3
|
+
// (the session's managed group box + the workspace's enrolled selfhosted machines).
|
|
4
4
|
//
|
|
5
5
|
// Each operation is workspace-scoped (the caller's grant) and, for the
|
|
6
6
|
// session-pointer mutations (attach/swap), session-scoped (the worker-signed
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// single op WITHOUT touching the active pointer.
|
|
13
13
|
|
|
14
14
|
import type { Settings } from "@opengeni/config";
|
|
15
|
+
import type { SandboxBackend } from "@opengeni/contracts";
|
|
15
16
|
import {
|
|
16
17
|
authorizePersonalMachineForAttempt,
|
|
17
18
|
getEnrollment,
|
|
@@ -45,6 +46,7 @@ import {
|
|
|
45
46
|
type SelfhostedOperationResourcePolicy,
|
|
46
47
|
} from "@opengeni/runtime/sandbox";
|
|
47
48
|
import { relayConfigFromSettings } from "./routing";
|
|
49
|
+
import { managedSessionGroupBackend } from "./runtime-settings";
|
|
48
50
|
|
|
49
51
|
export type FleetServices = {
|
|
50
52
|
db: Database;
|
|
@@ -74,8 +76,8 @@ export type FleetContext = {
|
|
|
74
76
|
/** The calling session (the pointer the attach/swap mutates + whose group box
|
|
75
77
|
* is the default fleet member). */
|
|
76
78
|
sessionId: string;
|
|
77
|
-
/** The session's
|
|
78
|
-
sessionBackend:
|
|
79
|
+
/** The session's durable home-compute policy. */
|
|
80
|
+
sessionBackend: SandboxBackend;
|
|
79
81
|
/** The session's own group sandbox id (the lease group). */
|
|
80
82
|
sessionGroupId: string;
|
|
81
83
|
};
|
|
@@ -264,8 +266,9 @@ async function probeEnrollment(
|
|
|
264
266
|
* List the fleet: the session's own group box when it has one (a synthetic
|
|
265
267
|
* entry) + the workspace's first-class selfhosted sandboxes (each probed for
|
|
266
268
|
* liveness), each with an `active` marker derived from the session's active
|
|
267
|
-
* pointer. A backend:none session
|
|
268
|
-
*
|
|
269
|
+
* pointer. A backend:none session and a machine-home session on a deployment
|
|
270
|
+
* without a managed provider have no synthetic group entry; a null pointer then
|
|
271
|
+
* means no compute is attached.
|
|
269
272
|
*/
|
|
270
273
|
export async function listFleet(
|
|
271
274
|
services: FleetServices,
|
|
@@ -285,8 +288,12 @@ export async function listFleet(
|
|
|
285
288
|
};
|
|
286
289
|
|
|
287
290
|
const entries: FleetSandboxEntry[] = [];
|
|
291
|
+
const groupBackend = managedSessionGroupBackend(
|
|
292
|
+
services.settings.sandboxBackend,
|
|
293
|
+
ctx.sessionBackend,
|
|
294
|
+
);
|
|
288
295
|
|
|
289
|
-
if (
|
|
296
|
+
if (groupBackend) {
|
|
290
297
|
// The session's own group box (the default/home sandbox; null active pointer ==
|
|
291
298
|
// this box). A session/group row is not provider existence. Online requires a
|
|
292
299
|
// warm lease, observed provider existence, and verified workspace readiness.
|
|
@@ -317,17 +324,10 @@ export async function listFleet(
|
|
|
317
324
|
? "unavailable"
|
|
318
325
|
: groupRecovering
|
|
319
326
|
? "recovering"
|
|
320
|
-
:
|
|
321
|
-
? "unavailable"
|
|
322
|
-
: "wakeable";
|
|
327
|
+
: "wakeable";
|
|
323
328
|
entries.push({
|
|
324
329
|
id: ctx.sessionGroupId,
|
|
325
|
-
kind:
|
|
326
|
-
ctx.sessionBackend === "selfhosted"
|
|
327
|
-
? "selfhosted"
|
|
328
|
-
: ctx.sessionBackend === "opensandbox"
|
|
329
|
-
? "opensandbox"
|
|
330
|
-
: "modal",
|
|
330
|
+
kind: groupBackend === "opensandbox" ? "opensandbox" : "modal",
|
|
331
331
|
name: "session sandbox",
|
|
332
332
|
liveness: groupOnline ? "online" : groupRecovering ? "reconnecting" : "offline",
|
|
333
333
|
active: groupActive,
|
|
@@ -467,10 +467,13 @@ async function resolveTarget(
|
|
|
467
467
|
> {
|
|
468
468
|
// The session's own group box → the default pointer (null).
|
|
469
469
|
if (target === ctx.sessionGroupId || target === "session" || target === "default") {
|
|
470
|
-
if (ctx.sessionBackend
|
|
470
|
+
if (!managedSessionGroupBackend(services.settings.sandboxBackend, ctx.sessionBackend)) {
|
|
471
471
|
return {
|
|
472
472
|
ok: false,
|
|
473
|
-
reason:
|
|
473
|
+
reason:
|
|
474
|
+
ctx.sessionBackend === "none"
|
|
475
|
+
? "this session has no home sandbox; attach a Connected Machine"
|
|
476
|
+
: "this deployment has no managed session sandbox; select an enrolled machine",
|
|
474
477
|
code: "unsupported_backend_context",
|
|
475
478
|
};
|
|
476
479
|
}
|
package/src/sandbox/routing.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
verifyDirectWorkspaceMutationSettlement,
|
|
27
27
|
verifyRetainedProcessMutationSettlement,
|
|
28
28
|
type Database,
|
|
29
|
+
type SandboxRetainedProcess,
|
|
29
30
|
type SandboxWorkspaceMutationAdmission,
|
|
30
31
|
} from "@opengeni/db";
|
|
31
32
|
import { settleSessionBackgroundCommandForRetainedProcess } from "@opengeni/db/session-background-commands";
|
|
@@ -86,6 +87,20 @@ export function directRetainedProcessMatchesBackend(
|
|
|
86
87
|
);
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
export function retainedProcessBackgroundSettlement(
|
|
91
|
+
process: Pick<SandboxRetainedProcess, "state" | "exitCode" | "settlementReason">,
|
|
92
|
+
fallback: RoutingRetainedProcessTerminalProof,
|
|
93
|
+
): { outcome: "exited" | "lost"; exitCode: number | null; reason: string } {
|
|
94
|
+
if (process.state === "active") {
|
|
95
|
+
throw new Error("Retained-process settlement returned an active durable process");
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
outcome: process.state,
|
|
99
|
+
exitCode: process.exitCode,
|
|
100
|
+
reason: process.settlementReason ?? fallback.reason,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
89
104
|
export type ChannelARoutingServices = {
|
|
90
105
|
db: Database;
|
|
91
106
|
settings: Settings;
|
|
@@ -423,7 +438,7 @@ export function wrapChannelABoxWithRouting(
|
|
|
423
438
|
"API retained-process settlement lost its exact durable backend identity",
|
|
424
439
|
);
|
|
425
440
|
}
|
|
426
|
-
await settleRetainedProcess(db, {
|
|
441
|
+
const settlement = await settleRetainedProcess(db, {
|
|
427
442
|
accountId: ids.accountId,
|
|
428
443
|
workspaceId: ids.workspaceId,
|
|
429
444
|
sessionId: ids.sessionId,
|
|
@@ -434,14 +449,13 @@ export function wrapChannelABoxWithRouting(
|
|
|
434
449
|
reason: proof.reason,
|
|
435
450
|
idleGraceMs: settings.sandboxIdleGraceMs,
|
|
436
451
|
});
|
|
452
|
+
const backgroundSettlement = retainedProcessBackgroundSettlement(settlement.process, proof);
|
|
437
453
|
await settleSessionBackgroundCommandForRetainedProcess(db, {
|
|
438
454
|
accountId: ids.accountId,
|
|
439
455
|
workspaceId: ids.workspaceId,
|
|
440
456
|
sessionId: ids.sessionId,
|
|
441
457
|
retainedProcessId: process.id,
|
|
442
|
-
|
|
443
|
-
exitCode: proof.exitCode,
|
|
444
|
-
reason: proof.reason,
|
|
458
|
+
...backgroundSettlement,
|
|
445
459
|
});
|
|
446
460
|
}
|
|
447
461
|
: undefined;
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type RigVersion,
|
|
5
5
|
type Session,
|
|
6
6
|
type SandboxBackend,
|
|
7
|
+
type SandboxOs,
|
|
7
8
|
} from "@opengeni/contracts";
|
|
8
9
|
import {
|
|
9
10
|
getRigVersion,
|
|
@@ -18,6 +19,37 @@ import {
|
|
|
18
19
|
rigProviderImageProviderBindingKeyHash,
|
|
19
20
|
} from "../rigs/provider-images";
|
|
20
21
|
|
|
22
|
+
export type ManagedSessionGroupBackend = Exclude<SandboxBackend, "none" | "selfhosted">;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the provider backend behind a session's synthetic managed group.
|
|
26
|
+
*
|
|
27
|
+
* A machine-home session keeps `selfhosted` as its durable policy while a
|
|
28
|
+
* non-null active pointer selects the enrolled machine. Clearing that pointer
|
|
29
|
+
* is an explicit switch to the deployment's managed group, so API readiness,
|
|
30
|
+
* viewer attachment, Channel-A, and worker turns must all select the same
|
|
31
|
+
* provider. Deployments configured with `none` or `selfhosted` have no managed
|
|
32
|
+
* fallback to expose.
|
|
33
|
+
*/
|
|
34
|
+
export function managedSessionGroupBackend(
|
|
35
|
+
deploymentBackend: SandboxBackend,
|
|
36
|
+
sessionBackend: SandboxBackend,
|
|
37
|
+
): ManagedSessionGroupBackend | null {
|
|
38
|
+
if (sessionBackend === "none") return null;
|
|
39
|
+
const backend = sessionBackend === "selfhosted" ? deploymentBackend : sessionBackend;
|
|
40
|
+
return backend === "none" || backend === "selfhosted" ? null : backend;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** A machine-home row carries the machine's host OS; its managed group uses the
|
|
44
|
+
* platform's canonical managed-sandbox OS instead. Ordinary sessions preserve
|
|
45
|
+
* their explicitly selected OS. */
|
|
46
|
+
export function managedSessionGroupOs(
|
|
47
|
+
sessionBackend: SandboxBackend,
|
|
48
|
+
sessionOs: SandboxOs,
|
|
49
|
+
): SandboxOs {
|
|
50
|
+
return sessionBackend === "selfhosted" ? "linux" : sessionOs;
|
|
51
|
+
}
|
|
52
|
+
|
|
21
53
|
/** Pre-V2 Packs are the sole compatibility path where a Pack can still own a
|
|
22
54
|
* sandbox image. V2 installations select a Rig instead. Keep this predicate at
|
|
23
55
|
* the shared runtime boundary so turns, API-direct tools, viewers, Browser and
|
|
File without changes
|