@opengeni/core 0.21.10 → 0.24.1

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.
Files changed (116) hide show
  1. package/dist/access/index.d.ts +1 -1
  2. package/dist/application/new-session-drafts.d.ts +1 -1
  3. package/dist/application/session-commands.d.ts +2 -2
  4. package/dist/billing/limits.d.ts +1 -1
  5. package/dist/chunk-6WKPWE5S.js +2380 -0
  6. package/dist/chunk-6WKPWE5S.js.map +1 -0
  7. package/dist/chunk-JJU6I5XD.js +2713 -0
  8. package/dist/chunk-JJU6I5XD.js.map +1 -0
  9. package/dist/chunk-NYPMQ7NO.js +2270 -0
  10. package/dist/chunk-NYPMQ7NO.js.map +1 -0
  11. package/dist/dependencies.d.ts +26 -6
  12. package/dist/domain/capabilities.d.ts +28 -3
  13. package/dist/domain/company-profile-durable-learning-adapter.d.ts +39 -0
  14. package/dist/domain/durable-learning-slack-publication.d.ts +72 -0
  15. package/dist/domain/editable-artifacts/agent-application.d.ts +192 -0
  16. package/dist/domain/editable-artifacts/durable-export-postgres.d.ts +4 -0
  17. package/dist/domain/editable-artifacts/durable-export.d.ts +212 -0
  18. package/dist/domain/editable-artifacts/errors.d.ts +47 -0
  19. package/dist/domain/editable-artifacts/hash.d.ts +11 -0
  20. package/dist/domain/editable-artifacts/in-memory.d.ts +99 -0
  21. package/dist/domain/editable-artifacts/index.d.ts +14 -0
  22. package/dist/domain/editable-artifacts/ports.d.ts +341 -0
  23. package/dist/domain/editable-artifacts/postgres-adapters.d.ts +13 -0
  24. package/dist/domain/editable-artifacts/service.d.ts +105 -0
  25. package/dist/domain/editable-artifacts/snapshot-compaction.d.ts +44 -0
  26. package/dist/domain/editable-artifacts/snapshot-verifier-genesis.d.ts +50 -0
  27. package/dist/domain/editable-artifacts/snapshot-verifier-materialization.d.ts +21 -0
  28. package/dist/domain/editable-artifacts/snapshot-verifier.d.ts +118 -0
  29. package/dist/domain/editable-artifacts/types.d.ts +410 -0
  30. package/dist/domain/memory-slack-delivery.d.ts +19 -0
  31. package/dist/domain/packs.d.ts +29 -1
  32. package/dist/domain/personal-connection-delegations.d.ts +9 -1
  33. package/dist/domain/scheduled-tasks.d.ts +2 -2
  34. package/dist/domain/session-tool-policy.d.ts +2 -2
  35. package/dist/domain/sessions.d.ts +14 -6
  36. package/dist/domain/skill-imports.d.ts +32 -0
  37. package/dist/domain/slack-publication-secret-safety.d.ts +8 -0
  38. package/dist/domain/timeline-annotations.d.ts +5 -0
  39. package/dist/domain/video-generation-capabilities.d.ts +9 -0
  40. package/dist/domain/video-generation.d.ts +47 -0
  41. package/dist/editable-artifact-live/application.d.ts +69 -0
  42. package/dist/editable-artifact-live/errors.d.ts +1 -0
  43. package/dist/editable-artifact-live/index.d.ts +8 -0
  44. package/dist/editable-artifact-live/outbox-dispatcher.d.ts +162 -0
  45. package/dist/editable-artifact-live/ports.d.ts +100 -0
  46. package/dist/editable-artifact-live/server.d.ts +71 -0
  47. package/dist/editable-artifact-live/ticket.d.ts +40 -0
  48. package/dist/editable-artifact-live/types.d.ts +213 -0
  49. package/dist/editable-artifact-live/wire.d.ts +34 -0
  50. package/dist/editable-artifact-live.d.ts +2 -0
  51. package/dist/editable-artifact-live.js +58 -0
  52. package/dist/editable-artifact-live.js.map +1 -0
  53. package/dist/editable-artifacts.d.ts +2 -0
  54. package/dist/editable-artifacts.js +179 -0
  55. package/dist/editable-artifacts.js.map +1 -0
  56. package/dist/index.d.ts +35 -26
  57. package/dist/index.js +2792 -609
  58. package/dist/index.js.map +1 -1
  59. package/dist/managed-session.d.ts +1 -1
  60. package/dist/rigs/index.d.ts +1 -1
  61. package/dist/rigs/provider-images.d.ts +31 -0
  62. package/dist/sandbox/routing.d.ts +1 -0
  63. package/dist/session-authorization.d.ts +1 -1
  64. package/dist/workflow-wake-contract.d.ts +7 -0
  65. package/package.json +18 -10
  66. package/src/application/new-session-drafts.ts +2 -0
  67. package/src/application/session-commands.ts +188 -107
  68. package/src/dependencies.ts +30 -2
  69. package/src/domain/capabilities.ts +604 -220
  70. package/src/domain/company-profile-durable-learning-adapter.ts +221 -0
  71. package/src/domain/durable-learning-slack-publication.ts +202 -0
  72. package/src/domain/editable-artifacts/agent-application.ts +687 -0
  73. package/src/domain/editable-artifacts/durable-export-postgres.ts +139 -0
  74. package/src/domain/editable-artifacts/durable-export.ts +734 -0
  75. package/src/domain/editable-artifacts/errors.ts +115 -0
  76. package/src/domain/editable-artifacts/hash.ts +131 -0
  77. package/src/domain/editable-artifacts/in-memory.ts +1662 -0
  78. package/src/domain/editable-artifacts/index.ts +14 -0
  79. package/src/domain/editable-artifacts/ports.ts +462 -0
  80. package/src/domain/editable-artifacts/postgres-adapters.ts +49 -0
  81. package/src/domain/editable-artifacts/service.ts +2402 -0
  82. package/src/domain/editable-artifacts/snapshot-compaction.ts +246 -0
  83. package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +235 -0
  84. package/src/domain/editable-artifacts/snapshot-verifier-materialization.ts +74 -0
  85. package/src/domain/editable-artifacts/snapshot-verifier.ts +687 -0
  86. package/src/domain/editable-artifacts/types.ts +835 -0
  87. package/src/domain/insights.ts +136 -33
  88. package/src/domain/memory-slack-delivery.ts +204 -0
  89. package/src/domain/memory-slack-publication.ts +5 -2
  90. package/src/domain/packs.ts +266 -5
  91. package/src/domain/personal-connection-delegations.ts +97 -6
  92. package/src/domain/scheduled-tasks.ts +155 -29
  93. package/src/domain/session-tool-policy.ts +8 -2
  94. package/src/domain/sessions.ts +274 -131
  95. package/src/domain/skill-imports.ts +350 -0
  96. package/src/domain/slack-publication-secret-safety.ts +42 -0
  97. package/src/domain/timeline-annotations.ts +204 -0
  98. package/src/domain/video-generation-capabilities.ts +69 -0
  99. package/src/domain/video-generation.ts +249 -0
  100. package/src/editable-artifact-live/application.ts +182 -0
  101. package/src/editable-artifact-live/errors.ts +4 -0
  102. package/src/editable-artifact-live/index.ts +8 -0
  103. package/src/editable-artifact-live/outbox-dispatcher.ts +916 -0
  104. package/src/editable-artifact-live/ports.ts +139 -0
  105. package/src/editable-artifact-live/server.ts +1707 -0
  106. package/src/editable-artifact-live/ticket.ts +217 -0
  107. package/src/editable-artifact-live/types.ts +286 -0
  108. package/src/editable-artifact-live/wire.ts +95 -0
  109. package/src/editable-artifact-live.ts +2 -0
  110. package/src/editable-artifacts.ts +2 -0
  111. package/src/index.ts +13 -0
  112. package/src/rigs/index.ts +26 -19
  113. package/src/rigs/provider-images.ts +110 -0
  114. package/src/sandbox/routing.ts +6 -3
  115. package/src/session-authorization.ts +3 -0
  116. package/src/workflow-wake-contract.ts +8 -0
