@opengeni/worker-bundle 1.0.0-canary.1 → 1.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 (244) hide show
  1. package/dist/activities/agent-run-admission.d.ts +3 -1
  2. package/dist/activities/agent-turn/admission.d.ts +24 -3
  3. package/dist/activities/agent-turn/agent-build.d.ts +4 -0
  4. package/dist/activities/agent-turn/claude-usage-observer.d.ts +58 -0
  5. package/dist/activities/agent-turn/code-search.d.ts +60 -0
  6. package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
  7. package/dist/activities/agent-turn/codex-plan-entitlement.d.ts +105 -0
  8. package/dist/activities/agent-turn/codex.d.ts +3 -2
  9. package/dist/activities/agent-turn/compaction-prep.d.ts +21 -5
  10. package/dist/activities/agent-turn/credential-leases.d.ts +19 -33
  11. package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
  12. package/dist/activities/agent-turn/errors.d.ts +82 -11
  13. package/dist/activities/agent-turn/failure-settlement.d.ts +6 -3
  14. package/dist/activities/agent-turn/final-reply.d.ts +18 -0
  15. package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
  16. package/dist/activities/agent-turn/finalization.d.ts +4 -2
  17. package/dist/activities/agent-turn/github-repository-bindings.d.ts +2 -0
  18. package/dist/activities/agent-turn/governance-model.d.ts +9 -2
  19. package/dist/activities/agent-turn/history-sink.d.ts +2 -0
  20. package/dist/activities/agent-turn/history.d.ts +2 -0
  21. package/dist/activities/agent-turn/input-wait-reply.d.ts +41 -0
  22. package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
  23. package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
  24. package/dist/activities/agent-turn/model-usage.d.ts +6 -0
  25. package/dist/activities/agent-turn/model-wire-dispatch.d.ts +15 -0
  26. package/dist/activities/agent-turn/optional-repositories.d.ts +59 -0
  27. package/dist/activities/agent-turn/provider-dispatch-barrier.d.ts +12 -1
  28. package/dist/activities/agent-turn/quiescence.d.ts +7 -7
  29. package/dist/activities/agent-turn/recovery-warning.d.ts +9 -0
  30. package/dist/activities/agent-turn/refresh-credentials.d.ts +6 -0
  31. package/dist/activities/agent-turn/run-credentials.d.ts +8 -3
  32. package/dist/activities/agent-turn/sandbox-establish.d.ts +2 -1
  33. package/dist/activities/agent-turn/sandbox-provision.d.ts +3 -1
  34. package/dist/activities/agent-turn/sandbox-route.d.ts +3 -20
  35. package/dist/activities/agent-turn/sandbox-runtime.d.ts +2 -2
  36. package/dist/activities/agent-turn/session-title.d.ts +34 -2
  37. package/dist/activities/agent-turn/skill-checkout.d.ts +25 -6
  38. package/dist/activities/agent-turn/skill-read.d.ts +70 -2
  39. package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
  40. package/dist/activities/agent-turn/skill-search.d.ts +3 -1
  41. package/dist/activities/agent-turn/skill-tools.d.ts +15 -2
  42. package/dist/activities/agent-turn/skill-transfer.d.ts +18 -6
  43. package/dist/activities/agent-turn/stream-attempt.d.ts +7 -3
  44. package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
  45. package/dist/activities/agent-turn/tool-environment.d.ts +56 -6
  46. package/dist/activities/agent-turn/tool-policy.d.ts +43 -0
  47. package/dist/activities/agent-turn/turn-context.d.ts +29 -0
  48. package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
  49. package/dist/activities/agent-turn/xai-capacity.d.ts +2 -1
  50. package/dist/activities/automations.d.ts +3 -1
  51. package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
  52. package/dist/activities/codemode-dispatcher.d.ts +9 -2
  53. package/dist/activities/codex-capacity.d.ts +18 -2
  54. package/dist/activities/codex-rotation.d.ts +7 -1
  55. package/dist/activities/context-compaction.d.ts +16 -2
  56. package/dist/activities/gmail-files.d.ts +32 -0
  57. package/dist/activities/goals.d.ts +8 -0
  58. package/dist/activities/knowledge-indexing.d.ts +19 -0
  59. package/dist/activities/mcp-account-routes.d.ts +3 -0
  60. package/dist/activities/mcp-credentials.d.ts +12 -13
  61. package/dist/activities/mcp-operation-authority.d.ts +0 -5
  62. package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
  63. package/dist/activities/open-suffix-resume.d.ts +13 -0
  64. package/dist/activities/parent-wake.d.ts +6 -12
  65. package/dist/activities/retained-screenshots.d.ts +7 -2
  66. package/dist/activities/rig-verification.d.ts +2 -3
  67. package/dist/activities/run-credential-renewal.d.ts +1 -0
  68. package/dist/activities/run-credentials.d.ts +15 -3
  69. package/dist/activities/sandbox-images.d.ts +1 -1
  70. package/dist/activities/sandbox-lease.d.ts +47 -9
  71. package/dist/activities/scheduled-tasks.d.ts +4 -35
  72. package/dist/activities/session-state.d.ts +70 -3
  73. package/dist/activities/types.d.ts +55 -6
  74. package/dist/activities/workspace-capture.d.ts +2 -0
  75. package/dist/activities/workspace-credential-provider.d.ts +46 -0
  76. package/dist/{activities-control-HMFGSKC5.js → activities-control-BNPTRTOE.js} +1896 -418
  77. package/dist/activities-control-BNPTRTOE.js.map +1 -0
  78. package/dist/activities-control.d.ts +182 -4
  79. package/dist/{activities-turn-AP67JADS.js → activities-turn-5LGZOSVU.js} +4476 -1327
  80. package/dist/activities-turn-5LGZOSVU.js.map +1 -0
  81. package/dist/activities.d.ts +182 -4
  82. package/dist/artifact-materializer-entry.js +5 -2
  83. package/dist/artifact-materializer-entry.js.map +1 -1
  84. package/dist/artifact-outbox-entry.js +5 -2
  85. package/dist/artifact-outbox-entry.js.map +1 -1
  86. package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
  87. package/dist/{chunk-A4XQWVZK.js → chunk-3ZTRWDMN.js} +307 -4
  88. package/dist/chunk-3ZTRWDMN.js.map +1 -0
  89. package/dist/{chunk-RAMNYSAW.js → chunk-4ER3YXOT.js} +22 -4
  90. package/dist/chunk-4ER3YXOT.js.map +1 -0
  91. package/dist/{chunk-CYITU5UH.js → chunk-LJX7Z2KP.js} +1445 -343
  92. package/dist/chunk-LJX7Z2KP.js.map +1 -0
  93. package/dist/editable-artifact-materializer-service.d.ts +2 -2
  94. package/dist/editable-artifact-outbox-service.d.ts +2 -2
  95. package/dist/host-export-pump.d.ts +3 -1
  96. package/dist/host-export.d.ts +1 -1
  97. package/dist/host-export.js +1 -1
  98. package/dist/http.d.ts +1 -1
  99. package/dist/index.d.ts +95 -3
  100. package/dist/index.js +137 -43
  101. package/dist/index.js.map +1 -1
  102. package/dist/observability-metrics.d.ts +118 -8
  103. package/dist/retained-process-diagnostics.d.ts +4 -0
  104. package/dist/retained-process-retry.d.ts +7 -0
  105. package/dist/sandbox-resume.d.ts +55 -13
  106. package/dist/sandbox-routing.d.ts +5 -3
  107. package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
  108. package/dist/session-event-fanout.d.ts +6 -0
  109. package/dist/warm-capture-holder.d.ts +3 -0
  110. package/dist/worker-service-lifecycle.d.ts +12 -0
  111. package/dist/workflow-bundle.js +273 -41
  112. package/dist/workflows/activities.d.ts +1 -1
  113. package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
  114. package/dist/workflows/scheduled-tasks.d.ts +4 -0
  115. package/dist/workflows/session.d.ts +36 -0
  116. package/dist/workflows.d.ts +1 -0
  117. package/package.json +21 -19
  118. package/src/activities/agent-run-admission.ts +17 -1
  119. package/src/activities/agent-turn/admission.ts +66 -3
  120. package/src/activities/agent-turn/agent-build.ts +84 -10
  121. package/src/activities/agent-turn/claim.ts +186 -43
  122. package/src/activities/agent-turn/claude-usage-observer.ts +221 -0
  123. package/src/activities/agent-turn/code-search.ts +275 -0
  124. package/src/activities/agent-turn/codex-capacity.ts +172 -8
  125. package/src/activities/agent-turn/codex-plan-entitlement.ts +254 -0
  126. package/src/activities/agent-turn/codex.ts +13 -5
  127. package/src/activities/agent-turn/compaction-prep.ts +170 -102
  128. package/src/activities/agent-turn/credential-leases.ts +122 -216
  129. package/src/activities/agent-turn/credential-restriction.ts +14 -0
  130. package/src/activities/agent-turn/errors.ts +647 -48
  131. package/src/activities/agent-turn/failure-settlement.ts +682 -130
  132. package/src/activities/agent-turn/final-reply.ts +46 -0
  133. package/src/activities/agent-turn/finalization-monitor.ts +120 -0
  134. package/src/activities/agent-turn/finalization.ts +146 -43
  135. package/src/activities/agent-turn/github-repository-bindings.ts +3 -1
  136. package/src/activities/agent-turn/governance-model.ts +69 -28
  137. package/src/activities/agent-turn/history-sink.ts +16 -2
  138. package/src/activities/agent-turn/history.ts +38 -11
  139. package/src/activities/agent-turn/input-wait-reply.ts +103 -0
  140. package/src/activities/agent-turn/knowledge-source-tools.ts +2 -0
  141. package/src/activities/agent-turn/media-artifacts.ts +2 -1
  142. package/src/activities/agent-turn/model-call-admission.ts +94 -0
  143. package/src/activities/agent-turn/model-usage.ts +64 -3
  144. package/src/activities/agent-turn/model-wire-dispatch.ts +27 -0
  145. package/src/activities/agent-turn/optional-repositories.ts +224 -0
  146. package/src/activities/agent-turn/provider-dispatch-barrier.ts +22 -0
  147. package/src/activities/agent-turn/quiescence.ts +10 -7
  148. package/src/activities/agent-turn/recovery-warning.ts +16 -0
  149. package/src/activities/agent-turn/refresh-credentials.ts +44 -0
  150. package/src/activities/agent-turn/run-credentials.ts +116 -55
  151. package/src/activities/agent-turn/run.ts +320 -93
  152. package/src/activities/agent-turn/sandbox-establish.ts +84 -8
  153. package/src/activities/agent-turn/sandbox-provision.ts +3 -1
  154. package/src/activities/agent-turn/sandbox-route.ts +4 -21
  155. package/src/activities/agent-turn/sandbox-runtime.ts +343 -18
  156. package/src/activities/agent-turn/session-title.ts +81 -5
  157. package/src/activities/agent-turn/skill-checkout.ts +111 -24
  158. package/src/activities/agent-turn/skill-install.ts +1 -1
  159. package/src/activities/agent-turn/skill-read.ts +374 -28
  160. package/src/activities/agent-turn/skill-remove.ts +46 -0
  161. package/src/activities/agent-turn/skill-save.ts +1 -1
  162. package/src/activities/agent-turn/skill-search.ts +10 -1
  163. package/src/activities/agent-turn/skill-selection.ts +4 -0
  164. package/src/activities/agent-turn/skill-tools.ts +112 -18
  165. package/src/activities/agent-turn/skill-transfer.ts +68 -23
  166. package/src/activities/agent-turn/stream-attempt.ts +313 -77
  167. package/src/activities/agent-turn/subscription-lease.ts +115 -0
  168. package/src/activities/agent-turn/tool-environment.ts +316 -167
  169. package/src/activities/agent-turn/tool-policy.ts +80 -1
  170. package/src/activities/agent-turn/turn-context.ts +35 -0
  171. package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
  172. package/src/activities/agent-turn/xai-capacity.ts +94 -51
  173. package/src/activities/automations.ts +76 -4
  174. package/src/activities/browser-deadline-checkpoint.ts +279 -0
  175. package/src/activities/capabilities.ts +108 -11
  176. package/src/activities/codemode-dispatcher.ts +36 -8
  177. package/src/activities/codex-capacity.ts +60 -25
  178. package/src/activities/codex-rotation.ts +39 -17
  179. package/src/activities/context-compaction.ts +75 -18
  180. package/src/activities/gmail-files.ts +88 -0
  181. package/src/activities/goals.ts +116 -121
  182. package/src/activities/google-drive-publication.ts +1 -3
  183. package/src/activities/image-generation-operation.ts +1 -1
  184. package/src/activities/knowledge-indexing.ts +269 -15
  185. package/src/activities/knowledge-source-sync.ts +10 -0
  186. package/src/activities/mcp-account-routes.ts +17 -0
  187. package/src/activities/mcp-credentials.ts +83 -194
  188. package/src/activities/mcp-operation-authority.ts +16 -41
  189. package/src/activities/model-call-fact-reconciler.ts +112 -0
  190. package/src/activities/open-suffix-resume.ts +15 -2
  191. package/src/activities/parent-wake.ts +46 -21
  192. package/src/activities/retained-screenshots.ts +82 -11
  193. package/src/activities/rig-verification.ts +38 -37
  194. package/src/activities/run-credential-renewal.ts +13 -1
  195. package/src/activities/run-credentials.ts +59 -17
  196. package/src/activities/run-input.ts +25 -16
  197. package/src/activities/sandbox-images.ts +0 -1
  198. package/src/activities/sandbox-lease.ts +798 -82
  199. package/src/activities/scheduled-tasks.ts +550 -178
  200. package/src/activities/session-state.ts +245 -6
  201. package/src/activities/site-auth-maintenance.ts +3 -0
  202. package/src/activities/types.ts +72 -5
  203. package/src/activities/workflow-wake.ts +2 -17
  204. package/src/activities/workspace-capture.ts +13 -2
  205. package/src/activities/workspace-credential-provider.ts +283 -0
  206. package/src/activities-control.ts +4 -0
  207. package/src/activities-turn.ts +5 -0
  208. package/src/activities.ts +13 -0
  209. package/src/activity-services.ts +16 -4
  210. package/src/browser-deadline-checkpoint-contract.ts +5 -0
  211. package/src/editable-artifact-hint-broker.ts +3 -0
  212. package/src/editable-artifact-materializer-service.ts +7 -3
  213. package/src/editable-artifact-outbox-service.ts +4 -4
  214. package/src/github-rest-mcp.ts +1 -2
  215. package/src/host-export-pump.ts +26 -4
  216. package/src/host-export.ts +3 -0
  217. package/src/http.ts +4 -2
  218. package/src/index.ts +99 -37
  219. package/src/observability-metrics.ts +510 -5
  220. package/src/personal-github-git-credentials.ts +2 -1
  221. package/src/pr-review-credentials.ts +1 -3
  222. package/src/retained-process-diagnostics.ts +50 -0
  223. package/src/retained-process-retry.ts +36 -0
  224. package/src/sandbox-resume.ts +388 -101
  225. package/src/sandbox-routing.ts +150 -25
  226. package/src/sandbox-snapshot-diagnostics.ts +112 -0
  227. package/src/session-event-fanout.ts +23 -0
  228. package/src/warm-capture-holder.ts +15 -0
  229. package/src/worker-service-lifecycle.ts +53 -0
  230. package/src/workflows/activities.ts +16 -1
  231. package/src/workflows/browser-deadline-checkpoint.ts +50 -0
  232. package/src/workflows/file-upload-reaper.ts +2 -0
  233. package/src/workflows/scheduled-tasks.ts +26 -13
  234. package/src/workflows/session.ts +242 -22
  235. package/src/workflows.ts +4 -0
  236. package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
  237. package/dist/activities/packs.d.ts +0 -55
  238. package/dist/activities-control-HMFGSKC5.js.map +0 -1
  239. package/dist/activities-turn-AP67JADS.js.map +0 -1
  240. package/dist/chunk-A4XQWVZK.js.map +0 -1
  241. package/dist/chunk-CYITU5UH.js.map +0 -1
  242. package/dist/chunk-RAMNYSAW.js.map +0 -1
  243. package/src/activities/agent-turn/knowledge-sources.ts +0 -86
  244. package/src/activities/packs.ts +0 -166
