@opengeni/worker-bundle 1.0.0-canary.0 → 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
@@ -20,10 +20,14 @@ import {
20
20
  renderWorkspaceGovernanceContext,
21
21
  type OpenGeniRuntime,
22
22
  } from "@opengeni/runtime";
23
- import { settingsWithResolvedModelContext, type Settings } from "@opengeni/config";
23
+ import {
24
+ codeSearchDeploymentPolicy,
25
+ settingsWithResolvedModelContext,
26
+ type Settings,
27
+ } from "@opengeni/config";
28
+ import { projectReasoningConfigurations, supportsReasoningConfiguration } from "@opengeni/codex";
24
29
  import { settingsWithSessionMcpServersForRun } from "../capabilities";
25
- import { resolveRigProviderImageForRun } from "@opengeni/core";
26
- import { resolveWorkspacePackRuntime, settingsWithPackSandboxImage } from "../packs";
30
+ import { resolveRigProviderImageForRun, settingsWithWorkspaceSandboxImage } from "@opengeni/core";
27
31
  import { createModelHistoryAttachmentProjector } from "../run-input";
28
32
  import type {
29
33
  TurnActivityServices as ActivityServices,
@@ -40,12 +44,15 @@ import {
40
44
  } from "../generated-images";
41
45
  import { createTurnMediaArtifacts } from "./media-artifacts";
42
46
  import { retryWhileMissing } from "@opengeni/storage";
47
+ import { measureTurnStartupPhase } from "../../observability-metrics";
43
48
  import { WorkspaceModelPolicyBlockedError } from "@opengeni/runtime";
44
49
  import {
45
50
  evaluateWorkspaceModelPolicy,
46
51
  resolveWorkspaceAgentHumanInputEnabled,
52
+ resolveWorkspaceDefaultAgentIdentity,
47
53
  type MediaGenerationResult,
48
54
  } from "@opengeni/contracts";
55
+ import { codeSearchEnabledForTurn } from "@opengeni/contracts/code-search";
49
56
 
50
57
  import { assertWorkspaceHumanInputAllowed } from "./admission";
51
58
  import {
@@ -60,6 +67,7 @@ import type { EventingState, WorkspaceRefState } from "./turn-context";
60
67
  export type GovernanceModelDeps = {
61
68
  input: RunAgentTurnInput;
62
69
  db: ActivityServices["db"];
70
+ observability: ActivityServices["observability"];
63
71
  runtime: ActivityServices["runtime"];
64
72
  objectStorage: ActivityServices["objectStorage"];
65
73
  eventing: EventingState;
@@ -84,13 +92,20 @@ export type GovernanceModelDeps = {
84
92
 
85
93
  export type GovernanceModelOk = {
86
94
  runtimePreparationStartedAt: number;
87
- packRuntime: Awaited<ReturnType<typeof resolveWorkspacePackRuntime>>;
88
95
  rigVersion:
89
96
  | NonNullable<Awaited<ReturnType<typeof materializeRigVersionForAttempt>>>["version"]
90
97
  | null;
91
98
  rigName: string | null;
92
99
  agentHumanInputEnabled: boolean;
100
+ /** Deployment and workspace allow the Jev-backed code_search tool. */
101
+ codeSearchEnabled: boolean;
93
102
  workspaceAgentInstructions: string | null | undefined;
103
+ /**
104
+ * Modular composer identity tier: the explicit workspace default identity,
105
+ * else the frozen legacy persona without `{{core}}`. Never dropped by
106
+ * instruction policies (only read for sessions with an agent configuration).
107
+ */
108
+ workspaceAgentIdentity: string | null;
94
109
  workspaceGovernance: ReturnType<typeof renderWorkspaceGovernanceContext>;
95
110
  structuredWorkspacePolicyActive: boolean;
96
111
  workspaceMemory: string | null | undefined;
@@ -155,6 +170,7 @@ export async function prepareGovernanceAndModel(
155
170
  const {
156
171
  input,
157
172
  db,
173
+ observability,
158
174
  runtime,
159
175
  objectStorage,
160
176
  eventing,
@@ -189,17 +205,15 @@ export async function prepareGovernanceAndModel(
189
205
  attemptId: input.attemptId,
190
206
  executionGeneration: turn.executionGeneration,
191
207
  };
192
- // Independent workspace reads after the personal-resource fence. Pack,
193
- // installed skills, frozen rig, governance snapshots, and model policy do
208
+ // Independent workspace reads after the personal-resource fence. The
209
+ // frozen rig, governance snapshots, and model policy do
194
210
  // not depend on each other. Company-brain selection still waits on the
195
211
  // snapshots below so its receipt stays exact.
196
212
  const [
197
- packRuntime,
198
213
  rigMaterialization,
199
214
  [workspace, companyProfileSnapshot, instructionPolicySnapshot, preferenceSnapshot],
200
215
  workspaceModelPolicy,
201
216
  ] = await Promise.all([
202
- resolveWorkspacePackRuntime(db, input.workspaceId),
203
217
  session.rigId && session.rigVersionId
204
218
  ? (async () =>
205
219
  await materializeRigVersionForAttempt(db, {
@@ -233,8 +247,20 @@ export async function prepareGovernanceAndModel(
233
247
  workspaceRefs.rigVersionId = session.rigVersionId ?? "";
234
248
  if (!workspace) throw new Error(`Workspace not found: ${input.workspaceId}`);
235
249
  const agentHumanInputEnabled = resolveWorkspaceAgentHumanInputEnabled(workspace.settings);
250
+ // The session's decision was frozen when it was created, so only a
251
+ // deliberate switch-off (deployment or workspace Off), or undoing one,
252
+ // changes its tool list.
253
+ const codeSearchEnabled = codeSearchEnabledForTurn(
254
+ session.codeSearchEnabled,
255
+ workspace.settings,
256
+ codeSearchDeploymentPolicy(capabilitySettings),
257
+ );
236
258
  const contextSelection = await resolveCompanyBrainContextSelection(db, governanceClaims);
237
259
  const workspaceAgentInstructions = contextSelection.legacyWorkspaceInstructions;
260
+ const workspaceAgentIdentity = resolveWorkspaceDefaultAgentIdentity(
261
+ workspace.settings,
262
+ workspaceAgentInstructions,
263
+ ).identity;
238
264
  const memoryPromptMode = contextSelection.receipt.memoryPromptMode;
239
265
  assertWorkspaceHumanInputAllowed(agentHumanInputEnabled, "resume", humanInputResume !== null);
240
266
  const companyProfileIncluded = contextSelection.receipt.companyProfileIncluded;
@@ -279,15 +305,13 @@ export async function prepareGovernanceAndModel(
279
305
  } catch {
280
306
  // Contribution telemetry must never change model execution semantics.
281
307
  }
282
- // A Rig is always a setup/check layer over the deployment platform sandbox.
283
- // The pre-v2 Pack image path remains only for rig-less compatibility sessions.
284
- const logicalSandboxSettings = rigVersion
285
- ? capabilitySettings
286
- : settingsWithPackSandboxImage(
287
- capabilitySettings,
288
- packRuntime.sandboxImage,
289
- packRuntime.sandboxProviderImages,
290
- );
308
+ // A Rig is always a setup/check layer over the deployment platform sandbox,
309
+ // or over the workspace's allowlisted selection of one.
310
+ const logicalSandboxSettings = settingsWithWorkspaceSandboxImage(
311
+ capabilitySettings,
312
+ workspace.settings,
313
+ turn.sandboxBackend,
314
+ );
291
315
  const providerImageSelection = await resolveRigProviderImageForRun(
292
316
  logicalSandboxSettings,
293
317
  rigVersion,
@@ -299,21 +323,29 @@ export async function prepareGovernanceAndModel(
299
323
  ? (providerImageSelection.imageId ?? undefined)
300
324
  : undefined;
301
325
  const baseRunSettings = {
302
- // IMAGE PRECEDENCE: a Rig uses the deployment platform base; a rig-less
303
- // pre-v2 Pack may retain its compatibility image. A matching verified
304
- // provider-native ID is then applied only to fresh creation without
326
+ // A Rig uses the deployment platform base. A matching verified
327
+ // provider-native ID is applied only to fresh creation without
305
328
  // changing the logical lease image.
306
329
  ...providerImageSettings,
307
330
  openaiModel: turn.model,
308
331
  openaiReasoningEffort: turn.reasoningEffort,
309
332
  sandboxBackend: turn.sandboxBackend,
310
333
  };
311
- const runSettings = await settingsWithSessionMcpServersForRun(
312
- db,
313
- input.workspaceId,
314
- input.sessionId,
315
- input.attemptId,
316
- baseRunSettings,
334
+ const runSettings = await measureTurnStartupPhase(
335
+ observability,
336
+ {
337
+ phase: "session_mcp_settings",
338
+ provider: turnExecutionPolicy.providerId,
339
+ backend: turn.sandboxBackend,
340
+ },
341
+ () =>
342
+ settingsWithSessionMcpServersForRun(
343
+ db,
344
+ input.workspaceId,
345
+ input.sessionId,
346
+ input.attemptId,
347
+ baseRunSettings,
348
+ ),
317
349
  );
318
350
 
319
351
  // Multi-provider per-turn routing → the provider gating (compaction mode,
@@ -365,12 +397,20 @@ export async function prepareGovernanceAndModel(
365
397
  fileIds,
366
398
  }),
367
399
  );
400
+ const useReasoningUpdates =
401
+ runSettings.reasoningConfigurationUpdatesEnabled &&
402
+ providerApi === "responses" &&
403
+ (resolvedModel?.provider.id === "codex" || resolvedModel?.provider.id === "openai") &&
404
+ supportsReasoningConfiguration(turnExecutionPolicy.upstreamModelId, turn.reasoningEffort);
368
405
  const modelHistoryProjector = async (
369
406
  items: Array<Record<string, unknown>>,
370
407
  projectionOptions?: Parameters<typeof attachmentProjector>[1],
371
408
  ) =>
372
409
  projectModelInputForCapabilities(
373
- await attachmentProjector(items, projectionOptions),
410
+ projectReasoningConfigurations(
411
+ await attachmentProjector(items, projectionOptions),
412
+ useReasoningUpdates,
413
+ ),
374
414
  modelInputPolicy,
375
415
  );
376
416
  const generatedImageHistoryProjector = async (
@@ -460,11 +500,12 @@ export async function prepareGovernanceAndModel(
460
500
  return {
461
501
  ok: {
462
502
  runtimePreparationStartedAt,
463
- packRuntime,
464
503
  rigVersion,
465
504
  rigName,
466
505
  agentHumanInputEnabled,
506
+ codeSearchEnabled,
467
507
  workspaceAgentInstructions,
508
+ workspaceAgentIdentity,
468
509
  workspaceGovernance,
469
510
  structuredWorkspacePolicyActive,
470
511
  workspaceMemory,
@@ -50,6 +50,7 @@ export type TurnHistorySinkDeps = {
50
50
  */
51
51
  export class TurnHistorySink {
52
52
  private readonly prefix = new HistoryPrefixGuard();
53
+ private checkpointTail: Promise<void> = Promise.resolve();
53
54
 
54
55
  seedHistory(input: string | readonly unknown[] | { readonly history: unknown[] }, count: number) {
55
56
  const items =
@@ -76,9 +77,22 @@ export class TurnHistorySink {
76
77
 
77
78
  constructor(private readonly deps: TurnHistorySinkDeps) {}
78
79
 
79
- reconcileConversationTruth = async (
80
+ reconcileConversationTruth = (
80
81
  options: { skipInputOnlyRows?: boolean; requireDurable?: boolean } = {},
81
- ) => {
82
+ ): Promise<void> => {
83
+ // The provider loop and the stream consumer checkpoint independently.
84
+ // Serialize the complete read/write/acknowledgment boundary, not just the
85
+ // database write: each caller must read history against the latest durable
86
+ // watermark. Keep each caller's durability policy and rejection intact.
87
+ const checkpoint = this.checkpointTail.then(() => this.reconcile(options));
88
+ this.checkpointTail = checkpoint.catch(() => {});
89
+ return checkpoint;
90
+ };
91
+
92
+ private reconcile = async (options: {
93
+ skipInputOnlyRows?: boolean;
94
+ requireDurable?: boolean;
95
+ }) => {
82
96
  const { media } = this.deps;
83
97
  const stream = this.deps.getStream();
84
98
  const turnId = this.deps.getTurnId();
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  normalizeProtocolJsonValue,
3
+ TURN_OPERATIONAL_NOTICE_PREFIX,
3
4
  sanitizeHistoryItemsForModel,
4
5
  toolCallIdFromSdkItem,
5
6
  } from "@opengeni/runtime";
@@ -31,15 +32,20 @@ export function historyRowsToAppend(
31
32
  }
32
33
  // Canonical model-facing inputs (including machine-input batches) are
33
34
  // persisted before inference and therefore live inside the prefix represented
34
- // by persistedHistoryCount. System messages synthesized only for this
35
- // attempt—recovery diagnostics, credential notices, attachment materialization
36
- // notes—must not accidentally become conversation memory during reconciliation.
37
- // Advance the in-memory watermark past them, but only allocate durable
38
- // positions to actual model/tool output.
35
+ // by persistedHistoryCount. Explicitly turn-scoped operational notices remain
36
+ // at their original positions: deleting them rewrites the model-visible prefix
37
+ // on the next turn and during compaction. Unscoped synthetic system messages
38
+ // still cannot silently become permanent conversation instructions.
39
39
  const rows: Array<{ position: number; item: Record<string, unknown> }> = [];
40
40
  for (const [offset, item] of modelReady.slice(persistedHistoryCount).entries()) {
41
41
  if (item.type === "message" && item.role === "system") {
42
- continue;
42
+ const content =
43
+ typeof item.content === "string"
44
+ ? item.content
45
+ : Array.isArray(item.content)
46
+ ? item.content.map((part: { text?: string }) => part.text ?? "").join("")
47
+ : "";
48
+ if (!content.startsWith(TURN_OPERATIONAL_NOTICE_PREFIX)) continue;
43
49
  }
44
50
  rows.push({
45
51
  position: nextPosition + rows.length,
@@ -149,10 +155,18 @@ export function pendingToolCallFromSdkEvent(event: unknown): {
149
155
  return null;
150
156
  }
151
157
  const raw = item.rawItem as Record<string, unknown>;
152
- // The hosted image call is a complete provider fact carried by one item; it
153
- // never receives a separate function result and therefore must not enter the
154
- // pending function-call ledger.
155
- if (raw.type === "hosted_tool_call" && raw.name === "image_generation_call") return null;
158
+ // Provider-executed search/image calls carry their outcome in this item,
159
+ // not a later function result. Registering them as pending leaves an
160
+ // impossible receipt behind even after the turn completes. Hosted MCP
161
+ // approval requests are different: they still require a response.
162
+ const providerData = raw.providerData as Record<string, unknown> | undefined;
163
+ if (
164
+ raw.type === "hosted_tool_call" &&
165
+ raw.name !== "mcp_approval_request" &&
166
+ providerData?.type !== "mcp_approval_request" &&
167
+ (raw.status === "completed" || raw.name === "image_generation_call")
168
+ )
169
+ return null;
156
170
  const callId = toolCallIdFromSdkItem(raw) ?? raw.id;
157
171
  const callType = raw.type;
158
172
  if (typeof callId !== "string" || callId.length === 0 || typeof callType !== "string") {
@@ -172,7 +186,20 @@ export function toolCallProducesRetainableSessionImage(name: string | null): boo
172
186
  return (
173
187
  name === "computer_screenshot" ||
174
188
  name === "view_image" ||
175
- name === "interaction__computer_observe"
189
+ name === "interaction__computer_observe" ||
190
+ retainableBrowserScreenshotToolCall(name)
191
+ );
192
+ }
193
+
194
+ /** Browser interactions can carry an image block, including opt-in observe frames. */
195
+ export function retainableBrowserScreenshotToolCall(name: string | null): boolean {
196
+ return (
197
+ name === "browser_screenshot" ||
198
+ name === "interaction__browser_screenshot" ||
199
+ name === "browser_observe" ||
200
+ name === "interaction__browser_observe" ||
201
+ name === "browser_act" ||
202
+ name === "interaction__browser_act"
176
203
  );
177
204
  }
178
205
 
@@ -0,0 +1,103 @@
1
+ import { listSessionEvents, type Database } from "@opengeni/db";
2
+ import type { TurnInitiator, TurnInitiatorContext } from "@opengeni/contracts";
3
+
4
+ type ReplyTurn = {
5
+ source?: string | undefined;
6
+ initiator: TurnInitiator;
7
+ initiatorContext: TurnInitiatorContext;
8
+ };
9
+
10
+ /**
11
+ * Provenance an agent adds when it creates a session or calls the API
12
+ * (`via`, `viaTruncated`), plus internal-update and legacy markers: the prompt
13
+ * came from an agent or a migration, not from a person.
14
+ */
15
+ const DERIVED_PROVENANCE_KEYS = ["via", "viaTruncated", "provenanceError", "backfill"] as const;
16
+
17
+ /**
18
+ * Worker-owned producers that create a session whose first turn (`source`
19
+ * `user`) is their task prompt: scheduled runs, automations and site-auth
20
+ * maintenance. An embedding host that asserts one of these service names only
21
+ * gives up the recorded reply; it grants nothing.
22
+ */
23
+ function isWorkerTaskProducer(initiator: TurnInitiator): boolean {
24
+ if (initiator.kind !== "service") return false;
25
+ const subjectId = initiator.subjectId;
26
+ return (
27
+ subjectId === "scheduler" ||
28
+ subjectId === "site-auth-maintenance" ||
29
+ subjectId.startsWith("automation:")
30
+ );
31
+ }
32
+
33
+ /**
34
+ * Whether a turn answers a message a person sent, directly or through an API
35
+ * caller that relays one (an embedding host, a realtime delegation). The
36
+ * source alone is not enough: every session's first turn is `user`, including
37
+ * a child an agent spawned and a session a scheduled task created.
38
+ */
39
+ function turnAnswersMessage(turn: ReplyTurn): boolean {
40
+ if (turn.source !== "user" && turn.source !== "api") return false;
41
+ if (
42
+ DERIVED_PROVENANCE_KEYS.some((key) =>
43
+ Object.prototype.hasOwnProperty.call(turn.initiatorContext, key),
44
+ )
45
+ ) {
46
+ return false;
47
+ }
48
+ return !isWorkerTaskProducer(turn.initiator);
49
+ }
50
+
51
+ /**
52
+ * The reply `turn.completed` records when a turn ends through `wait_for_input`
53
+ * (read back with `turnCompletedReply` in `@opengeni/contracts`).
54
+ *
55
+ * Such a turn settles with an empty `output`: the wait, not an answer, ended
56
+ * it. When the turn answers a person's message, its latest assistant message
57
+ * is still that message's answer, for example a status reply given before
58
+ * waiting again on work in flight. That message shares its model response with
59
+ * the wait call, so it streams as commentary, which is activity everywhere
60
+ * else. Recording it lets unread attention and Slack treat it as the answer
61
+ * without relabelling the provider's phase in stored history. Turns that
62
+ * machine input, an agent or a worker-owned producer started only narrate
63
+ * progress and record nothing.
64
+ *
65
+ * The message this activity completed last is the newest. An activity that
66
+ * resumed the turn (after an approval, a human-input answer or a recovery) and
67
+ * completed none reads the turn's latest durable message instead.
68
+ */
69
+ export async function inputWaitReply(input: {
70
+ inputWaitYielded: boolean;
71
+ turn: ReplyTurn;
72
+ latestAssistantMessageText: string | null;
73
+ readLatestDurableTurnMessage: () => Promise<string | null>;
74
+ }): Promise<string | null> {
75
+ if (!input.inputWaitYielded || !turnAnswersMessage(input.turn)) return null;
76
+ const text = input.latestAssistantMessageText ?? (await input.readLatestDurableTurnMessage());
77
+ return text !== null && text.trim().length > 0 ? text : null;
78
+ }
79
+
80
+ /** How far back to look past rejected-late or duplicate completions. */
81
+ const DURABLE_MESSAGE_LOOKBACK = 16;
82
+
83
+ /**
84
+ * Text of the newest current `agent.message.completed` this turn persisted,
85
+ * or null when the session's newest completion belongs to another turn.
86
+ */
87
+ export async function latestDurableTurnMessageText(
88
+ db: Database,
89
+ input: { workspaceId: string; sessionId: string; turnId: string },
90
+ ): Promise<string | null> {
91
+ const events = await listSessionEvents(db, input.workspaceId, input.sessionId, {
92
+ direction: "before",
93
+ includeTypes: ["agent.message.completed"],
94
+ limit: DURABLE_MESSAGE_LOOKBACK,
95
+ });
96
+ for (const event of events.reverse()) {
97
+ if (event.duplicateOfEventId || (event.turnAssociation ?? "current") !== "current") continue;
98
+ if (event.turnId !== input.turnId) return null;
99
+ const text = (event.payload as { text?: unknown } | null)?.text;
100
+ return typeof text === "string" ? text : null;
101
+ }
102
+ return null;
103
+ }
@@ -1,3 +1,4 @@
1
+ import { isRetiredNativeAtlassianSource } from "@opengeni/contracts/atlassian-native-retirement";
1
2
  import type { AttemptToolDefinition } from "@opengeni/codemode";
2
3
  import {
3
4
  freezeAgentLearningPolicy,
@@ -24,6 +25,7 @@ export async function createKnowledgeSourceAttemptTools(input: {
24
25
  });
25
26
  const source = accepted?.task.agentConfig.knowledgeSource;
26
27
  if (!accepted || !source || accepted.task.action.kind !== "agent_turn") return [];
28
+ if (isRetiredNativeAtlassianSource(source)) return [];
27
29
  const actor = input.context.actor;
28
30
  const authorize = async () => {
29
31
  const current = await freezeAgentLearningPolicy(input.db, input.context);
@@ -12,7 +12,7 @@ import {
12
12
  type TurnToolCancellationFence,
13
13
  } from "@opengeni/runtime";
14
14
  import type { Settings } from "@opengeni/config";
15
- import type { RetainedArtifactMetadata } from "@opengeni/contracts";
15
+ import type { RetainedArtifactMetadata, RetainedSessionScreenshotKind } from "@opengeni/contracts";
16
16
  import type { ResumedTurnSandbox } from "../../sandbox-resume";
17
17
  import type { SharedActivityServices } from "../types";
18
18
  import {
@@ -79,6 +79,7 @@ export class TurnMediaArtifacts {
79
79
  sandboxFileDownloadBackend: Settings["sandboxBackend"];
80
80
  nativeImageGenerationRetention: NativeImageGenerationRetention | null = null;
81
81
  readonly retainedSessionImageCallIds = new Set<string>();
82
+ readonly retainedSessionImageKindsByCallId = new Map<string, RetainedSessionScreenshotKind>();
82
83
 
83
84
  constructor(private readonly deps: TurnMediaArtifactDeps) {
84
85
  this.sandboxFileDownloadBackend = deps.getModelRunSettings().sandboxBackend;
@@ -0,0 +1,94 @@
1
+ import type { StreamEvent } from "@openai/agents";
2
+
3
+ /** SDK producer/consumer rendezvous. Usage stays on the sole consumer writer. */
4
+ export function createModelCallAdmission(input: {
5
+ signal: AbortSignal;
6
+ admit: () => Promise<void>;
7
+ }) {
8
+ type Receipt = {
9
+ promise: Promise<void>;
10
+ resolve: () => void;
11
+ reject: (error: unknown) => void;
12
+ };
13
+ const receipts = new WeakMap<object, Receipt>();
14
+ const responseReceipts = new Map<string, Receipt>();
15
+ const pending = new Set<Receipt>();
16
+ const responseId = (event: unknown): string | null => {
17
+ const id = (event as { response?: { id?: unknown } } | null)?.response?.id;
18
+ return typeof id === "string" && id.length > 0 ? id : null;
19
+ };
20
+ let latest: Promise<void> = Promise.resolve();
21
+ let failure: unknown;
22
+ let failed = false;
23
+ let rejectHalted!: (error: unknown) => void;
24
+ const halted = new Promise<never>((_, reject) => {
25
+ rejectHalted = reject;
26
+ });
27
+ void halted.catch(() => undefined);
28
+ const fail = (error: unknown) => {
29
+ if (failed) return;
30
+ failed = true;
31
+ failure = error;
32
+ rejectHalted(error);
33
+ for (const receipt of pending) receipt.reject(error);
34
+ pending.clear();
35
+ responseReceipts.clear();
36
+ };
37
+ const abort = () => fail(input.signal.reason ?? new Error("Model stream cancelled"));
38
+ input.signal.addEventListener("abort", abort, { once: true });
39
+ if (input.signal.aborted) abort();
40
+ return {
41
+ beforeModelRequest: async () => {
42
+ await Promise.race([latest, halted]);
43
+ if (failed) throw failure;
44
+ // Even a settled predecessor does not grant admission to the next call.
45
+ await Promise.race([input.admit(), halted]);
46
+ if (failed) throw failure;
47
+ },
48
+ onModelResponse: (event: StreamEvent): Promise<void> => {
49
+ if (failed) return Promise.reject(failure);
50
+ const id = responseId(event);
51
+ const existing =
52
+ receipts.get(event) ??
53
+ (id ? responseReceipts.get(id) : undefined) ??
54
+ (!id && pending.size === 1 ? pending.values().next().value : undefined);
55
+ if (existing) return existing.promise;
56
+ let resolve!: () => void;
57
+ let reject!: (error: unknown) => void;
58
+ const promise = new Promise<void>((yes, no) => {
59
+ resolve = yes;
60
+ reject = no;
61
+ });
62
+ // The next model entry awaits this receipt; rejection can happen sooner.
63
+ void promise.catch(() => undefined);
64
+ const receipt = { promise, resolve, reject };
65
+ receipts.set(event, receipt);
66
+ if (id) responseReceipts.set(id, receipt);
67
+ pending.add(receipt);
68
+ latest = promise;
69
+ return promise;
70
+ },
71
+ settle: (event: { type: string; data?: unknown }) => {
72
+ if (event.type !== "raw_model_stream_event" || !event.data || typeof event.data !== "object")
73
+ return;
74
+ if ((event.data as { type?: unknown }).type !== "response_done") return;
75
+ const id = responseId(event.data);
76
+ // Runner retry normalization copies response_done. It cannot create a
77
+ // second response before this receipt permits the next model entry.
78
+ const receipt =
79
+ receipts.get(event.data) ??
80
+ (id ? responseReceipts.get(id) : undefined) ??
81
+ (pending.size === 1 ? pending.values().next().value : undefined);
82
+ if (!receipt) return;
83
+ pending.delete(receipt);
84
+ if (id) responseReceipts.delete(id);
85
+ receipt.resolve();
86
+ },
87
+ fail,
88
+ close: () => {
89
+ input.signal.removeEventListener("abort", abort);
90
+ if (pending.size > 0) fail(new Error("Model stream closed before response settlement"));
91
+ responseReceipts.clear();
92
+ },
93
+ };
94
+ }