package/src/rigs/index.ts CHANGED
@@ -36,6 +36,9 @@ import {
36
36
  type Database,
37
37
  } from "@opengeni/db";
38
38
  import { HTTPException } from "hono/http-exception";
39
+ import { rigProviderImagesFromVerification } from "./provider-images";
40
+
41
+ export * from "./provider-images";
39
42
 
40
43
  export const MAX_RIGS_PER_WORKSPACE = 50;
41
44
  export const MAX_CHECKS_PER_RIG = 100;
@@ -352,6 +355,13 @@ export async function promoteSetupAppendChange(
352
355
  if (typeof payload.command !== "string" || !payload.command.trim()) {
353
356
  throw new HTTPException(422, { message: "setup_append change is missing command" });
354
357
  }
358
+ const nextDefinition = {
359
+ image: base.image,
360
+ setupScript: appendRigSetupCommand(base.setupScript, payload.command),
361
+ checks: base.checks,
362
+ credentialHooks: base.credentialHooks,
363
+ defaultVariableSetIds: base.defaultVariableSetIds,
364
+ };
355
365
  const { version, change: updated } = await promoteChangeWithActiveCas(
356
366
  deps,
357
367
  grant.workspaceId,
@@ -359,16 +369,13 @@ export async function promoteSetupAppendChange(
359
369
  change.id,
360
370
  {
361
371
  expectedActiveVersionId: change.baseVersionId,
362
- image: base.image,
363
- setupScript: appendRigSetupCommand(base.setupScript, payload.command),
364
- checks: base.checks,
365
- credentialHooks: base.credentialHooks,
366
- defaultVariableSetIds: base.defaultVariableSetIds,
372
+ ...nextDefinition,
367
373
  changelog:
368
374
  typeof payload.note === "string" && payload.note.trim()
369
375
  ? payload.note
370
376
  : "Verified setup append",
371
377
  createdBy: change.proposedBy ?? rigActorForGrant(grant),
378
+ providerImages: rigProviderImagesFromVerification(change.verification, nextDefinition),
372
379
  },
373
380
  );
374
381
  await recordRigAuditEvent(deps.db, {
@@ -418,6 +425,18 @@ export async function promoteVerifiedDefinitionEditChangeForApi(
418
425
  defaultVariableSetIds?: unknown;
419
426
  changelog?: unknown;
420
427
  };
428
+ const nextDefinition = {
429
+ image: payload.image === undefined ? base.image : (payload.image as string | null),
430
+ setupScript:
431
+ payload.setupScript === undefined ? base.setupScript : (payload.setupScript as string | null),
432
+ checks: Array.isArray(payload.checks) ? (payload.checks as RigVersion["checks"]) : base.checks,
433
+ credentialHooks: Array.isArray(payload.credentialHooks)
434
+ ? (payload.credentialHooks as string[])
435
+ : base.credentialHooks,
436
+ defaultVariableSetIds: Array.isArray(payload.defaultVariableSetIds)
437
+ ? (payload.defaultVariableSetIds as string[])
438
+ : base.defaultVariableSetIds,
439
+ };
421
440
  const { version, change: updated } = await promoteChangeWithActiveCas(
422
441
  deps,
423
442
  grant.workspaceId,
@@ -425,25 +444,13 @@ export async function promoteVerifiedDefinitionEditChangeForApi(
425
444
  change.id,
426
445
  {
427
446
  expectedActiveVersionId: change.baseVersionId,
428
- image: payload.image === undefined ? base.image : (payload.image as string | null),
429
- setupScript:
430
- payload.setupScript === undefined
431
- ? base.setupScript
432
- : (payload.setupScript as string | null),
433
- checks: Array.isArray(payload.checks)
434
- ? (payload.checks as RigVersion["checks"])
435
- : base.checks,
436
- credentialHooks: Array.isArray(payload.credentialHooks)
437
- ? (payload.credentialHooks as string[])
438
- : base.credentialHooks,
439
- defaultVariableSetIds: Array.isArray(payload.defaultVariableSetIds)
440
- ? (payload.defaultVariableSetIds as string[])
441
- : base.defaultVariableSetIds,
447
+ ...nextDefinition,
442
448
  changelog:
443
449
  typeof payload.changelog === "string" && payload.changelog.trim()
444
450
  ? payload.changelog
445
451
  : "Verified definition edit",
446
452
  createdBy: rigActorForGrant(grant),
453
+ providerImages: rigProviderImagesFromVerification(change.verification, nextDefinition),
447
454
  },
448
455
  );
449
456
  await recordRigAuditEvent(deps.db, {
@@ -0,0 +1,110 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ RigProviderImage as RigProviderImageContract,
4
+ stableJson,
5
+ type RigChangeVerification,
6
+ type RigProviderImage,
7
+ type RigProviderImages,
8
+ type RigVersion,
9
+ type SandboxBackend,
10
+ } from "@opengeni/contracts";
11
+
12
+ export type RigProviderImageDefinition = Pick<
13
+ RigVersion,
14
+ "image" | "setupScript" | "checks" | "credentialHooks" | "defaultVariableSetIds"
15
+ >;
16
+
17
+ function sha256(value: string): string {
18
+ return `sha256:${createHash("sha256").update(value, "utf8").digest("hex")}`;
19
+ }
20
+
21
+ export function rigProviderImageProviderBindingKeyHash(bindingKey: string): string {
22
+ return sha256(bindingKey);
23
+ }
24
+
25
+ export function rigProviderImageSetupHash(
26
+ definition: Pick<RigProviderImageDefinition, "setupScript">,
27
+ ): string {
28
+ return sha256(definition.setupScript ?? "");
29
+ }
30
+
31
+ /**
32
+ * Hash every exact rig-definition input that can affect whether a provider
33
+ * image may be reused. Credential values and variable-set contents are
34
+ * intentionally absent: verification never injects them into the build box.
35
+ * Their declared hook/set identities still participate so a new rig version
36
+ * cannot silently inherit an older build record.
37
+ */
38
+ export function rigProviderImageContentHash(input: {
39
+ backend: SandboxBackend;
40
+ sourceImage: string | null;
41
+ definition: RigProviderImageDefinition;
42
+ }): string {
43
+ return sha256(
44
+ stableJson({
45
+ version: 1,
46
+ backend: input.backend,
47
+ sourceImage: input.sourceImage,
48
+ image: input.definition.image,
49
+ setupScript: input.definition.setupScript,
50
+ checks: input.definition.checks,
51
+ credentialHooks: input.definition.credentialHooks,
52
+ defaultVariableSetIds: input.definition.defaultVariableSetIds,
53
+ }),
54
+ );
55
+ }
56
+
57
+ /** Modal's patched snapshot API accepts a caller-owned UUID idempotency key.
58
+ * v2 denotes images proven by a separate cold boot before publication. */
59
+ export function rigProviderImageBuildRequestId(input: {
60
+ targetId: string;
61
+ backend: SandboxBackend;
62
+ contentHash: string;
63
+ }): string {
64
+ const bytes = createHash("sha256")
65
+ .update("opengeni-rig-provider-image-build-v2\0", "utf8")
66
+ .update(input.targetId, "utf8")
67
+ .update("\0", "utf8")
68
+ .update(input.backend, "utf8")
69
+ .update("\0", "utf8")
70
+ .update(input.contentHash, "utf8")
71
+ .digest()
72
+ .subarray(0, 16);
73
+ // RFC 4122 variant + deterministic version-5-shaped UUID. The digest, not a
74
+ // provider response, is the idempotency identity.
75
+ bytes[6] = (bytes[6]! & 0x0f) | 0x50;
76
+ bytes[8] = (bytes[8]! & 0x3f) | 0x80;
77
+ const hex = bytes.toString("hex");
78
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
79
+ }
80
+
81
+ export function rigProviderImageMatchesDefinition(
82
+ image: RigProviderImage,
83
+ definition: RigProviderImageDefinition,
84
+ ): boolean {
85
+ return (
86
+ image.setupHash === rigProviderImageSetupHash(definition) &&
87
+ image.contentHash ===
88
+ rigProviderImageContentHash({
89
+ backend: image.backend,
90
+ sourceImage: image.sourceImage,
91
+ definition,
92
+ })
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Promotion copies only a finalized, structurally valid build record whose
98
+ * hashes match the exact version definition being inserted. A malformed or
99
+ * stale optimization record is discarded; the version remains correct and
100
+ * falls back to runtime setup.
101
+ */
102
+ export function rigProviderImagesFromVerification(
103
+ verification: RigChangeVerification | null,
104
+ definition: RigProviderImageDefinition,
105
+ ): RigProviderImages {
106
+ const parsed = RigProviderImageContract.safeParse(verification?.providerImage);
107
+ if (!parsed.success || parsed.data.status === "building") return {};
108
+ if (!rigProviderImageMatchesDefinition(parsed.data, definition)) return {};
109
+ return { [parsed.data.backend]: parsed.data };
110
+ }
@@ -11,7 +11,7 @@
11
11
  // The DB-coupled glue (readActiveSandbox / getSandbox / the selfhosted ControlRpc
12
12
  // over the events bus) lives here, not in the leaf (which stays db-free).
13
13
 
14
- import { sandboxArchiveCaptureTimeoutMs, type Settings } from "@opengeni/config";
14
+ import { sandboxLifecycleTransitionWaitMs, type Settings } from "@opengeni/config";
15
15
  import {
16
16
  advanceWorkspaceGenerationForDirectRequest,
17
17
  advanceWorkspaceGenerationForRetainedProcess,
@@ -61,6 +61,7 @@ export type ChannelARoutingServices = {
61
61
  settings: Settings;
62
62
  bus?: EventBus;
63
63
  onSandboxOperation?: RoutingSandboxOperationObserver;
64
+ waitSignal?: AbortSignal;
64
65
  };
65
66
 
66
67
  /** Map the deployment relay URL to the leaf's `SelfhostedRelayConfig` shape. The
@@ -214,7 +215,8 @@ export function wrapChannelABoxWithRouting(
214
215
  routeTargetId: backend.sandboxId,
215
216
  routeEpoch: backend.activeEpoch,
216
217
  operation: op,
217
- captureWaitMs: sandboxArchiveCaptureTimeoutMs(settings),
218
+ captureWaitMs: sandboxLifecycleTransitionWaitMs(settings),
219
+ ...(services.waitSignal ? { waitSignal: services.waitSignal } : {}),
218
220
  });
219
221
  return { admission, providerBinding };
220
222
  }
@@ -310,7 +312,8 @@ export function wrapChannelABoxWithRouting(
310
312
  sessionId: ids.sessionId,
311
313
  processId: process.id,
312
314
  operation: op,
313
- captureWaitMs: sandboxArchiveCaptureTimeoutMs(settings),
315
+ captureWaitMs: sandboxLifecycleTransitionWaitMs(settings),
316
+ ...(services.waitSignal ? { waitSignal: services.waitSignal } : {}),
314
317
  })
315
318
  : undefined;
316
319
  const afterProcessMutation = homeLease
@@ -238,5 +238,8 @@ async function resolveSessionAuthorizationActor(
238
238
  executionGeneration,
239
239
  initiator: turn.initiator,
240
240
  initiatorContext: turn.initiatorContext,
241
+ initiatingHumanSubjectId:
242
+ turn.initiatingHumanSubjectId ??
243
+ (turn.initiator.kind === "subject" ? turn.initiator.subjectId : null),
241
244
  });
242
245
  }
@@ -4,3 +4,11 @@ export const SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID =
4
4
  export const SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_TYPE =
5
5
  "sessionWorkflowWakeDispatcherWorkflow";
6
6
  export const SESSION_WORKFLOW_WAKE_DISPATCHER_PERIOD_MS = 10_000;
7
+
8
+ /**
9
+ * Temporal delivers activity cancellation through heartbeats. Keep both the
10
+ * activity's local heartbeat timer and the worker's SDK throttle at this bound
11
+ * so the end-to-end Pause/Steer physical-cancellation contract is not already
12
+ * exhausted before sandbox/tool quiescence and replacement admission begin.
13
+ */
14
+ export const TURN_ACTIVITY_CANCELLATION_HEARTBEAT_INTERVAL_MS = 500;