@@ -1,5 +1,5 @@
1
1
  import type * as activities from "../activities.js";
2
- type WorkflowControlActivities = Pick<typeof activities, "enqueueGoalRetryWake" | "expireSessionHumanInput" | "expireSessionInteractionIntervention" | "failSessionAttempt" | "getCodexCapacityWait" | "markSessionIdle" | "peekSessionWork" | "persistSessionAttemptQuiescence" | "reconcileSessionAttemptQuiescence" | "reconcileCodexCapacityWait" | "recoverDispatch" | "recoverEscapedMcpTimeout" | "settleSessionInterruptions" | "settleSessionInputWait">;
2
+ type WorkflowControlActivities = Pick<typeof activities, "enqueueGoalRetryWake" | "expireSessionHumanInput" | "expireSessionInteractionIntervention" | "expireScheduledRunHumanWait" | "failSessionAttempt" | "getCodexCapacityWait" | "markSessionIdle" | "peekSessionWork" | "persistSessionAttemptQuiescence" | "reconcileSessionAttemptQuiescence" | "reconcileSettledSessionAttempt" | "reconcileCodexCapacityWait" | "recoverDispatch" | "recoverEscapedMcpTimeout" | "settleSessionInterruptions" | "settleSessionInputWait">;
3
3
  /**
4
4
  * Session/schedule workflow control activities are bounded, idempotent database
5
5
  * and provider-metadata operations. They must not inherit the agent turn's
@@ -0,0 +1,9 @@
1
+ import type { BrowserDeadlineCheckpointTarget } from "@opengeni/db";
2
+ export declare function browserDeadlineCheckpointWorkflow(target: BrowserDeadlineCheckpointTarget): Promise<{
3
+ status: "skipped";
4
+ } | {
5
+ status: "suspended";
6
+ }>;
7
+ /** Runs from the existing lease-sweep dispatch. Inventory never performs provider
8
+ * I/O; each exact browser has an independent durable capture/cleanup child. */
9
+ export declare function browserDeadlineCheckpointSweepWorkflow(): Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import type { TurnInitiator } from "@opengeni/contracts";
2
+ import type { DispatchScheduledTaskRunInput } from "../activities/types.js";
2
3
  type ScheduledTaskFireWorkflowBase = {
3
4
  accountId: string;
4
5
  workspaceId: string;
@@ -8,10 +9,13 @@ export type ScheduledTaskFireWorkflowInput = ScheduledTaskFireWorkflowBase & ({
8
9
  triggerType: "scheduled";
9
10
  agentRunUsageIdempotencyKey?: never;
10
11
  initiator?: never;
12
+ credentialRestriction?: never;
11
13
  } | {
12
14
  triggerType: "manual" | "initial" | "provider_event" | "retry" | "repair";
13
15
  agentRunUsageIdempotencyKey: string;
14
16
  initiator: TurnInitiator;
17
+ credentialRestriction?: "developer_setup";
15
18
  });
19
+ export declare function scheduledTaskDispatchInput(input: ScheduledTaskFireWorkflowInput, producerKey: string): DispatchScheduledTaskRunInput;
16
20
  export declare function scheduledTaskFireWorkflow(input: ScheduledTaskFireWorkflowInput): Promise<void>;
17
21
  export {};
@@ -1,5 +1,40 @@
1
1
  import type * as activities from "../activities.js";
2
2
  import { type EscapedMcpTimeoutRecoveryDetail, type PostClaimDatabaseRecoveryDetail, type PreClaimFailureDetail, type PreClaimFailureDisposition } from "../activities/types.js";
3
+ /**
4
+ * Provider capacity waits are shared: every waiter of one exhausted pool learns
5
+ * the same authoritative reset time, and one capacity mutation (for example the
6
+ * bounded refresh that verifies a quota reset) wakes every waiter at once, both
7
+ * as the typed capacity signal and as the generic durable workflow wake. Without
8
+ * spread, a reset resumes the whole backlog in the same few seconds and its
9
+ * turns stampede sandbox creation and the provider. Each workflow therefore
10
+ * delays its reconciliation by a bounded, replay-deterministic (Temporal-seeded
11
+ * `Math.random`) jitter: up to one minute past a scheduled reset timer and up to
12
+ * 30 seconds after a capacity or queue wake or an already-due waiter. A wake
13
+ * that lands inside a waiter's timer spread does not shorten it. The Postgres
14
+ * waiter stays authoritative; jitter only delays the same reconciliation
15
+ * activity and never creates queue rows, input, or inference. Interruptions are
16
+ * never delayed.
17
+ *
18
+ * The patch marker is not understood by workers built before it: rolling the
19
+ * worker image back past this change while a session has recorded the marker
20
+ * (it waited on capacity in its current run) fails that workflow's tasks as
21
+ * nondeterministic until a patched worker returns.
22
+ */
23
+ export declare const CAPACITY_WAKE_JITTER_PATCH = "session-capacity-wake-jitter-v1";
24
+ /**
25
+ * A scheduled run's approval timeout sleeps on a durable Temporal timer. A
26
+ * history recorded by a worker that ignored the deadline has no timer command
27
+ * there, so replay only arms it behind this marker.
28
+ */
29
+ export declare const SCHEDULED_HUMAN_WAIT_TIMEOUT_PATCH = "session-scheduled-human-wait-timeout-v1";
30
+ export declare const CAPACITY_TIMER_WAKE_JITTER_MAX_MS = 60000;
31
+ export declare const CAPACITY_WAKE_JITTER_MAX_MS = 30000;
32
+ /**
33
+ * Pure + exported so the bound is unit-testable without a workflow environment.
34
+ * `overrideMaxMs` is the test-only SessionWorkflowInput ceiling; it can only
35
+ * narrow the production bound.
36
+ */
37
+ export declare function capacityWakeJitterMs(kind: "timer" | "wake", sample: number, overrideMaxMs?: number): number;
3
38
  /**
4
39
  * How long the continuation loop must hold before re-admitting the next turn. 0 ⇒ no
5
40
  * hold (re-dispatch immediately — a rotation candidate is ready, or no idle delay was
@@ -76,5 +111,6 @@ export type SessionWorkflowInput = {
76
111
  initialEventId?: string;
77
112
  maxTurnsPerRun?: number;
78
113
  maxCapacityChecksPerRun?: number;
114
+ capacityWakeJitterMaxMs?: number;
79
115
  };
80
116
  export declare function sessionWorkflow(input: SessionWorkflowInput): Promise<void>;
@@ -6,6 +6,7 @@ export { automationRunWorkflow, type AutomationRunWorkflowInput } from "./workfl
6
6
  export { knowledgeSourceSyncWake, knowledgeSourceSyncWorkflow, knowledgeSourceSyncWorkflowId, type KnowledgeSourceSyncWorkflowInput, } from "./workflows/knowledge-source-sync.js";
7
7
  export { sandboxDrainWorkflow, sandboxReaperMaintenanceWorkflow, sandboxReaperWorkflow, sandboxReaperWorkflowV2, } from "./workflows/sandbox-reaper.js";
8
8
  export { fileUploadReaperWorkflow } from "./workflows/file-upload-reaper.js";
9
+ export { browserDeadlineCheckpointWorkflow, browserDeadlineCheckpointSweepWorkflow, } from "./workflows/browser-deadline-checkpoint.js";
9
10
  export { siteAuthMaintenanceWorkflow } from "./workflows/site-auth-maintenance.js";
10
11
  export { videoGenerationWorkflow, videoGenerationWorkflowId, type VideoGenerationWorkflowInput, } from "./workflows/video-generation.js";
11
12
  export { sessionWorkflowWakeDispatcherWorkflow } from "./workflows/workflow-wake.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/worker-bundle",
3
- "version": "1.0.0-canary.1",
3
+ "version": "1.0.0",
4
4
  "description": "OpenGeni worker entry and reusable embedded lifecycle, shipped with a release-coherent pre-bundled Temporal workflow artifact.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -54,24 +54,26 @@
54
54
  },
55
55
  "dependencies": {
56
56
  "@llamaindex/liteparse": "2.14.2",
57
- "@opengeni/agent-proto": "^0.6.0-canary.4",
58
- "@opengeni/capabilities": "^0.3.3-canary.16",
59
- "@opengeni/codemode": "^0.5.8-canary.1",
60
- "@opengeni/codex": "^0.2.23-canary.1",
61
- "@opengeni/config": "^1.2.1-canary.1",
62
- "@opengeni/contracts": "^4.0.0-canary.1",
63
- "@opengeni/core": "^3.0.0-canary.1",
64
- "@opengeni/db": "^5.0.0-canary.1",
65
- "@opengeni/documents": "^0.8.29-canary.1",
66
- "@opengeni/events": "^0.4.27-canary.1",
67
- "@opengeni/github": "^0.7.12-canary.1",
68
- "@opengeni/network": "^0.3.1-canary.16",
69
- "@opengeni/observability": "^0.8.28-canary.1",
70
- "@opengeni/runtime": "^3.0.0-canary.1",
71
- "@opengeni/sdk": "^6.0.0-canary.1",
72
- "@opengeni/storage": "^0.2.129-canary.1",
73
- "@opengeni/tool-gateway": "^0.1.9-canary.1",
74
- "@opengeni/xai-subscription": "^0.1.4-canary.16",
57
+ "@opengeni/agent-proto": "1.0.0",
58
+ "@opengeni/capabilities": "1.0.0",
59
+ "@opengeni/codemode": "1.0.0",
60
+ "@opengeni/codex": "1.0.0",
61
+ "@opengeni/config": "1.0.0",
62
+ "@opengeni/contracts": "1.0.0",
63
+ "@opengeni/core": "1.0.0",
64
+ "@opengeni/db": "1.0.0",
65
+ "@opengeni/documents": "1.0.0",
66
+ "@opengeni/events": "1.0.0",
67
+ "@opengeni/github": "1.0.0",
68
+ "@opengeni/interaction": "1.0.0",
69
+ "@opengeni/jev": "1.0.0",
70
+ "@opengeni/network": "1.0.0",
71
+ "@opengeni/observability": "1.0.0",
72
+ "@opengeni/runtime": "1.0.0",
73
+ "@opengeni/sdk": "1.0.0",
74
+ "@opengeni/storage": "1.0.0",
75
+ "@opengeni/tool-gateway": "1.0.0",
76
+ "@opengeni/xai-subscription": "1.0.0",
75
77
  "@temporalio/activity": "^1.17.0",
76
78
  "@temporalio/client": "^1.17.0",
77
79
  "@temporalio/worker": "^1.17.0",
@@ -1,10 +1,16 @@
1
1
  import { configuredStaticUsageLimits, type Settings } from "@opengeni/config";
2
2
  import { modelFundingForAdmission } from "@opengeni/core";
3
- import { getBillingBalance, isCodexBilledTurn, sumUsageQuantity } from "@opengeni/db";
3
+ import {
4
+ checkWorkspaceAllowance,
5
+ getBillingBalance,
6
+ isCodexBilledTurn,
7
+ sumUsageQuantity,
8
+ } from "@opengeni/db";
4
9
  import type { ControlActivityServices } from "./types";
5
10
 
6
11
  export type AgentRunAdmissionDenial =
7
12
  | "insufficient_credits"
13
+ | "allowance_exhausted"
8
14
  | "monthly_model_cost_limit"
9
15
  | "monthly_agent_run_limit";
10
16
 
@@ -16,6 +22,8 @@ export async function agentRunAdmissionDenial(
16
22
  workspaceId: string;
17
23
  model: string;
18
24
  requestedAgentRuns: number;
25
+ /** The accepted work's causal human, not the scheduler/service caller. */
26
+ initiatingHumanSubjectId?: string | null;
19
27
  },
