@opengeni/worker-bundle 1.0.1 → 2.0.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.
Files changed (122) hide show
  1. package/dist/activities/agent-turn/codex.d.ts +1 -1
  2. package/dist/activities/agent-turn/compaction-prep.d.ts +1 -5
  3. package/dist/activities/agent-turn/errors.d.ts +31 -5
  4. package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
  5. package/dist/activities/agent-turn/finalization.d.ts +1 -1
  6. package/dist/activities/agent-turn/governance-model.d.ts +0 -2
  7. package/dist/activities/agent-turn/quiescence.d.ts +1 -0
  8. package/dist/activities/agent-turn/recovery-warning.d.ts +8 -0
  9. package/dist/activities/agent-turn/run-credentials.d.ts +0 -1
  10. package/dist/activities/agent-turn/sandbox-establish.d.ts +1 -1
  11. package/dist/activities/agent-turn/sandbox-route.d.ts +0 -20
  12. package/dist/activities/agent-turn/sandbox-runtime.d.ts +1 -1
  13. package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
  14. package/dist/activities/agent-turn/skill-search.d.ts +1 -1
  15. package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
  16. package/dist/activities/agent-turn/tool-environment.d.ts +0 -4
  17. package/dist/activities/agent-turn/turn-context.d.ts +2 -0
  18. package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
  19. package/dist/activities/codex-capacity.d.ts +6 -1
  20. package/dist/activities/codex-rotation.d.ts +1 -1
  21. package/dist/activities/context-compaction.d.ts +7 -1
  22. package/dist/activities/mcp-account-routes.d.ts +22 -0
  23. package/dist/activities/mcp-credentials.d.ts +12 -13
  24. package/dist/activities/mcp-operation-authority.d.ts +0 -5
  25. package/dist/activities/rig-verification.d.ts +2 -3
  26. package/dist/activities/sandbox-images.d.ts +1 -1
  27. package/dist/activities/sandbox-lease.d.ts +4 -3
  28. package/dist/activities/session-state.d.ts +57 -2
  29. package/dist/activities/types.d.ts +12 -3
  30. package/dist/{activities-control-HMFGSKC5.js → activities-control-BOLIY3H4.js} +366 -187
  31. package/dist/activities-control-BOLIY3H4.js.map +1 -0
  32. package/dist/activities-control.d.ts +110 -2
  33. package/dist/{activities-turn-AP67JADS.js → activities-turn-2B3WMHBB.js} +767 -471
  34. package/dist/activities-turn-2B3WMHBB.js.map +1 -0
  35. package/dist/activities.d.ts +110 -2
  36. package/dist/artifact-materializer-entry.js +5 -2
  37. package/dist/artifact-materializer-entry.js.map +1 -1
  38. package/dist/artifact-outbox-entry.js +2 -2
  39. package/dist/artifact-outbox-entry.js.map +1 -1
  40. package/dist/{chunk-A4XQWVZK.js → chunk-I7HKKMUJ.js} +77 -1
  41. package/dist/chunk-I7HKKMUJ.js.map +1 -0
  42. package/dist/{chunk-CYITU5UH.js → chunk-TVEE2UUC.js} +275 -146
  43. package/dist/chunk-TVEE2UUC.js.map +1 -0
  44. package/dist/editable-artifact-materializer-service.d.ts +2 -2
  45. package/dist/editable-artifact-outbox-service.d.ts +2 -2
  46. package/dist/index.d.ts +55 -1
  47. package/dist/index.js +4 -3
  48. package/dist/index.js.map +1 -1
  49. package/dist/observability-metrics.d.ts +11 -3
  50. package/dist/retained-process-diagnostics.d.ts +4 -0
  51. package/dist/sandbox-resume.d.ts +2 -12
  52. package/dist/sandbox-routing.d.ts +5 -3
  53. package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
  54. package/dist/warm-capture-holder.d.ts +3 -0
  55. package/dist/workflow-bundle.js +51 -11
  56. package/package.json +15 -15
  57. package/src/activities/agent-turn/agent-build.ts +42 -5
  58. package/src/activities/agent-turn/claim.ts +12 -0
  59. package/src/activities/agent-turn/codex-capacity.ts +26 -4
  60. package/src/activities/agent-turn/codex.ts +6 -2
  61. package/src/activities/agent-turn/compaction-prep.ts +53 -72
  62. package/src/activities/agent-turn/errors.ts +98 -10
  63. package/src/activities/agent-turn/failure-settlement.ts +49 -28
  64. package/src/activities/agent-turn/finalization-monitor.ts +121 -0
  65. package/src/activities/agent-turn/finalization.ts +79 -21
  66. package/src/activities/agent-turn/governance-model.ts +15 -19
  67. package/src/activities/agent-turn/history.ts +24 -10
  68. package/src/activities/agent-turn/quiescence.ts +3 -0
  69. package/src/activities/agent-turn/recovery-warning.ts +18 -0
  70. package/src/activities/agent-turn/run-credentials.ts +3 -7
  71. package/src/activities/agent-turn/run.ts +68 -52
  72. package/src/activities/agent-turn/sandbox-establish.ts +10 -2
  73. package/src/activities/agent-turn/sandbox-route.ts +0 -20
  74. package/src/activities/agent-turn/sandbox-runtime.ts +40 -7
  75. package/src/activities/agent-turn/skill-remove.ts +46 -0
  76. package/src/activities/agent-turn/skill-save.ts +1 -1
  77. package/src/activities/agent-turn/skill-search.ts +1 -1
  78. package/src/activities/agent-turn/skill-selection.ts +2 -0
  79. package/src/activities/agent-turn/skill-tools.ts +10 -5
  80. package/src/activities/agent-turn/stream-attempt.ts +38 -15
  81. package/src/activities/agent-turn/tool-environment.ts +44 -29
  82. package/src/activities/agent-turn/turn-context.ts +3 -0
  83. package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
  84. package/src/activities/capabilities.ts +17 -2
  85. package/src/activities/codex-capacity.ts +38 -9
  86. package/src/activities/codex-rotation.ts +18 -5
  87. package/src/activities/context-compaction.ts +26 -4
  88. package/src/activities/goals.ts +1 -0
  89. package/src/activities/google-drive-publication.ts +1 -3
  90. package/src/activities/mcp-account-routes.ts +139 -0
  91. package/src/activities/mcp-credentials.ts +83 -194
  92. package/src/activities/mcp-operation-authority.ts +16 -41
  93. package/src/activities/parent-wake.ts +8 -0
  94. package/src/activities/rig-verification.ts +38 -37
  95. package/src/activities/run-input.ts +25 -16
  96. package/src/activities/sandbox-images.ts +0 -1
  97. package/src/activities/sandbox-lease.ts +177 -44
  98. package/src/activities/scheduled-tasks.ts +118 -93
  99. package/src/activities/session-state.ts +83 -3
  100. package/src/activities/types.ts +18 -2
  101. package/src/activities/workflow-wake.ts +2 -17
  102. package/src/editable-artifact-materializer-service.ts +7 -3
  103. package/src/editable-artifact-outbox-service.ts +4 -4
  104. package/src/github-rest-mcp.ts +0 -1
  105. package/src/index.ts +2 -1
  106. package/src/observability-metrics.ts +105 -2
  107. package/src/personal-github-git-credentials.ts +0 -1
  108. package/src/pr-review-credentials.ts +0 -2
  109. package/src/retained-process-diagnostics.ts +50 -0
  110. package/src/sandbox-resume.ts +58 -73
  111. package/src/sandbox-routing.ts +44 -19
  112. package/src/sandbox-snapshot-diagnostics.ts +112 -0
  113. package/src/warm-capture-holder.ts +15 -0
  114. package/src/workflows/session.ts +64 -2
  115. package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
  116. package/dist/activities/packs.d.ts +0 -55
  117. package/dist/activities-control-HMFGSKC5.js.map +0 -1
  118. package/dist/activities-turn-AP67JADS.js.map +0 -1
  119. package/dist/chunk-A4XQWVZK.js.map +0 -1
  120. package/dist/chunk-CYITU5UH.js.map +0 -1
  121. package/src/activities/agent-turn/knowledge-sources.ts +0 -86
  122. package/src/activities/packs.ts +0 -166
@@ -0,0 +1,112 @@
1
+ import { sandboxLeaseTelemetryKey, type Observability } from "@opengeni/observability";
2
+
3
+ type SafeSnapshotError = {
4
+ errorClass: "SnapshotOperationError";
5
+ errorCode: "snapshot_operation_failed";
6
+ status?: number;
7
+ origin: "sandbox-resume" | "worker-lifecycle";
8
+ causeName?: string;
9
+ integrityCode?: string;
10
+ providerErrorName?: string;
11
+ providerGrpcCode?: number;
12
+ providerHttpStatus?: number;
13
+ providerRetryable?: boolean;
14
+ };
15
+
16
+ export function safeSnapshotError(
17
+ error: unknown,
18
+ origin: SafeSnapshotError["origin"] = "sandbox-resume",
19
+ ): SafeSnapshotError {
20
+ const fields: SafeSnapshotError = {
21
+ errorClass: "SnapshotOperationError",
22
+ errorCode: "snapshot_operation_failed",
23
+ origin,
24
+ };
25
+ try {
26
+ if (error && typeof error === "object") {
27
+ const candidate = error as {
28
+ name?: unknown;
29
+ code?: unknown;
30
+ status?: unknown;
31
+ statusCode?: unknown;
32
+ };
33
+ if (
34
+ typeof candidate.name === "string" &&
35
+ /^[A-Z][A-Za-z0-9]{2,62}Error$/u.test(candidate.name)
36
+ ) {
37
+ fields.causeName = candidate.name;
38
+ }
39
+ if (typeof candidate.code === "string" && /^[a-z0-9_]{1,64}$/u.test(candidate.code)) {
40
+ fields.integrityCode = candidate.code;
41
+ }
42
+ const status = Number(candidate.status ?? candidate.statusCode);
43
+ if (Number.isInteger(status) && status >= 100 && status <= 599) fields.status = status;
44
+ }
45
+ } catch {
46
+ // Diagnostics must never replace the exact internal snapshot failure.
47
+ }
48
+ // The SDK wraps provider classification in details, not Error.cause. Never
49
+ // project free-form messages, causes, request IDs or payloads. Read fields
50
+ // independently so a hostile getter cannot hide other safe classifications.
51
+ const read = (value: unknown, key: string): unknown => {
52
+ try {
53
+ return value && typeof value === "object" ? Reflect.get(value, key) : undefined;
54
+ } catch {
55
+ return undefined;
56
+ }
57
+ };
58
+ const details = read(error, "details");
59
+ const providerName = read(details, "errorName");
60
+ if (
61
+ typeof providerName === "string" &&
62
+ [
63
+ "ClientError",
64
+ "TimeoutError",
65
+ "ConnectionError",
66
+ "AuthError",
67
+ "NotFoundError",
68
+ "InvalidError",
69
+ "RemoteError",
70
+ "AbortError",
71
+ ].includes(providerName)
72
+ )
73
+ fields.providerErrorName = providerName;
74
+ const grpcCode = read(details, "errorCode");
75
+ if (
76
+ providerName === "ClientError" &&
77
+ typeof grpcCode === "number" &&
78
+ Number.isInteger(grpcCode) &&
79
+ grpcCode >= 0 &&
80
+ grpcCode <= 16
81
+ )
82
+ fields.providerGrpcCode = grpcCode;
83
+ for (const key of ["status", "httpStatus", "responseStatus"]) {
84
+ const status = read(details, key);
85
+ if (typeof status === "number" && Number.isInteger(status) && status >= 100 && status <= 599) {
86
+ fields.providerHttpStatus = status;
87
+ break;
88
+ }
89
+ }
90
+ const retryable = read(error, "retryable");
91
+ if (typeof retryable === "boolean") fields.providerRetryable = retryable;
92
+ return fields;
93
+ }
94
+
95
+ export function warnDrainSnapshotFailure(
96
+ observability: Pick<Observability, "warn">,
97
+ message: string,
98
+ error: unknown,
99
+ lease: { workspaceId?: string; sandboxGroupId: string; leaseEpoch: number },
100
+ ): void {
101
+ try {
102
+ observability.warn(message, {
103
+ ...safeSnapshotError(error, "worker-lifecycle"),
104
+ ...(lease.workspaceId
105
+ ? { sandboxLeaseKey: sandboxLeaseTelemetryKey(lease.workspaceId, lease.sandboxGroupId) }
106
+ : {}),
107
+ leaseEpoch: lease.leaseEpoch,
108
+ });
109
+ } catch {
110
+ // Logging cannot replace the provider failure or prevent claim release.
111
+ }
112
+ }
@@ -0,0 +1,15 @@
1
+ import type { LeaseSnapshot } from "@opengeni/db";
2
+
3
+ /** Physical capture retention is not permission to heartbeat or execute a closed turn. */
4
+ export function retainsHolderForWarmCapture(
5
+ lease: Pick<LeaseSnapshot, "liveness" | "leaseEpoch" | "archiveCapture"> | null,
6
+ expectedEpoch: number,
7
+ now = Date.now(),
8
+ ): boolean {
9
+ return Boolean(
10
+ lease?.liveness === "warm" &&
11
+ lease.leaseEpoch === expectedEpoch &&
12
+ lease.archiveCapture &&
13
+ lease.archiveCapture.deadlineAt.getTime() > now,
14
+ );
15
+ }
@@ -229,7 +229,15 @@ export function preClaimFailureDetail(error: unknown): PreClaimFailureDetail | u
229
229
  ) {
230
230
  return undefined;
231
231
  }