20
28
  ): Promise<AgentRunAdmissionDenial | null> {
21
29
  const codexBilled = await isCodexBilledTurn({
@@ -46,6 +54,14 @@ export async function agentRunAdmissionDenial(
46
54
  if (balance.balanceMicros <= 0) return "insufficient_credits";
47
55
  }
48
56
  }
57
+ if (!externallyBilled) {
58
+ const refusal = await checkWorkspaceAllowance(services.db, {
59
+ accountId: input.accountId,
60
+ workspaceId: input.workspaceId,
61
+ subjectId: input.initiatingHumanSubjectId ?? null,
62
+ });
63
+ if (refusal) return refusal.code;
64
+ }
49
65
  if (
50
66
  services.settings.usageLimitsMode !== "static" &&
51
67
  services.settings.usageLimitsMode !== "managed"
@@ -1,4 +1,4 @@
1
- import { getBillingBalance, sumUsageQuantity } from "@opengeni/db";
1
+ import { checkWorkspaceAllowance, getBillingBalance, sumUsageQuantity } from "@opengeni/db";
2
2
  import {
3
3
  configuredStaticUsageLimits,
4
4
  resolveTurnExecutionPolicyV1,
@@ -8,6 +8,7 @@ import { selectCodexCredentialId } from "@opengeni/codex";
8
8
  import { directPersonalConnectionSubjectId } from "@opengeni/core";
9
9
  import type { TurnActivityServices as ActivityServices } from "../types";
10
10
  import {
11
+ type AllowanceExhaustedRefusal,
11
12
  type SessionEvent,
12
13
  type SessionTurn,
13
14
  type ToolAuthNeededPayload,
@@ -243,12 +244,65 @@ export class BudgetExhaustedError extends Error {
243
244
  constructor(
244
245
  message: string,
245
246
  readonly serializedRunState: string | null,
247
+ readonly allowance: AllowanceRefusal | null = null,
246
248
  ) {
247
249
  super(message);
248
250
  this.name = "BudgetExhaustedError";
249
251
  }
250
252
  }
251
253
 
254
+ export type AllowanceRefusal = AllowanceExhaustedRefusal;
255
+
256
+ /** Account allowance exhaustion is recoverable state, never a provider failure. */
257
+ export class AllowanceExhaustedError extends Error {
258
+ readonly code = "allowance_exhausted";
259
+
260
+ constructor(readonly refusal: AllowanceRefusal) {
261
+ super(refusal.message);
262
+ this.name = "AllowanceExhaustedError";
263
+ }
264
+ }
265
+
266
+ /** Revalidate between paid calls without replaying provider work or reserving credits. */
267
+ export async function ensureRunAllowedBetweenModelCalls(input: {
268
+ settings: Settings;
269
+ db: ActivityServices["db"];
270
+ accountId: string;
271
+ workspaceId: string;
272
+ isExternallyBilledTurn: boolean;
273
+ entitlements?: ActivityServices["entitlements"];
274
+ chargesOpenGeniCredits: boolean;
275
+ countsTowardTokenCap: boolean;
276
+ initiatingHumanSubjectId: string | null;
277
+ serializedRunState?: () => string | null;
278
+ }): Promise<void> {
279
+ try {
280
+ await ensureRunAllowed(
281
+ input.settings,
282
+ input.db,
283
+ input.accountId,
284
+ input.workspaceId,
285
+ input.isExternallyBilledTurn,
286
+ input.entitlements,
287
+ input.chargesOpenGeniCredits,
288
+ input.countsTowardTokenCap,
289
+ input.initiatingHumanSubjectId,
290
+ );
291
+ } catch (limitError) {
292
+ let serializedRunState: string | null = null;
293
+ try {
294
+ serializedRunState = input.serializedRunState?.() ?? null;
295
+ } catch {
296
+ // Durable history remains authoritative when the SDK state cannot serialize.
297
+ }
298
+ throw new BudgetExhaustedError(
299
+ limitError instanceof Error ? limitError.message : String(limitError),
300
+ serializedRunState,
301
+ limitError instanceof AllowanceExhaustedError ? limitError.refusal : null,
302
+ );
303
+ }
304
+ }
305
+
252
306
  // Exported for unit testing the external-billing bypass (codex-billing.test.ts); not
253
307
  // part of the activity surface. Takes the accepted policy's billing attribution and
254
308
  // the optional §7.5 P3 host `entitlements` port (when bound, its `admitRun` REPLACES
@@ -262,6 +316,7 @@ export async function ensureRunAllowed(
262
316
  entitlements?: ActivityServices["entitlements"],
263
317
  chargesOpenGeniCredits = !isExternallyBilledTurn,
264
318
  countsTowardTokenCap = !isExternallyBilledTurn,
319
+ initiatingHumanSubjectId: string | null = null,
265
320
  ): Promise<void> {
266
321
  // Upstream settlement and workspace-facing cost are independent. External
267
322
  // metering skips the token cap; free/subscription/workspace cost skips the
@@ -291,7 +346,7 @@ export async function ensureRunAllowed(
291
346
  quantity: 1,
292
347
  });
293
348
  if (!decision.allowed) {
294
- throw new Error(decision.reason || "insufficient OpenGeni credits");
349
+ throw new Error(decision.reason || "insufficient Opengeni credits");
295
350
  }
296
351
  } else if (
297
352
  chargesOpenGeniCredits &&
@@ -299,9 +354,17 @@ export async function ensureRunAllowed(
299
354
  ) {
300
355
  const balance = await getBillingBalance(db, accountId);
301
356
  if (balance.balanceMicros <= 0) {
302
- throw new Error("insufficient OpenGeni credits");
357
+ throw new Error("insufficient Opengeni credits");
303
358
  }
304
359
  }
360
+ if (chargesOpenGeniCredits) {
361
+ const refusal = await checkWorkspaceAllowance(db, {
362
+ accountId,
363
+ workspaceId,
364
+ subjectId: initiatingHumanSubjectId,
365
+ });
366
+ if (refusal) throw new AllowanceExhaustedError(refusal);
367
+ }
305
368
  if (settings.usageLimitsMode === "static" || settings.usageLimitsMode === "managed") {
306
369
  const limits = configuredStaticUsageLimits(settings);
307
370
  if (limits.maxMonthlyAgentRunsPerWorkspace) {
@@ -8,9 +8,14 @@ import {
8
8
  loadWorkspaceVercelAiGatewayCredentialLease,
9
9
  getExternalLinkTurnAuthorization,
10
10
  getSessionTurnForAttempt,
11
+ ensureSessionReasoningConfiguration,
12
+ ensureSessionSkillCatalog,
13
+ sessionHasToolRouterHistory,
11
14
  } from "@opengeni/db";
15
+ import { recoveryAwareSessionInstructions } from "./recovery-warning";
12
16
  import {
13
17
  formatSkillCatalog,
18
+ skillCatalogEntryIds,
14
19
  type AttemptConnectorActionBinding,
15
20
  type BuildAgentOptions,
16
21
  type ConnectorActionPolicyHooks,
@@ -24,7 +29,7 @@ import {
24
29
  resolveModelProvider,
25
30
  type Settings,
26
31
  } from "@opengeni/config";
27
- import { type CodexRequestContext } from "@opengeni/codex";
32
+ import { type CodexRequestContext, supportsReasoningConfiguration } from "@opengeni/codex";
28
33
  import { executeXaiSubscriptionImageGeneration } from "../xai-image-generation";
29
34
  import { rigProviderImageContentHash, videoGenerationCapabilitiesForPolicy } from "@opengeni/core";
30
35
  import {
@@ -34,7 +39,7 @@ import {
34
39
  type VideoGenerationCredentialLease,
35
40
  } from "../video-generation-admission";
36
41
  import { VideoReferenceInputError } from "../video-reference-staging";
37
- import { rigProviderImageSourceImage } from "../packs";
42
+ import { rigProviderImageSourceImage } from "../sandbox-images";
38
43
  import type { TurnActivityServices as ActivityServices, RunAgentTurnInput } from "../types";
39
44
  import { recordTurnStartupPhase } from "../../observability-metrics";
40
45
  import { summarizeCompanyBrainContributions } from "../../model-context-contributions";
@@ -48,12 +53,14 @@ import {
48
53
  } from "../image-generation-references";
49
54
  import { SandboxChannelAService } from "@opengeni/runtime/sandbox";
50
55
  import { sandboxRunAs } from "@opengeni/runtime";
51
- import { VideoGenerationRejectedResult } from "@opengeni/contracts";
56
+ import { VideoGenerationRejectedResult, resolveAgentToolFamilies } from "@opengeni/contracts";
52
57
 
53
58
  import {
54
59
  structuredToolTransportForTurn,
55
60
  hostedWebSearchForTurn,
56
61
  connectedSubscriptionImageGenerationAuthority,
62
+ textVerbosityForTurn,
63
+ reasoningSummaryForTurn,
57
64
  } from "./tool-policy";
58
65
  import type { ClaimTurnOk } from "./claim";
59
66
  import type { GovernanceModelOk } from "./governance-model";
@@ -76,6 +83,7 @@ import { resolveVideoReferenceSandboxAccess } from "./video-reference-sandbox";
76
83
 
77
84
  export type BuildTurnAgentDeps = {
78
85
  skillCatalog: NonNullable<BuildAgentOptions["skillCatalog"]>;
86
+ mcpServers: Settings["mcpServers"];
79
87
  input: RunAgentTurnInput;
80
88
  db: ActivityServices["db"];
81
89
  runtime: ActivityServices["runtime"];
@@ -105,6 +113,7 @@ export type BuildTurnAgentDeps = {
105
113
  supportsImageInput: GovernanceModelOk["supportsImageInput"];
106
114
  agentHumanInputEnabled: GovernanceModelOk["agentHumanInputEnabled"];
107
115
  workspaceAgentInstructions: GovernanceModelOk["workspaceAgentInstructions"];
116
+ workspaceAgentIdentity: GovernanceModelOk["workspaceAgentIdentity"];
108
117
  workspaceGovernance: GovernanceModelOk["workspaceGovernance"];
109
118
  structuredWorkspacePolicyActive: GovernanceModelOk["structuredWorkspacePolicyActive"];
110
119
  workspaceMemory: GovernanceModelOk["workspaceMemory"];
@@ -127,6 +136,8 @@ export type BuildTurnAgentDeps = {
127
136
  connectorActionPolicy: ConnectorActionPolicyHooks;
128
137
  trigger: ClaimTurnOk["trigger"];
129
138
  preparationIndependentToolNames: readonly string[];
139
+ /** The attempt's tool catalog includes the Jev-backed code_search tool. */
140
+ codeSearchAvailable: boolean;
130
141
  videoGenerationAcceptancesByCallId: Map<string, { operationId: string; requestDigest: string }>;
131
142
  activeSandboxBackend: Settings["sandboxBackend"] | undefined;
132
143
  groupBoxBackend: Settings["sandboxBackend"];
@@ -136,6 +147,7 @@ export type BuildTurnAgentDeps = {
136
147
 
137
148
  export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
138
149
  const {
150
+ mcpServers,
139
151
  input,
140
152
  db,
141
153
  runtime,
@@ -164,6 +176,7 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
164
176
  supportsImageInput,
165
177
  agentHumanInputEnabled,
166
178
  workspaceAgentInstructions,
179
+ workspaceAgentIdentity,
167
180
  workspaceGovernance,
168
181
  structuredWorkspacePolicyActive,
169
182
  workspaceMemory,
@@ -184,6 +197,7 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
184
197
  connectorActionPolicy,
185
198
  trigger,
186
199
  preparationIndependentToolNames,
200
+ codeSearchAvailable,
187
201
  videoGenerationAcceptancesByCallId,
188
202
  activeSandboxBackend,
189
203
  groupBoxBackend,
@@ -191,6 +205,14 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
191
205
  codexContext,
192
206
  } = deps;
193
207
  const preparedTools = eventing.preparedTools!;
208
+ // Durable recovery truth is read for every attempt, including reconstruction
209
+ // after compaction. It is never inferred from transcript tool successes.
210
+ // These scoped reads are independent. Keep the second live video-policy
211
+ // read here rather than reusing tool preparation's earlier policy snapshot.
212
+ const [sessionInstructions, videoGenerationPolicy] = await Promise.all([
213
+ recoveryAwareSessionInstructions(db, input.workspaceId, session),
214
+ getWorkspaceVideoGenerationPolicy(db, input.workspaceId),
215
+ ]);
194
216
 
195
217
  const missingSessionTitleHint = preparationIndependentToolNames.includes(
196
218
  SESSION_TITLE_MODEL_TOOL_NAME,
@@ -267,7 +289,7 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
267
289
  // Never expose a paid image operation unless its permanent artifact can
268
290
  // be committed. Failing after provider execution would leave an
269
291
  // unrecoverable outcome-unknown operation with no user-visible image.
270
- if (!objectStorage) return {};
292
+ if (!objectStorage || !resolveAgentToolFamilies(session.agent).media) return {};
271
293
  if (nativeImageProviderBinding) {
272
294
  media.nativeImageGenerationRetention = {
273
295
  ...nativeImageProviderBinding,
@@ -383,12 +405,11 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
383
405
  },
384
406
  };
385
407
  })();
386
- const videoGenerationPolicy = await getWorkspaceVideoGenerationPolicy(db, input.workspaceId);
387
408
  const videoGenerationEnabled =
388
409
  videoGenerationPolicy.defaultModelId !== null &&
389
410
  videoGenerationPolicy.enabledModelIds.length > 0;
390
411
  let videoGenerationCredential: VideoGenerationCredentialLease | null = null;
391
- if (objectStorage && videoGenerationEnabled) {
412
+ if (objectStorage && videoGenerationEnabled && resolveAgentToolFamilies(session.agent).media) {
392
413
  if (videoGenerationPolicy.fundingSource === "opengeni_credits") {
393
414
  videoGenerationCredential = managedVideoGenerationCredentialLease(eventing.modelRunSettings);
394
415
  } else if (videoGenerationPolicy.fundingSource === "workspace_gateway") {
@@ -555,8 +576,19 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
555
576
  turnExecutionPolicy.providerId,
556
577
  turnExecutionPolicy.latencyMode,
557
578
  );
579
+ const textVerbosity = textVerbosityForTurn(resolvedModel, turnExecutionPolicy.upstreamModelId);
580
+ const reasoningSummary = reasoningSummaryForTurn(resolvedModel);
558
581
  const approvedToolCallId = approvedConnectorActionCallId(trigger);
559
- const modelVisibleSkillCatalogText = formatSkillCatalog(deps.skillCatalog);
582
+ const modelVisibleSkillCatalogText = await ensureSessionSkillCatalog(db, {
583
+ accountId: input.accountId,
584
+ workspaceId: input.workspaceId,
585
+ sessionId: input.sessionId,
586
+ turnId: turn.id,
587
+ expectedExecutionGeneration: turn.executionGeneration,
588
+ expectedAttemptId: input.attemptId,
589
+ catalog: formatSkillCatalog(deps.skillCatalog),
590
+ });
591
+ eventing.modelVisibleSkillIds = skillCatalogEntryIds(modelVisibleSkillCatalogText);
560
592
  try {
561
593
  eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
562
594
  buildCompanyBrainContributionReceiptFor(modelVisibleSkillCatalogText),
@@ -581,11 +613,38 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
581
613
  );
582
614
  if (linkedToolAuthority && !linkedToolAuthority.authorized)
583
615
  throw new Error("Native identity link was revoked");
616
+ const useReasoningUpdates =
617
+ eventing.modelRunSettings.reasoningConfigurationUpdatesEnabled &&
618
+ resolvedModel?.provider.api === "responses" &&
619
+ (resolvedModel.provider.id === "codex" || resolvedModel.provider.id === "openai") &&
620
+ supportsReasoningConfiguration(turnExecutionPolicy.upstreamModelId, turn.reasoningEffort);
621
+ const requestReasoningEffort =
622
+ useReasoningUpdates &&
623
+ supportsReasoningConfiguration(turnExecutionPolicy.upstreamModelId, turn.reasoningEffort)
624
+ ? await ensureSessionReasoningConfiguration(db, {
625
+ accountId: input.accountId,
626
+ workspaceId: input.workspaceId,
627
+ sessionId: input.sessionId,
628
+ turnId: turn.id,
629
+ expectedExecutionGeneration: turn.executionGeneration,
630
+ expectedAttemptId: input.attemptId,
631
+ effort: turn.reasoningEffort,
632
+ })
633
+ : turn.reasoningEffort;
634
+ const toolRouterInHistory = session.agent
635
+ ? await sessionHasToolRouterHistory(db, {
636
+ accountId: input.accountId,
637
+ workspaceId: input.workspaceId,
638
+ sessionId: input.sessionId,
639
+ })
640
+ : false;
584
641
  const agent = (() => {
585
642
  const agentConstructionStartedAt = performance.now();
586
643
  let agentConstructionOutcome: "completed" | "failed" = "completed";
587
644
  try {
588
- return runtime.buildAgent(eventing.modelRunSettings, runtimeResources, {
645
+ // Approval policy must use the same accepted account identities as tool
646
+ // preparation. Keep the separately resolved model/sandbox settings intact.
647
+ return runtime.buildAgent({ ...eventing.modelRunSettings, mcpServers }, runtimeResources, {
589
648
  ...(linkedToolAuthority
590
649
  ? {
591
650
  authorizeAttemptExecution: async () => {
@@ -605,9 +664,12 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
605
664
  }
606
665
  : {}),
607
666
  ...(preparedTools.inputWaitYield ? { inputWaitYield: preparedTools.inputWaitYield } : {}),
608
- reasoningEffort: turn.reasoningEffort,
667
+ ...(session.agent ? { agentConfig: session.agent, toolRouterInHistory } : {}),
668
+ reasoningEffort: requestReasoningEffort,
669
+ ...(reasoningSummary ? { reasoningSummary } : {}),
609
670
  latencyMode: turnExecutionPolicy.latencyMode,
610
671
  ...(serviceTier ? { serviceTier } : {}),
672
+ ...(textVerbosity ? { textVerbosity } : {}),
611
673
  ...(humanInputResume ? { humanInputResponse: humanInputResume } : {}),
612
674
  humanInputEnabled: agentHumanInputEnabled,
613
675
  missingSessionTitleHint,
@@ -636,6 +698,7 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
636
698
  ? { gitTokenSeed: sandboxGitToken }
637
699
  : {}),
638
700
  ...(sandboxCodemodeToken ? { codemodeAvailable: true } : {}),
701
+ ...(codeSearchAvailable ? { codeSearchAvailable: true } : {}),
639
702
  // Managed boxes receive the bearer through their protected per-session
640
703
  // token file. Connected Machines use transient per-exec delivery above,
641
704
  // so they must not run the file-seeding lifecycle hook.
@@ -707,6 +770,17 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
707
770
  }),
708
771
  onRetainableSessionImageOutput: media.retainSessionImageAtToolBoundary,
709
772
  skillCatalog: deps.skillCatalog,
773
+ skillCatalogInHistory: true,
774
+ // A session with an agent configuration composes the modular prompt
775
+ // (identity, base behavior, runtime mechanics, capability modules);
776
+ // its workspace identity survives instruction policies. Null keeps
777
+ // the legacy composition below byte-for-byte.
778
+ ...(session.agent
779
+ ? {
780
+ agentConfig: session.agent,
781
+ ...(workspaceAgentIdentity ? { workspaceAgentIdentity } : {}),
782
+ }
783
+ : {}),
710
784
  ...(!structuredWorkspacePolicyActive && workspaceAgentInstructions
711
785
  ? { instructionsTemplate: workspaceAgentInstructions }
712
786
  : {}),
@@ -715,7 +789,7 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
715
789
  // Per-session persona tier (session > workspace > deployment default).
716
790
  // Composed system-level AFTER the workspace persona so it refines it for
717
791
  // this one session; absent ⇒ byte-identical to today's composition.
718
- ...(session.instructions ? { sessionInstructions: session.instructions } : {}),
792
+ ...(sessionInstructions ? { sessionInstructions } : {}),
719
793
  ...workspaceEnvironmentOption,
720
794
  // RIG RUNTIME (M3): the doctrine block, the setup-script hook (only when
721
795
  // the frozen version carries a non-empty script), and the rig credential