232
- const detail = cause.details?.[0] as { disposition?: unknown; code?: unknown } | undefined;
232
+ const detail = cause.details?.[0] as
233
+ | {
234
+ disposition?: unknown;
235
+ code?: unknown;
236
+ sqlState?: unknown;
237
+ reason?: unknown;
238
+ retryPolicy?: unknown;
239
+ }
240
+ | undefined;
233
241
  if (
234
242
  detail?.code !== "db_deadlock" &&
235
243
  detail?.code !== "db_serialization_failure" &&
@@ -239,6 +247,27 @@ export function preClaimFailureDetail(error: unknown): PreClaimFailureDetail | u
239
247
  return undefined;
240
248
  }
241
249
  const disposition = detail.disposition;
250
+ if (disposition === "blocked") {
251
+ if (
252
+ detail.code !== "db_failure" ||
253
+ detail.retryPolicy !== "explicit_recheck" ||
254
+ (detail.reason !== "database_claim_rejected" &&
255
+ detail.reason !== "initiator_membership_required" &&
256
+ detail.reason !== "personal_resource_grant_required") ||
257
+ !(
258
+ detail.sqlState === null ||
259
+ (typeof detail.sqlState === "string" && /^[0-9A-Z]{5}$/.test(detail.sqlState))
260
+ )
261
+ )
262
+ return undefined;
263
+ return {
264
+ disposition,
265
+ code: detail.code,
266
+ reason: detail.reason,
267
+ sqlState: detail.sqlState,
268
+ retryPolicy: "explicit_recheck",
269
+ };
270
+ }
242
271
  if (disposition !== "retryable" && disposition !== "permanent") return undefined;
243
272
  if (
244
273
  (detail.code === "db_deadlock" || detail.code === "db_serialization_failure") &&
@@ -351,6 +380,7 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
351
380
  const preserveQuiescenceWake = patched("session-quiescence-reconciliation-wake-v1");
352
381
  const staleControlSignalIsOnlyWakeHint = patched("session-control-stale-wake-v1");
353
382
  const unclaimedAttemptRecovery = patched("session-unclaimed-attempt-recovery-v1");
383
+ let durableAdmissionBlocking = false;
354
384
  // PR #2208 changed a typed-cancelled result from a plain re-peek into a
355
385
  // recoverDispatch activity. Version that new command so histories which
356
386
  // already recorded the legacy re-peek remain deterministic on replay.
@@ -561,10 +591,29 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
561
591
  const closeSignalVersion = signalVersion;
562
592
  const closeNonControlSignalVersion = nonControlSignalVersion;
563
593
  const workflowId = workflowInfo().workflowId;
594
+ // Re-evaluate at the changed command, not only workflow entry. A replay
595
+ // without the marker keeps its old shape; the next live admission cycle
596
+ // can activate this fix without waiting for continueAsNew.
597
+ durableAdmissionBlocking = patched("session-durable-admission-block-v1");
598
+ const safeObservation = patched("session-safe-control-observation-v1");
564
599
  const peek = await activity.peekSessionWork({
565
600
  workspaceId: input.workspaceId,
566
601
  sessionId: input.sessionId,
602
+ ...(durableAdmissionBlocking ? { includeAdmissionFence: true } : {}),
603
+ ...(safeObservation ? { observerAccountId: input.accountId } : {}),
567
604
  });
605
+ if (peek.kind === "unavailable" || peek.kind === "attempt-owned") {
606
+ // No terminal/idle projection and no successor dispatch. Restoration
607
+ // need not produce a wake, so retain the observer with a bounded timer
608
+ // instead of closing and stranding durable work. Signals interrupt the
609
+ // wait; continue-as-new above bounds history, never business execution.
610
+ await condition(() => signalVersion !== closeSignalVersion, "30s");
611
+ continue;
612
+ }
613
+ if (peek.kind === "admission-blocked") {
614
+ if (signalVersion !== closeSignalVersion || pendingQuiescenceProofs.size > 0) continue;
615
+ return;
616
+ }
568
617
  if (peek.kind === "interruption-pending") {
569
618
  const settlement = await activity.settleSessionInterruptions({
570
619
  accountId: input.accountId,
@@ -630,6 +679,7 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
630
679
  const finalPeek = await activity.peekSessionWork({
631
680
  workspaceId: input.workspaceId,
632
681
  sessionId: input.sessionId,
682
+ ...(safeObservation ? { observerAccountId: input.accountId } : {}),
633
683
  });
634
684
  if (
635
685
  finalPeek.kind !== "sandbox-lifecycle-wait" ||
@@ -711,6 +761,7 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
711
761
  const finalPeek = await activity.peekSessionWork({
712
762
  workspaceId: input.workspaceId,
713
763
  sessionId: input.sessionId,
764
+ ...(safeObservation ? { observerAccountId: input.accountId } : {}),
714
765
  });
715
766
  if (
716
767
  finalPeek.kind !== "input-wait" ||
@@ -763,6 +814,7 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
763
814
  const finalPeek = await activity.peekSessionWork({
764
815
  workspaceId: input.workspaceId,
765
816
  sessionId: input.sessionId,
817
+ ...(safeObservation ? { observerAccountId: input.accountId } : {}),
766
818
  });
767
819
  if (finalPeek.kind !== "idle") continue;
768
820
  await activity.markSessionIdle({
@@ -779,7 +831,15 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
779
831
  peek.kind === "approval-pending"
780
832
  ? ({ kind: "approval", triggerEventId: peek.triggerEventId } as const)
781
833
  : ({ kind: "next" } as const);
782
- if (!(await runTurn(input.accountId, input.workspaceId, input.sessionId, trigger))) {
834
+ if (
835
+ !(await runTurn(
836
+ input.accountId,
837
+ input.workspaceId,
838
+ input.sessionId,
839
+ trigger,
840
+ "admissionFence" in peek ? peek.admissionFence : undefined,
841
+ ))
842
+ ) {
783
843
  if (signalVersion !== closeSignalVersion) continue;
784
844
  return;
785
845
  }
@@ -790,6 +850,7 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
790
850
  workspaceId: string,
791
851
  sessionId: string,
792
852
  trigger: activities.RunAgentTurnInput["trigger"],
853
+ admissionFence?: activities.FailSessionAttemptInput["admissionFence"],
793
854
  ): Promise<boolean> {
794
855
  const capacityWaitEntryBaseline = { wakeups, capacityWakeups };
795
856
  // Capture every admission-relevant signal before activity dispatch. A
@@ -1072,6 +1133,7 @@ export async function sessionWorkflow(input: SessionWorkflowInput): Promise<void
1072
1133
  ? { preClaimFailureDisposition: admissionFailureDisposition }
1073
1134
  : {}),
1074
1135
  ...(admissionFailure ? { preClaimFailure: admissionFailure } : {}),
1136
+ ...(durableAdmissionBlocking && admissionFence ? { admissionFence } : {}),
1075
1137
  ...(postClaimDatabaseRecovery ? { postClaimDatabaseRecovery } : {}),
1076
1138
  trigger,
1077
1139
  error: workflowFailureMessage(outcome.error),
@@ -1,20 +0,0 @@
1
- import { type FirstPartyMcpToolName, type Permission, type ResourceRef, type KnowledgeFilePreparationResult } from "@opengeni/contracts";
2
- import { type Settings } from "@opengeni/config";
3
- import { createFirstPartyAttemptClient } from "@opengeni/runtime";
4
- export type KnowledgeSourcePreparationOutcome = KnowledgeFilePreparationResult | {
5
- status: "failed";
6
- fileId: string;
7
- message: string;
8
- };
9
- /** Accepted chat/schedule resources use ordinary agent authority and policy. */
10
- export declare function prepareTurnKnowledgeSources(input: {
11
- settings: Settings;
12
- scope: Parameters<typeof createFirstPartyAttemptClient>[0]["scope"];
13
- resources: readonly ResourceRef[];
14
- selectedTools?: readonly FirstPartyMcpToolName[] | undefined;
15
- permissions?: readonly Permission[] | null | undefined;
16
- learningMode: "automatic" | "review_first" | "off";
17
- signal?: AbortSignal | undefined;
18
- onOutcome: (outcome: KnowledgeSourcePreparationOutcome) => Promise<void>;
19
- prepare?: (fileId: string) => Promise<KnowledgeFilePreparationResult>;
20
- }): Promise<string | undefined>;
@@ -1,55 +0,0 @@
1
- import { CapabilityPack } from "@opengeni/contracts";
2
- import { type Database } from "@opengeni/db";
3
- import { packInstallationUsesLegacyRuntime } from "@opengeni/core";
4
- import { type InstalledSkillActivation, type PackSkillActivation } from "@opengeni/runtime";
5
- export { resolveRigProviderImageSelection, rigProviderImageSourceImage, settingsWithPackSandboxImage, settingsWithRigImage, settingsWithRigProviderImage, } from "./sandbox-images.js";
6
- export { packInstallationUsesLegacyRuntime };
7
- /**
8
- * Legacy pack-scoped runtime compatibility. V2 Pack installations own ordinary
9
- * Skill components and select an explicit Rig; they contribute nothing here.
10
- */
11
- export type WorkspacePackRuntime = {
12
- sandboxImage: string | null;
13
- sandboxProviderImages: CapabilityPack["sandboxProviderImages"] | null;
14
- skillActivations: PackSkillActivation[];
15
- };
16
- export type WorkspaceInstalledSkillRuntime = {
17
- activations: InstalledSkillActivation[];
18
- };
19
- /**
20
- * Resolves only pre-V2 active Pack installations. A frozen manifest/digest is
21
- * the protocol marker for V2: inline Skills were migrated into the ordinary
22
- * Skill ledger and sandboxImage was resolved to selectedRigId during install,
23
- * so reading either field directly here would duplicate ownership and silently
24
- * override session compute.
25
- */
26
- export declare function resolveWorkspacePackRuntime(db: Database, workspaceId: string): Promise<WorkspacePackRuntime>;
27
- /**
28
- * Resolves every active immutable Skill through the normalized Plugin/Skill-
29
- * Facet ledger. The data layer has already filtered ineffective owner edges;
30
- * this boundary independently verifies exact files before runtime activation.
31
- */
32
- export declare function resolveWorkspaceInstalledSkillRuntime(db: Database, workspaceId: string): Promise<WorkspaceInstalledSkillRuntime>;
33
- /**
34
- * Pure pre-V2 compatibility rule for enabled Pack manifests. At most one
35
- * legacy Pack may declare a sandbox image, and legacy Skill names must be
36
- * unique. V2 rows never reach this function through runtime resolution.
37
- */
38
- export declare function workspacePackRuntimeFromPacks(packs: CapabilityPack[]): WorkspacePackRuntime;
39
- /**
40
- * Resolves the per-workspace agent persona override (the white-label surface).
41
- * Returns the workspace's stored template when set, else null to mean "use the
42
- * deployment default" (settings.agentInstructionsTemplate). The runtime always
43
- * injects the non-bypassable CORE regardless, so a null here keeps the
44
- * byte-identical default and a non-null value only restyles the persona.
45
- *
46
- * This is the workspace tier of the session > workspace > deployment-default
47
- * resolution; per-session overrides do not exist in this slice, so the worker
48
- * resolves workspace > default and passes the result as instructionsTemplate.
49
- */
50
- export declare function resolveWorkspaceAgentInstructions(db: Database, workspaceId: string): Promise<string | null>;
51
- /**
52
- * Applies a pack-declared sandbox image to run settings. With no pack image
53
- * the settings pass through untouched, so deployments without packs keep the
54
- * global OPENGENI_DOCKER_IMAGE / OPENGENI_MODAL_IMAGE_REF behavior exactly.
55
- */