@opengeni/core 0.12.7 → 0.14.3

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 (39) hide show
  1. package/dist/access/index.d.ts +22 -0
  2. package/dist/application/new-session-drafts.d.ts +14 -0
  3. package/dist/application/session-commands.d.ts +107 -0
  4. package/dist/billing/limits.d.ts +29 -0
  5. package/dist/dependencies.d.ts +137 -0
  6. package/dist/domain/capabilities.d.ts +62 -0
  7. package/dist/domain/environments.d.ts +33 -0
  8. package/dist/domain/insights.d.ts +11 -0
  9. package/dist/domain/packs.d.ts +27 -0
  10. package/dist/domain/resources.d.ts +32 -0
  11. package/dist/domain/scheduled-tasks.d.ts +72 -0
  12. package/dist/domain/session-tool-policy.d.ts +31 -0
  13. package/dist/domain/sessions.d.ts +256 -0
  14. package/dist/domain/slack-bot.d.ts +19 -0
  15. package/dist/domain/workspace-members.d.ts +34 -0
  16. package/dist/index.d.ts +23 -1189
  17. package/dist/index.js +758 -115
  18. package/dist/index.js.map +1 -1
  19. package/dist/managed-auth-type.d.ts +2 -0
  20. package/dist/rigs/index.d.ts +57 -0
  21. package/dist/sandbox/fleet.d.ts +197 -0
  22. package/dist/sandbox/routing.d.ts +55 -0
  23. package/dist/sandbox-types.d.ts +52 -0
  24. package/dist/session-authorization.d.ts +36 -0
  25. package/dist/transcription.d.ts +71 -0
  26. package/dist/workflow-wake-contract.d.ts +4 -0
  27. package/package.json +11 -11
  28. package/src/access/index.ts +73 -2
  29. package/src/application/new-session-drafts.ts +3 -0
  30. package/src/application/session-commands.ts +22 -9
  31. package/src/dependencies.ts +5 -0
  32. package/src/domain/insights.ts +480 -0
  33. package/src/domain/session-tool-policy.ts +22 -39
  34. package/src/domain/sessions.ts +140 -72
  35. package/src/domain/slack-bot.ts +2 -4
  36. package/src/index.ts +2 -0
  37. package/src/sandbox/fleet.ts +96 -33
  38. package/src/sandbox/routing.ts +29 -7
  39. package/src/transcription.ts +142 -0
package/dist/index.js CHANGED
@@ -3,6 +3,79 @@ var SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID = "opengeni-session-workflow-wa
3
3
  var SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_TYPE = "sessionWorkflowWakeDispatcherWorkflow";
4
4
  var SESSION_WORKFLOW_WAKE_DISPATCHER_PERIOD_MS = 1e4;
5
5
 
6
+ // src/transcription.ts
7
+ var TranscriptionServiceError = class extends Error {
8
+ code;
9
+ status;
10
+ retryable;
11
+ constructor(input) {
12
+ super(input.message);
13
+ this.name = "TranscriptionServiceError";
14
+ this.code = input.code;
15
+ this.status = input.status ?? statusForVoiceInputError(input.code);
16
+ this.retryable = input.retryable ?? false;
17
+ }
18
+ };
19
+ function statusForVoiceInputError(code) {
20
+ switch (code) {
21
+ case "permission_denied":
22
+ return 403;
23
+ case "policy_blocked":
24
+ return 403;
25
+ case "not_supported":
26
+ return 415;
27
+ case "unavailable":
28
+ return 503;
29
+ case "too_large":
30
+ return 413;
31
+ case "invalid_audio":
32
+ return 400;
33
+ case "timeout":
34
+ return 504;
35
+ case "cancelled":
36
+ return 499;
37
+ case "network":
38
+ case "provider":
39
+ return 502;
40
+ case "unknown":
41
+ default:
42
+ return 500;
43
+ }
44
+ }
45
+ function normalizeMimeType(mimeType) {
46
+ return mimeType.trim().toLowerCase();
47
+ }
48
+ function isAcceptedMimeType(mimeType, accepted) {
49
+ const normalized = normalizeMimeType(mimeType);
50
+ if (accepted.some((candidate) => normalizeMimeType(candidate) === normalized)) {
51
+ return true;
52
+ }
53
+ const bare = normalized.split(";")[0]?.trim() ?? normalized;
54
+ return accepted.some((candidate) => {
55
+ const allowed = normalizeMimeType(candidate);
56
+ return allowed === bare || allowed.split(";")[0]?.trim() === bare;
57
+ });
58
+ }
59
+ function filenameForMimeType(mimeType) {
60
+ const bare = normalizeMimeType(mimeType).split(";")[0] ?? "audio/webm";
61
+ switch (bare) {
62
+ case "audio/mp4":
63
+ case "audio/m4a":
64
+ return "audio.mp4";
65
+ case "audio/ogg":
66
+ return "audio.ogg";
67
+ case "audio/mpeg":
68
+ case "audio/mp3":
69
+ return "audio.mp3";
70
+ case "audio/wav":
71
+ case "audio/x-wav":
72
+ return "audio.wav";
73
+ case "audio/webm":
74
+ default:
75
+ return "audio.webm";
76
+ }
77
+ }
78
+
6
79
  // src/sandbox/fleet.ts
7
80
  import {
8
81
  getEnrollment,
@@ -22,6 +95,7 @@ import {
22
95
  import { HTTPException } from "hono/http-exception";
23
96
 
24
97
  // src/sandbox/routing.ts
98
+ import { sandboxArchiveCaptureTimeoutMs } from "@opengeni/config";
25
99
  import {
26
100
  advanceWorkspaceGenerationForDirectRequest,
27
101
  advanceWorkspaceGenerationForRetainedProcess,
@@ -40,7 +114,8 @@ import {
40
114
  isProviderSandboxGoneDuringRoutedOperation,
41
115
  makeActiveBackendResolver,
42
116
  NatsControlRpc,
43
- RoutingSandboxSession
117
+ RoutingSandboxSession,
118
+ resolveModalCheckpointProviderBindingForSession
44
119
  } from "@opengeni/runtime/sandbox";
45
120
  function relayConfigFromSettings(settings) {
46
121
  const raw = settings.selfhostedRelayUrl?.trim();
@@ -94,7 +169,8 @@ function wrapChannelABoxWithRouting(services, ids, established) {
94
169
  if (backend.activeEpoch === void 0) {
95
170
  throw new Error("API-direct workspace mutation resolved without an active route epoch");
96
171
  }
97
- return await advanceWorkspaceGenerationForDirectRequest(db, {
172
+ const providerBinding = homeLease.backend === "modal" ? await resolveModalCheckpointProviderBindingForSession(settings, backend.session) : null;
173
+ const admission = await advanceWorkspaceGenerationForDirectRequest(db, {
98
174
  accountId: ids.accountId,
99
175
  workspaceId: ids.workspaceId,
100
176
  sessionId: ids.sessionId,
@@ -105,8 +181,10 @@ function wrapChannelABoxWithRouting(services, ids, established) {
105
181
  expectedInstanceId: backend.providerInstanceId,
106
182
  routeTargetId: backend.sandboxId,
107
183
  routeEpoch: backend.activeEpoch,
108
- operation: op
184
+ operation: op,
185
+ captureWaitMs: sandboxArchiveCaptureTimeoutMs(settings)
109
186
  });
187
+ return { admission, providerBinding };
110
188
  } : void 0;
111
189
  const afterMutation = homeLease ? async ({
112
190
  op,
@@ -116,10 +194,14 @@ function wrapChannelABoxWithRouting(services, ids, established) {
116
194
  retainedProcess
117
195
  }) => {
118
196
  if (admission === null) return;
119
- if (!admission || typeof admission !== "object" || typeof admission.id !== "string" || typeof admission.workspaceGeneration !== "number" || backend.leaseEpoch === void 0 || backend.providerInstanceId === void 0 || backend.activeEpoch === void 0) {
197
+ if (!admission || typeof admission !== "object" || backend.leaseEpoch === void 0 || backend.providerInstanceId === void 0 || backend.activeEpoch === void 0) {
120
198
  throw new Error("API-direct workspace mutation settlement lacked its exact admission");
121
199
  }
122
- const exactAdmission = admission;
200
+ const boundAdmission = admission;
201
+ const exactAdmission = boundAdmission.admission;
202
+ if (!exactAdmission || typeof exactAdmission.id !== "string" || typeof exactAdmission.workspaceGeneration !== "number" || !("providerBinding" in boundAdmission)) {
203
+ throw new Error("API-direct workspace mutation settlement lacked its bound admission");
204
+ }
123
205
  if (outcome === "resolved" && retainedProcess) {
124
206
  await retainWorkspaceMutationProcess(db, {
125
207
  accountId: ids.accountId,
@@ -130,6 +212,7 @@ function wrapChannelABoxWithRouting(services, ids, established) {
130
212
  admissionId: exactAdmission.id,
131
213
  admittedWorkspaceGeneration: exactAdmission.workspaceGeneration,
132
214
  operation: op,
215
+ providerBinding: boundAdmission.providerBinding ?? null,
133
216
  owner: {
134
217
  kind: "direct",
135
218
  requestId: ids.directRequest.requestId,
@@ -167,7 +250,8 @@ function wrapChannelABoxWithRouting(services, ids, established) {
167
250
  workspaceId: ids.workspaceId,
168
251
  sessionId: ids.sessionId,
169
252
  processId: process.id,
170
- operation: op
253
+ operation: op,
254
+ captureWaitMs: sandboxArchiveCaptureTimeoutMs(settings)
171
255
  }) : void 0;
172
256
  const afterProcessMutation = homeLease ? async ({
173
257
  op,
@@ -555,47 +639,37 @@ async function swapActiveSandbox(services, ctx, target, workingDir) {
555
639
  await readinessHold?.release().catch(() => void 0);
556
640
  }
557
641
  }
558
- async function runOnSandbox(services, ctx, target, op) {
559
- const sandbox = await getSandbox2(services.db, ctx.workspaceId, target);
560
- if (!sandbox) {
561
- return {
562
- target,
563
- kind: op.kind,
564
- ok: false,
565
- reason: `sandbox ${target} not found in this workspace`
566
- };
567
- }
568
- if (sandbox.kind !== "selfhosted" || !sandbox.enrollmentId) {
569
- return {
570
- target,
571
- kind: op.kind,
572
- ok: false,
573
- reason: `run_on routes one-off ops to enrolled selfhosted machines; ${sandbox.kind} targets are reached via the active sandbox (swap to it first)`
574
- };
575
- }
576
- const enrollment = await getEnrollment(services.db, ctx.workspaceId, sandbox.enrollmentId);
577
- if (!enrollment || enrollment.status !== "active") {
578
- return { target, kind: op.kind, ok: false, reason: `sandbox ${target} is not enrolled/active` };
579
- }
642
+ async function executeRunOnSelfhostedMachine(machine, target, op) {
580
643
  const session = new SelfhostedSession({
581
- workspaceId: ctx.workspaceId,
582
- agentId: sandbox.enrollmentId,
583
- controlRpc: controlRpc(services.bus),
584
- relay: relayConfigFromSettings(services.settings)
644
+ workspaceId: machine.workspaceId,
645
+ agentId: machine.agentId,
646
+ controlRpc: machine.controlRpc,
647
+ relay: machine.relay,
648
+ timeoutMs: machine.controlTimeoutMs,
649
+ execTimeoutMs: machine.execTimeoutMs
585
650
  });
586
651
  try {
587
652
  if (op.kind === "exec") {
653
+ const deadlineMs = session.effectiveExecDeadlineMs;
588
654
  const res = await session.exec({
589
655
  cmd: op.cmd,
590
656
  ...op.workdir ? { workdir: op.workdir } : {}
591
657
  });
658
+ const timedOut = res.timedOut === true;
659
+ const hasTerminalExit = res.exitCode !== null;
592
660
  return {
593
661
  target,
594
662
  kind: "exec",
595
- ok: true,
663
+ // `ok` means the one-off operation reached a terminal response. Preserve
664
+ // the established non-zero-exit behavior, but never claim success when
665
+ // the machine killed the child or returned no terminal exit proof.
666
+ ok: !timedOut && hasTerminalExit,
596
667
  stdout: res.stdout,
597
668
  stderr: res.stderr,
598
- exitCode: res.exitCode
669
+ exitCode: res.exitCode,
670
+ timedOut,
671
+ deadlineMs,
672
+ ...timedOut ? { reason: `command exceeded the ${deadlineMs} ms execution deadline` } : !hasTerminalExit ? { reason: "machine returned no terminal exit code" } : {}
599
673
  };
600
674
  }
601
675
  if (op.kind === "read") {
@@ -606,8 +680,51 @@ async function runOnSandbox(services, ctx, target, op) {
606
680
  return { target, kind: "write", ok: true, bytesWritten };
607
681
  } catch (error) {
608
682
  const reason = error instanceof Error ? error.message : String(error);
609
- return { target, kind: op.kind, ok: false, reason };
683
+ return {
684
+ target,
685
+ kind: op.kind,
686
+ ok: false,
687
+ reason,
688
+ // A transport failure is not evidence that the process itself timed out,
689
+ // so leave `timedOut` absent while still reporting the enforced deadline.
690
+ ...op.kind === "exec" ? { deadlineMs: session.effectiveExecDeadlineMs } : {}
691
+ };
692
+ }
693
+ }
694
+ async function runOnSandbox(services, ctx, target, op) {
695
+ const sandbox = await getSandbox2(services.db, ctx.workspaceId, target);
696
+ if (!sandbox) {
697
+ return {
698
+ target,
699
+ kind: op.kind,
700
+ ok: false,
701
+ reason: `sandbox ${target} not found in this workspace`
702
+ };
610
703
  }
704
+ if (sandbox.kind !== "selfhosted" || !sandbox.enrollmentId) {
705
+ return {
706
+ target,
707
+ kind: op.kind,
708
+ ok: false,
709
+ reason: `run_on routes one-off ops to enrolled selfhosted machines; ${sandbox.kind} targets are reached via the active sandbox (swap to it first)`
710
+ };
711
+ }
712
+ const enrollment = await getEnrollment(services.db, ctx.workspaceId, sandbox.enrollmentId);
713
+ if (!enrollment || enrollment.status !== "active") {
714
+ return { target, kind: op.kind, ok: false, reason: `sandbox ${target} is not enrolled/active` };
715
+ }
716
+ return executeRunOnSelfhostedMachine(
717
+ {
718
+ workspaceId: ctx.workspaceId,
719
+ agentId: sandbox.enrollmentId,
720
+ controlRpc: controlRpc(services.bus),
721
+ relay: relayConfigFromSettings(services.settings),
722
+ controlTimeoutMs: services.settings.sandboxSelfhostedControlTimeoutMs,
723
+ execTimeoutMs: services.settings.sandboxSelfhostedExecTimeoutMs
724
+ },
725
+ target,
726
+ op
727
+ );
611
728
  }
612
729
  async function provisionSandbox(services, ctx, input) {
613
730
  if (input.kind === "selfhosted") {
@@ -660,8 +777,34 @@ async function requireAccessContext(c, deps) {
660
777
  return context;
661
778
  }
662
779
  async function requireAccessGrant(c, deps, workspaceId, permission) {
780
+ return (await requireAccessGrantAuthorization(c, deps, workspaceId, permission)).grant;
781
+ }
782
+ function accessGrantAuthorizationFromContext(context, grant) {
783
+ const matchingAccountGrants = context.accountGrants.filter(
784
+ (candidate) => candidate.accountId === grant.accountId
785
+ );
786
+ const delegated = grant.metadata?.delegated === true;
787
+ const contextIntegrity = context.subjectId === grant.subjectId && context.accountGrants.every((candidate) => candidate.subjectId === context.subjectId) && context.workspaceGrants.every(
788
+ (candidate) => candidate.subjectId === context.subjectId && candidate.principalKind === grant.principalKind && candidate.metadata?.delegated === true === delegated && Boolean(candidate.serviceInitiator) === Boolean(grant.serviceInitiator) && Boolean(candidate.serviceInitiatorContext) === Boolean(grant.serviceInitiatorContext) && context.accountGrants.filter(
789
+ (accountGrant) => accountGrant.accountId === candidate.accountId
790
+ ).length === 1
791
+ ) && matchingAccountGrants.length === 1 && matchingAccountGrants[0]?.subjectId === context.subjectId;
792
+ return {
793
+ grant,
794
+ accountGrant: contextIntegrity ? matchingAccountGrants[0] : null,
795
+ authenticatedSubjectId: context.subjectId,
796
+ contextIntegrity
797
+ };
798
+ }
799
+ async function requireAccessGrantAuthorization(c, deps, workspaceId, permission) {
663
800
  const context = await requireAccessContext(c, deps);
664
- const grant = context.workspaceGrants.find((candidate) => candidate.workspaceId === workspaceId) ?? await getWorkspaceGrant(deps.db, context.subjectId, workspaceId);
801
+ const principalKind = hostedHumanSessionPrincipalKind(context);
802
+ const grant = context.workspaceGrants.find((candidate) => candidate.workspaceId === workspaceId) ?? await getWorkspaceGrant(
803
+ deps.db,
804
+ context.subjectId,
805
+ workspaceId,
806
+ principalKind ? { principalKind } : void 0
807
+ );
665
808
  if (!grant) {
666
809
  const workspace = await requireWorkspace(deps.db, workspaceId).catch(() => null);
667
810
  if (!workspace) {
@@ -672,7 +815,15 @@ async function requireAccessGrant(c, deps, workspaceId, permission) {
672
815
  if (permission) {
673
816
  requirePermission(grant, permission);
674
817
  }
675
- return grant;
818
+ return accessGrantAuthorizationFromContext(context, grant);
819
+ }
820
+ function hostedHumanSessionPrincipalKind(context) {
821
+ if (context.mode !== "managed" || context.workspaceGrants.length === 0) {
822
+ return void 0;
823
+ }
824
+ return context.workspaceGrants.every(
825
+ (grant) => grant.principalKind === "human_session" && grant.metadata?.delegated !== true && !grant.serviceInitiator
826
+ ) ? "human_session" : void 0;
676
827
  }
677
828
  function requirePermission(grant, permission) {
678
829
  if (!hasPermission(grant.permissions, permission)) {
@@ -790,7 +941,8 @@ async function apiKeyAccessContext(c, deps, mode) {
790
941
  accountId: apiKey.accountId,
791
942
  subjectId,
792
943
  subjectLabel: apiKey.name,
793
- permissions: apiKey.permissions
944
+ permissions: apiKey.permissions,
945
+ principalKind: "api_key"
794
946
  }
795
947
  ] : [],
796
948
  defaultAccountId: apiKey.accountId,
@@ -824,6 +976,7 @@ async function delegatedAccessContext(c, deps, mode, token = bearerToken(c)) {
824
976
  subjectId: payload.subjectId,
825
977
  ...payload.subjectLabel ? { subjectLabel: payload.subjectLabel } : {},
826
978
  permissions: payload.permissions,
979
+ principalKind: payload.principalKind,
827
980
  // sessionId is worker-asserted (HMAC-signed token claim), not agent
828
981
  // controlled; it scopes session-bound MCP tools such as goal management.
829
982
  metadata: {
@@ -3241,6 +3394,10 @@ var PROJECTABLE_REGISTRY_ID = /^[A-Za-z0-9_-]+$/;
3241
3394
  function sortedIds(ids) {
3242
3395
  return [...new Set(ids)].sort();
3243
3396
  }
3397
+ function defaultSessionMcpServerIds(servers) {
3398
+ const mandatory = new Set(MANDATORY_SESSION_MCP_SERVER_IDS);
3399
+ return sortedIds([...servers].map((server) => server.id).filter((id) => !mandatory.has(id)));
3400
+ }
3244
3401
  function projectIds(ids) {
3245
3402
  const projectable = ids.filter(
3246
3403
  (id) => id.length <= SESSION_EFFECTIVE_TOOL_POLICY_ID_MAX_LENGTH && PROJECTABLE_REGISTRY_ID.test(id)
@@ -3251,16 +3408,16 @@ function projectIds(ids) {
3251
3408
  };
3252
3409
  }
3253
3410
  function resolveSessionToolPolicy(input) {
3254
- const policy = input.toolPolicy ?? { mode: "legacy", inheritedFromSessionId: null };
3411
+ const policy = input.toolPolicy;
3255
3412
  const availableIds = new Set(input.availableMcpServerIds);
3256
3413
  const defaultIds = new Set(input.defaultMcpServerIds ?? []);
3257
3414
  const mandatoryIds = MANDATORY_SESSION_MCP_SERVER_IDS.filter(
3258
3415
  (id) => availableIds.has(id)
3259
3416
  );
3260
3417
  const mandatoryIdSet = new Set(mandatoryIds);
3261
- const selectedRefs = input.turnToolsProvided === true ? mergeToolRefs2([], input.turnTools ?? []) : input.turnToolsProvided === false ? mergeToolRefs2([], input.sessionTools) : mergeToolRefs2(input.sessionTools, input.turnTools ?? []);
3262
- const tracksWorkspaceDefaults = policy.mode === "workspace_default" && input.turnToolsProvided !== true;
3263
- let toolRefs = selectedRefs.filter((tool) => tool.optional !== true || availableIds.has(tool.id));
3418
+ const selectedRefs = mergeToolRefs2([], input.sessionTools);
3419
+ const tracksWorkspaceDefaults = policy.mode === "workspace_default";
3420
+ let toolRefs = selectedRefs.filter((tool) => availableIds.has(tool.id));
3264
3421
  if (tracksWorkspaceDefaults) {
3265
3422
  toolRefs = mergeToolRefs2(
3266
3423
  toolRefs,
@@ -3326,16 +3483,13 @@ function resolveSessionToolPolicy(input) {
3326
3483
  }
3327
3484
  };
3328
3485
  }
3329
- function sessionToolPolicyAllowsDefaultNativeTools(policy) {
3330
- return policy.mode === "workspace_default" && policy.lazyRouter.state === "required";
3331
- }
3332
3486
  async function workspaceSessionToolPolicyServerIds(db, workspaceId, settings) {
3333
3487
  const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(db, workspaceId, settings);
3334
3488
  return sortedIds(runtimeSettings.mcpServers.map((server) => server.id));
3335
3489
  }
3336
3490
  async function workspaceSessionToolPolicyDefaultServerIds(db, workspaceId, settings) {
3337
3491
  const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(db, workspaceId, settings);
3338
- return sortedIds(enabledCapabilityMcpToolRefs(settings, runtimeSettings).map((tool) => tool.id));
3492
+ return defaultSessionMcpServerIds(runtimeSettings.mcpServers);
3339
3493
  }
3340
3494
  function sessionWithEffectiveToolPolicy(session, workspaceServerIds, workspaceDefaultServerIds = []) {
3341
3495
  const availableIds = new Set(workspaceServerIds);
@@ -3345,7 +3499,7 @@ function sessionWithEffectiveToolPolicy(session, workspaceServerIds, workspaceDe
3345
3499
  return {
3346
3500
  ...session,
3347
3501
  effectiveToolPolicy: resolveSessionToolPolicy({
3348
- ...session.toolPolicy ? { toolPolicy: session.toolPolicy } : {},
3502
+ toolPolicy: session.toolPolicy,
3349
3503
  sessionTools: session.tools,
3350
3504
  availableMcpServerIds: availableIds,
3351
3505
  defaultMcpServerIds: workspaceDefaultServerIds
@@ -3367,7 +3521,7 @@ import {
3367
3521
  import { HTTPException as HTTPException11 } from "hono/http-exception";
3368
3522
 
3369
3523
  // src/domain/sessions.ts
3370
- import { CODEX_MODEL_ID_PREFIX } from "@opengeni/codex";
3524
+ import { CODEX_MODEL_ID_PREFIX, isCodexBilledModel } from "@opengeni/codex";
3371
3525
  import {
3372
3526
  canonicalizeConfiguredModelId,
3373
3527
  configuredAllowedModels,
@@ -3378,11 +3532,13 @@ import {
3378
3532
  CreateSessionRequest,
3379
3533
  DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
3380
3534
  DEFAULT_FIRST_PARTY_MCP_TOOLS,
3535
+ FIRST_PARTY_MCP_TOOL_NAMES,
3381
3536
  OPENGENI_SLACK_BOT_SESSION_METADATA_KEY as OPENGENI_SLACK_BOT_SESSION_METADATA_KEY2,
3382
3537
  SessionSpawnDenial,
3383
3538
  ServiceTurnInitiator,
3384
3539
  ServiceTurnInitiatorContext,
3385
3540
  evaluateWorkspaceModelPolicy,
3541
+ latencyModeForMetadata,
3386
3542
  reasoningEffortForMetadata,
3387
3543
  stableJson as stableJson2,
3388
3544
  SessionMcpApprovalPolicy
@@ -3430,10 +3586,10 @@ import { HTTPException as HTTPException10 } from "hono/http-exception";
3430
3586
  // src/domain/slack-bot.ts
3431
3587
  import {
3432
3588
  OPENGENI_SLACK_BOT_CREDENTIAL_LABEL,
3433
- OPENGENI_SLACK_BOT_REQUIRED_SCOPES,
3434
3589
  OPENGENI_SLACK_BOT_CREDENTIAL_ROLE,
3435
3590
  OPENGENI_SLACK_BOT_SESSION_METADATA_KEY,
3436
- OpenGeniSlackBotConnectionMetadata
3591
+ OpenGeniSlackBotConnectionMetadata,
3592
+ areOpenGeniSlackBotScopesAccepted
3437
3593
  } from "@opengeni/contracts";
3438
3594
  import {
3439
3595
  getConnectionMetadata as getConnectionMetadata2
@@ -3444,8 +3600,7 @@ function openGeniSlackBotMetadata(metadata) {
3444
3600
  return parsed.success ? parsed.data : null;
3445
3601
  }
3446
3602
  function isOpenGeniSlackBotConnection(connection) {
3447
- const granted = new Set(connection.grantedScopes);
3448
- return connection.verifiedInstallAt != null && connection.verifiedInstallVersion === connection.version && connection.subjectId === null && connection.providerDomain === "slack.com" && connection.kind === "app_install" && granted.size === OPENGENI_SLACK_BOT_REQUIRED_SCOPES.length && OPENGENI_SLACK_BOT_REQUIRED_SCOPES.every((scope) => granted.has(scope)) && openGeniSlackBotMetadata(connection.metadata)?.credentialRole === OPENGENI_SLACK_BOT_CREDENTIAL_ROLE;
3603
+ return connection.verifiedInstallAt != null && connection.verifiedInstallVersion === connection.version && connection.subjectId === null && connection.providerDomain === "slack.com" && connection.kind === "app_install" && areOpenGeniSlackBotScopesAccepted(connection.grantedScopes) && openGeniSlackBotMetadata(connection.metadata)?.credentialRole === OPENGENI_SLACK_BOT_CREDENTIAL_ROLE;
3449
3604
  }
3450
3605
  function hasReservedOpenGeniSlackBotMetadata(metadata) {
3451
3606
  return metadata?.credentialRole === OPENGENI_SLACK_BOT_CREDENTIAL_ROLE || metadata?.credentialLabel === OPENGENI_SLACK_BOT_CREDENTIAL_LABEL;
@@ -3502,7 +3657,7 @@ var SessionSpawnDeniedError = class extends Error {
3502
3657
  };
3503
3658
  function resolveFirstPartyMcpToolsForCreate(requested, parentStored) {
3504
3659
  if (requested !== void 0) return [...requested];
3505
- if (parentStored === void 0) return null;
3660
+ if (parentStored === void 0) return [...DEFAULT_FIRST_PARTY_MCP_TOOLS];
3506
3661
  return [...parentStored ?? DEFAULT_FIRST_PARTY_MCP_TOOLS];
3507
3662
  }
3508
3663
  function sessionSpawnDeniedMessage(denial) {
@@ -3786,7 +3941,8 @@ async function createAndStartSession(input) {
3786
3941
  const sessionMetadata = {
3787
3942
  ...input.metadata,
3788
3943
  model: input.model,
3789
- reasoningEffort: input.reasoningEffort
3944
+ reasoningEffort: input.reasoningEffort,
3945
+ ...input.latencyMode !== void 0 ? { latencyMode: input.latencyMode } : {}
3790
3946
  };
3791
3947
  if (input.createIdempotencyKey) {
3792
3948
  const keyedResult = await createSessionWithIdempotencyKeyResult(input.db, {
@@ -3798,7 +3954,7 @@ async function createAndStartSession(input) {
3798
3954
  resources: input.resources,
3799
3955
  skills: input.skills ?? [],
3800
3956
  tools: input.tools,
3801
- ...input.toolPolicy ? { toolPolicy: input.toolPolicy } : {},
3957
+ toolPolicy: input.toolPolicy,
3802
3958
  metadata: sessionMetadata,
3803
3959
  ...input.createdBy ? { createdBy: input.createdBy } : {},
3804
3960
  ...input.createdByContext ? { createdByContext: input.createdByContext } : {},
@@ -3809,7 +3965,7 @@ async function createAndStartSession(input) {
3809
3965
  rigId: input.rigId ?? null,
3810
3966
  rigVersionId: input.rigVersionId ?? null,
3811
3967
  firstPartyMcpPermissions: input.firstPartyMcpPermissions ?? null,
3812
- firstPartyMcpTools: input.firstPartyMcpTools ?? null,
3968
+ firstPartyMcpTools: input.firstPartyMcpTools,
3813
3969
  instructions: input.instructions ?? null,
3814
3970
  parentSessionId: input.parentSessionId ?? null,
3815
3971
  createIdempotencyKey: input.createIdempotencyKey,
@@ -3843,7 +3999,7 @@ async function createAndStartSession(input) {
3843
3999
  resources: input.resources,
3844
4000
  skills: input.skills ?? [],
3845
4001
  tools: input.tools,
3846
- ...input.toolPolicy ? { toolPolicy: input.toolPolicy } : {},
4002
+ toolPolicy: input.toolPolicy,
3847
4003
  metadata: sessionMetadata,
3848
4004
  ...input.createdBy ? { createdBy: input.createdBy } : {},
3849
4005
  ...input.createdByContext ? { createdByContext: input.createdByContext } : {},
@@ -3854,7 +4010,7 @@ async function createAndStartSession(input) {
3854
4010
  rigId: input.rigId ?? null,
3855
4011
  rigVersionId: input.rigVersionId ?? null,
3856
4012
  firstPartyMcpPermissions: input.firstPartyMcpPermissions ?? null,
3857
- firstPartyMcpTools: input.firstPartyMcpTools ?? null,
4013
+ firstPartyMcpTools: input.firstPartyMcpTools,
3858
4014
  instructions: input.instructions ?? null,
3859
4015
  parentSessionId: input.parentSessionId ?? null,
3860
4016
  sandboxGroupId: input.sandboxGroupId ?? null,
@@ -3908,7 +4064,7 @@ async function finishStartSession(input, session) {
3908
4064
  reasoningEffortFallback: input.reasoningEffort,
3909
4065
  turnExecutionPolicy: input.turnExecutionPolicy,
3910
4066
  createdEventPayload: {
3911
- ...input.toolPolicy ? { toolPolicy: input.toolPolicy } : {},
4067
+ toolPolicy: input.toolPolicy,
3912
4068
  ...input.variableSet ? { variableSetId: input.variableSet.id, variableSetName: input.variableSet.name } : {},
3913
4069
  ...input.sessionMcpServers?.length ? { mcpServers: input.sessionMcpServers } : {}
3914
4070
  },
@@ -3952,6 +4108,24 @@ function canonicalConfiguredModel(settings, model) {
3952
4108
  function assertConfiguredModel(settings, model) {
3953
4109
  canonicalConfiguredModel(settings, model);
3954
4110
  }
4111
+ var CODEX_COMPACTION_V2_PROVIDER_LOCKED = "codex_compaction_v2_provider_locked";
4112
+ var CodexCompactionV2ProviderLockedError = class extends Error {
4113
+ code = CODEX_COMPACTION_V2_PROVIDER_LOCKED;
4114
+ productModelId;
4115
+ constructor(productModelId) {
4116
+ super(
4117
+ `session is locked to Codex remote compaction v2; model "${productModelId}" is not a Codex subscription model`
4118
+ );
4119
+ this.name = "CodexCompactionV2ProviderLockedError";
4120
+ this.productModelId = productModelId;
4121
+ }
4122
+ };
4123
+ function assertSessionAllowsProductModel(session, productModelId) {
4124
+ if (productModelId === null || productModelId === void 0) return;
4125
+ if (session.codexCompactionMode !== "remote_v2") return;
4126
+ if (isCodexBilledModel(productModelId)) return;
4127
+ throw new CodexCompactionV2ProviderLockedError(productModelId);
4128
+ }
3955
4129
  async function assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model) {
3956
4130
  if (model === null || model === void 0) {
3957
4131
  return;
@@ -3990,12 +4164,25 @@ async function requireQueuedTurnForApi(db, workspaceId, sessionId, turnId) {
3990
4164
  function reasoningEffortForSession(metadata, fallback) {
3991
4165
  return reasoningEffortForMetadata(metadata, fallback);
3992
4166
  }
4167
+ function latencyModeForSession(metadata, fallback = "standard") {
4168
+ return latencyModeForMetadata(metadata, fallback);
4169
+ }
3993
4170
  async function postUserMessageTurn(input) {
3994
4171
  const { db, bus, workflowClient, settings, accountId, workspaceId, sessionId } = input;
3995
4172
  const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
3996
4173
  const requestedReasoningEffort = input.reasoningEffort ?? null;
3997
4174
  assertConfiguredModel(settings, requestedModel);
3998
4175
  await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, requestedModel);
4176
+ const sessionForModelGate = await requireSession2(db, workspaceId, sessionId);
4177
+ const effectiveModelForGate = requestedModel ?? sessionForModelGate.model;
4178
+ try {
4179
+ assertSessionAllowsProductModel(sessionForModelGate, effectiveModelForGate);
4180
+ } catch (error) {
4181
+ if (error instanceof CodexCompactionV2ProviderLockedError) {
4182
+ throw new HTTPException10(422, { message: error.message, cause: error });
4183
+ }
4184
+ throw error;
4185
+ }
3999
4186
  const operationKey = input.clientEventId ?? crypto.randomUUID();
4000
4187
  let result;
4001
4188
  try {
@@ -4021,10 +4208,9 @@ async function postUserMessageTurn(input) {
4021
4208
  text: input.text,
4022
4209
  turnInstructions: input.turnInstructions ?? null,
4023
4210
  resources: input.resources,
4024
- tools: input.tools,
4025
- toolsProvided: input.toolsProvided,
4026
4211
  model: requestedModel,
4027
4212
  reasoningEffort: requestedReasoningEffort,
4213
+ latencyMode: input.latencyMode ?? null,
4028
4214
  reasoningEffortFallback: input.reasoningEffortFallback ?? settings.openaiReasoningEffort,
4029
4215
  turnExecutionPolicy: input.turnExecutionPolicy,
4030
4216
  source: input.origin === "operator" ? "api" : "user",
@@ -4215,12 +4401,15 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
4215
4401
  }
4216
4402
  await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model);
4217
4403
  const reasoningEffort = payload.reasoningEffort ?? settings.openaiReasoningEffort;
4404
+ const latencyMode = payload.latencyMode ?? "standard";
4218
4405
  const turnExecutionPolicy = resolveTurnExecutionPolicyV1(settings, {
4219
4406
  modelId: model,
4220
4407
  requestedModelId: payload.model ?? null,
4221
4408
  modelSource: payload.model === void 0 ? "deployment" : "explicit",
4222
4409
  reasoningEffort,
4223
- reasoningSource: payload.reasoningEffort === void 0 ? "deployment" : "explicit"
4410
+ reasoningSource: payload.reasoningEffort === void 0 ? "deployment" : "explicit",
4411
+ latencyMode,
4412
+ latencyModeSource: payload.latencyMode === void 0 ? "deployment" : "explicit"
4224
4413
  });
4225
4414
  const parentFirstPartyMcpPermissions = parentSession ? [...parentSession.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS] : null;
4226
4415
  if (parentFirstPartyMcpPermissions && payload.firstPartyMcpPermissions?.some(
@@ -4255,9 +4444,8 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
4255
4444
  parentSession ? parentSession.firstPartyMcpTools : void 0
4256
4445
  );
4257
4446
  if (payload.goal) {
4258
- const effectiveTools = firstPartyMcpTools ?? [...DEFAULT_FIRST_PARTY_MCP_TOOLS];
4259
4447
  const missingGoalTools = ["goal_update", "goal_complete", "goal_pause"].filter(
4260
- (name) => !effectiveTools.includes(name)
4448
+ (name) => !firstPartyMcpTools.includes(name)
4261
4449
  );
4262
4450
  if (missingGoalTools.length > 0) {
4263
4451
  throw new HTTPException10(422, {
@@ -4385,6 +4573,7 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
4385
4573
  ...payload.clientEventId ? { clientEventId: payload.clientEventId } : {},
4386
4574
  model,
4387
4575
  reasoningEffort,
4576
+ latencyMode,
4388
4577
  turnExecutionPolicy,
4389
4578
  // A shared spawn inherits the box's backend; a caller-supplied
4390
4579
  // sandboxBackend on a shared spawn is ignored (it is the same box). A
@@ -4458,61 +4647,43 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
4458
4647
  return session;
4459
4648
  }
4460
4649
  async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, input) {
4461
- if (input.toolsProvided && !deps.settings.sessionTurnToolReplacementEnabled) {
4462
- throw new HTTPException10(503, {
4463
- message: "explicit follow-up tool replacement is temporarily unavailable until provenance-aware turn workers finish rolling out; omit tools to inherit the session policy and retry"
4464
- });
4465
- }
4466
4650
  const { settings, db, bus, workflowClient, objectStorage } = deps;
4467
4651
  await requireSessionAuthorization(deps, grant, {
4468
4652
  sessionId,
4469
4653
  operation: input.delivery === "steer" ? "session.steer" : "session.append",
4470
4654
  surface: "core"
4471
4655
  });
4472
- const capabilityRuntimeSettings = await settingsWithEnabledCapabilityMcpServers(
4473
- db,
4474
- workspaceId,
4475
- settings
4476
- );
4477
4656
  const existingSession = await requireSession2(db, workspaceId, sessionId);
4478
4657
  const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
4479
4658
  const effectiveModel = canonicalConfiguredModel(settings, requestedModel ?? existingSession.model) ?? null;
4480
4659
  if (effectiveModel === null) {
4481
4660
  throw new Error("effective follow-up model unexpectedly resolved to null");
4482
4661
  }
4662
+ try {
4663
+ assertSessionAllowsProductModel(existingSession, effectiveModel);
4664
+ } catch (error) {
4665
+ if (error instanceof CodexCompactionV2ProviderLockedError) {
4666
+ throw new HTTPException10(422, { message: error.message, cause: error });
4667
+ }
4668
+ throw error;
4669
+ }
4483
4670
  const sessionReasoningEffort = reasoningEffortForSession(
4484
4671
  existingSession.metadata,
4485
4672
  settings.openaiReasoningEffort
4486
4673
  );
4487
4674
  const effectiveReasoningEffort = input.reasoningEffort ?? sessionReasoningEffort;
4675
+ const sessionLatencyMode = latencyModeForSession(existingSession.metadata, "standard");
4676
+ const effectiveLatencyMode = input.latencyMode ?? sessionLatencyMode;
4488
4677
  const turnExecutionPolicy = resolveTurnExecutionPolicyV1(settings, {
4489
4678
  modelId: effectiveModel,
4490
4679
  requestedModelId: input.model ?? null,
4491
4680
  modelSource: input.model == null ? "session" : "explicit",
4492
4681
  reasoningEffort: effectiveReasoningEffort,
4493
- reasoningSource: input.reasoningEffort == null ? "session" : "explicit"
4682
+ reasoningSource: input.reasoningEffort == null ? "session" : "explicit",
4683
+ latencyMode: effectiveLatencyMode,
4684
+ latencyModeSource: input.latencyMode == null ? "session" : "explicit"
4494
4685
  });
4495
- const runtimeSettings = settingsWithSessionMcpServerMetadata(
4496
- capabilityRuntimeSettings,
4497
- existingSession.mcpServers
4498
- );
4499
4686
  const requestedResources = normalizeResources(input.resources ?? []);
4500
- const tracksWorkspaceDefaults = existingSession.toolPolicy?.mode === "workspace_default";
4501
- const sessionPolicyTools = withFirstPartyTools(
4502
- tracksWorkspaceDefaults ? withDefaultEnabledCapabilityMcpTools(
4503
- availableToolRefs(existingSession.tools, runtimeSettings),
4504
- settings,
4505
- capabilityRuntimeSettings
4506
- ) : existingSession.tools,
4507
- runtimeSettings
4508
- );
4509
- const validatedTools = input.toolsProvided ? validateToolRefsForSessionPolicy({
4510
- requested: input.tools ?? [],
4511
- settings: runtimeSettings,
4512
- allowedTools: sessionPolicyTools,
4513
- message: "message tools may only narrow the session tool policy"
4514
- }) : [];
4515
- const requestedTools = input.toolsProvided ? validatedTools : [];
4516
4687
  await requireLimit(deps, {
4517
4688
  accountId: grant.accountId,
4518
4689
  workspaceId,
@@ -4546,10 +4717,9 @@ async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, inp
4546
4717
  text: input.text,
4547
4718
  turnInstructions: input.turnInstructions ?? null,
4548
4719
  resources: requestedResources,
4549
- tools: requestedTools,
4550
- toolsProvided: input.toolsProvided,
4551
4720
  model: input.model ?? null,
4552
4721
  reasoningEffort: input.reasoningEffort ?? null,
4722
+ latencyMode: input.latencyMode ?? null,
4553
4723
  reasoningEffortFallback: sessionReasoningEffort,
4554
4724
  turnExecutionPolicy,
4555
4725
  mcpCredentialUpdates,
@@ -4654,7 +4824,7 @@ async function updateSessionMcpApprovalPolicy(deps, grant, sessionId, serverId,
4654
4824
  effectiveFrom: "next_attempt"
4655
4825
  };
4656
4826
  }
4657
- function toolPolicyAuditSnapshot(session, tools, policy = session.toolPolicy ?? { mode: "legacy", inheritedFromSessionId: null }) {
4827
+ function toolPolicyAuditSnapshot(session, tools, firstPartyMcpTools, policy = session.toolPolicy) {
4658
4828
  const allToolRefs = mergeToolRefs([], tools).sort((left, right) => {
4659
4829
  const leftMandatory = left.kind === "mcp" && left.id === "opengeni";
4660
4830
  const rightMandatory = right.kind === "mcp" && right.id === "opengeni";
@@ -4673,6 +4843,8 @@ function toolPolicyAuditSnapshot(session, tools, policy = session.toolPolicy ??
4673
4843
  toolIds: [...toolRefs].sort((left, right) => `${left.kind}:${left.id}`.localeCompare(`${right.kind}:${right.id}`)).map((tool) => tool.id),
4674
4844
  toolRefs,
4675
4845
  toolCount: allToolRefs.length,
4846
+ firstPartyMcpTools: [...firstPartyMcpTools].sort(),
4847
+ firstPartyMcpToolCount: firstPartyMcpTools.length,
4676
4848
  truncated: allToolRefs.length > toolRefs.length
4677
4849
  };
4678
4850
  }
@@ -4706,10 +4878,12 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4706
4878
  }
4707
4879
  return withFirstPartyTools(validatedTools, runtimeSettings);
4708
4880
  })() : null;
4881
+ const explicitRequestedFirstPartyTools = explicitRequest ? [...explicitRequest.firstPartyMcpTools] : null;
4709
4882
  const workspaceDefaultTools = withFirstPartyTools(
4710
4883
  withDefaultEnabledCapabilityMcpTools([], deps.settings, capabilityRuntimeSettings),
4711
4884
  runtimeSettings
4712
4885
  );
4886
+ const workspaceDefaultFirstPartyTools = [...FIRST_PARTY_MCP_TOOL_NAMES];
4713
4887
  const events = await appendSessionEventsWithLockedSessionUpdate(
4714
4888
  deps.db,
4715
4889
  grant.workspaceId,
@@ -4720,6 +4894,7 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4720
4894
  throw new SessionToolPolicyVersionConflictError(currentVersion);
4721
4895
  }
4722
4896
  let nextTools;
4897
+ let nextFirstPartyMcpTools;
4723
4898
  let nextPolicy;
4724
4899
  if (session.parentSessionId) {
4725
4900
  const parent = await context.getLockedSession(session.parentSessionId);
@@ -4735,6 +4910,9 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4735
4910
  ) : parent.tools,
4736
4911
  runtimeSettings
4737
4912
  );
4913
+ const parentFirstPartyMcpTools = [
4914
+ ...parent.firstPartyMcpTools ?? DEFAULT_FIRST_PARTY_MCP_TOOLS
4915
+ ];
4738
4916
  if (requestedMode === "workspace_default") {
4739
4917
  if (!parentTracksWorkspaceDefaults) {
4740
4918
  throw new HTTPException10(403, {
@@ -4742,6 +4920,7 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4742
4920
  });
4743
4921
  }
4744
4922
  nextTools = parentEffective;
4923
+ nextFirstPartyMcpTools = parentFirstPartyMcpTools;
4745
4924
  nextPolicy = {
4746
4925
  mode: "workspace_default",
4747
4926
  inheritedFromSessionId: parent.id
@@ -4753,6 +4932,16 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4753
4932
  parentEffective,
4754
4933
  "session tools may only narrow the parent session tool policy"
4755
4934
  );
4935
+ const parentFirstPartySet = new Set(parentFirstPartyMcpTools);
4936
+ const widenedFirstPartyTool = explicitRequestedFirstPartyTools.find(
4937
+ (tool) => !parentFirstPartySet.has(tool)
4938
+ );
4939
+ if (widenedFirstPartyTool) {
4940
+ throw new HTTPException10(403, {
4941
+ message: `session OpenGeni tools may only narrow the parent policy: ${widenedFirstPartyTool}`
4942
+ });
4943
+ }
4944
+ nextFirstPartyMcpTools = explicitRequestedFirstPartyTools;
4756
4945
  nextPolicy = {
4757
4946
  mode: "explicit",
4758
4947
  inheritedFromSessionId: parent.id
@@ -4760,13 +4949,19 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4760
4949
  }
4761
4950
  } else {
4762
4951
  nextTools = requestedMode === "workspace_default" ? workspaceDefaultTools : explicitRequestedTools;
4952
+ nextFirstPartyMcpTools = requestedMode === "workspace_default" ? workspaceDefaultFirstPartyTools : explicitRequestedFirstPartyTools;
4763
4953
  nextPolicy = { mode: requestedMode, inheritedFromSessionId: null };
4764
4954
  }
4765
- const currentPolicy = session.toolPolicy ?? {
4766
- mode: "legacy",
4767
- inheritedFromSessionId: null
4768
- };
4769
- const unchanged = stableJson2({ tools: session.tools, policy: currentPolicy }) === stableJson2({ tools: nextTools, policy: nextPolicy });
4955
+ const currentPolicy = session.toolPolicy;
4956
+ const unchanged = stableJson2({
4957
+ tools: session.tools,
4958
+ firstPartyMcpTools: session.firstPartyMcpTools ?? DEFAULT_FIRST_PARTY_MCP_TOOLS,
4959
+ policy: currentPolicy
4960
+ }) === stableJson2({
4961
+ tools: nextTools,
4962
+ firstPartyMcpTools: nextFirstPartyMcpTools,
4963
+ policy: nextPolicy
4964
+ });
4770
4965
  if (unchanged) {
4771
4966
  return { events: [] };
4772
4967
  }
@@ -4776,8 +4971,18 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4776
4971
  {
4777
4972
  type: "session.tool_policy.updated",
4778
4973
  payload: {
4779
- before: toolPolicyAuditSnapshot(session, session.tools, currentPolicy),
4780
- after: toolPolicyAuditSnapshot(session, nextTools, nextPolicy),
4974
+ before: toolPolicyAuditSnapshot(
4975
+ session,
4976
+ session.tools,
4977
+ [...session.firstPartyMcpTools ?? DEFAULT_FIRST_PARTY_MCP_TOOLS],
4978
+ currentPolicy
4979
+ ),
4980
+ after: toolPolicyAuditSnapshot(
4981
+ session,
4982
+ nextTools,
4983
+ nextFirstPartyMcpTools,
4984
+ nextPolicy
4985
+ ),
4781
4986
  version: nextVersion,
4782
4987
  effectiveFrom: "next_attempt"
4783
4988
  }
@@ -4785,6 +4990,7 @@ async function updateSessionToolPolicy(deps, grant, sessionId, request) {
4785
4990
  ],
4786
4991
  update: {
4787
4992
  tools: nextTools,
4993
+ firstPartyMcpTools: nextFirstPartyMcpTools,
4788
4994
  toolPolicy: nextPolicy,
4789
4995
  toolPolicyVersion: nextVersion,
4790
4996
  expectedToolPolicyVersion: request.expectedVersion
@@ -5076,6 +5282,424 @@ function trimmedScheduledTaskName(name) {
5076
5282
  return trimmed;
5077
5283
  }
5078
5284
 
5285
+ // src/domain/insights.ts
5286
+ import { configuredStaticUsageLimits as configuredStaticUsageLimits2 } from "@opengeni/config";
5287
+ import {
5288
+ WorkspaceInsightsSnapshot
5289
+ } from "@opengeni/contracts";
5290
+ import {
5291
+ aggregateModelCallFacts,
5292
+ aggregateModelCallFactsByDay,
5293
+ aggregateRootSessionDrivers,
5294
+ aggregateScheduleFacts,
5295
+ aggregateSessionDepth,
5296
+ aggregateWarmSecondsByGroup,
5297
+ countOnlineMachines,
5298
+ countScheduledTaskFires,
5299
+ countSessionsAttachedToGroups,
5300
+ enumerateUtcDays,
5301
+ listFloorSessions,
5302
+ listLiveWarmLeases,
5303
+ listModelCallFacets,
5304
+ listScheduledTasks,
5305
+ requireWorkspace as requireWorkspace3,
5306
+ sumUsageQuantity as sumUsageQuantity2,
5307
+ sumUsageQuantityByDay,
5308
+ sumUsageQuantityInRange
5309
+ } from "@opengeni/db";
5310
+ var MACHINE_HEARTBEAT_FRESH_MS = 12e4;
5311
+ function microsToUsd(micros) {
5312
+ return Math.round(micros / 1e6 * 100) / 100;
5313
+ }
5314
+ function cacheHitPct(cached, input) {
5315
+ if (input <= 0) return 0;
5316
+ return Math.min(100, Math.max(0, Math.round(cached / input * 100)));
5317
+ }
5318
+ function startOfUtcDay(date) {
5319
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
5320
+ }
5321
+ function startOfUtcMonth2(date) {
5322
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
5323
+ }
5324
+ function startOfUtcYear(date) {
5325
+ return new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
5326
+ }
5327
+ function resolveRangeWindow(range, now) {
5328
+ const until = now;
5329
+ let since;
5330
+ let rangeLabel;
5331
+ let priorLabel;
5332
+ let seriesLabel;
5333
+ let cacheSeriesLabel;
5334
+ switch (range) {
5335
+ case "today":
5336
+ since = startOfUtcDay(now);
5337
+ rangeLabel = "Today (UTC)";
5338
+ priorLabel = "Prior equal window";
5339
+ seriesLabel = "Credit $ (UTC day)";
5340
+ cacheSeriesLabel = "Cache hit %";
5341
+ break;
5342
+ case "week":
5343
+ since = new Date(startOfUtcDay(now).getTime() - 6 * 24 * 60 * 60 * 1e3);
5344
+ rangeLabel = "Last 7 days (UTC)";
5345
+ priorLabel = "Prior 7 days";
5346
+ seriesLabel = "Credit $ / day";
5347
+ cacheSeriesLabel = "Cache hit % / day";
5348
+ break;
5349
+ case "month":
5350
+ since = startOfUtcMonth2(now);
5351
+ rangeLabel = "This month (UTC)";
5352
+ priorLabel = "Prior equal window";
5353
+ seriesLabel = "Credit $ / day";
5354
+ cacheSeriesLabel = "Cache hit % / day";
5355
+ break;
5356
+ case "ytd":
5357
+ since = startOfUtcYear(now);
5358
+ rangeLabel = "Year to date (UTC)";
5359
+ priorLabel = "Prior equal window";
5360
+ seriesLabel = "Credit $ / day";
5361
+ cacheSeriesLabel = "Cache hit % / day";
5362
+ break;
5363
+ default: {
5364
+ const _exhaustive = range;
5365
+ throw new Error(`Unknown insights range: ${_exhaustive}`);
5366
+ }
5367
+ }
5368
+ const durationMs = until.getTime() - since.getTime();
5369
+ const priorUntil = since;
5370
+ const priorSince = new Date(priorUntil.getTime() - Math.max(durationMs, 1));
5371
+ return {
5372
+ since,
5373
+ until,
5374
+ priorSince,
5375
+ priorUntil,
5376
+ rangeLabel,
5377
+ priorLabel,
5378
+ seriesLabel,
5379
+ cacheSeriesLabel
5380
+ };
5381
+ }
5382
+ function ageLabel(updatedAt, now) {
5383
+ const ms = Math.max(0, now.getTime() - updatedAt.getTime());
5384
+ const minutes = Math.floor(ms / 6e4);
5385
+ if (minutes < 1) return "just now";
5386
+ if (minutes < 60) return `${minutes}m`;
5387
+ const hours = Math.floor(minutes / 60);
5388
+ if (hours < 48) return `${hours}h`;
5389
+ return `${Math.floor(hours / 24)}d`;
5390
+ }
5391
+ function floorState(input) {
5392
+ if (input.directControlState === "paused") return "paused";
5393
+ switch (input.status) {
5394
+ case "running":
5395
+ return "running";
5396
+ case "failed":
5397
+ return "failed";
5398
+ case "requires_action":
5399
+ case "waiting":
5400
+ return "waiting";
5401
+ case "compacting":
5402
+ return "compacting";
5403
+ case "completed":
5404
+ case "idle":
5405
+ case "queued":
5406
+ return "idle";
5407
+ default:
5408
+ return "idle";
5409
+ }
5410
+ }
5411
+ function billingPathOf(value) {
5412
+ return value === "external" ? "external" : "opengeni_credits";
5413
+ }
5414
+ async function getWorkspaceInsights(db, settings, input) {
5415
+ await requireWorkspace3(db, input.workspaceId);
5416
+ const now = input.now ?? /* @__PURE__ */ new Date();
5417
+ const window = resolveRangeWindow(input.range, now);
5418
+ const provider = input.provider?.trim() || null;
5419
+ const model = input.model?.trim() || null;
5420
+ const modelFilterActive = Boolean(provider || model);
5421
+ const filter = { provider, model };
5422
+ const [
5423
+ workspaceCreditMicros,
5424
+ priorWorkspaceCreditMicros,
5425
+ warmSeconds,
5426
+ priorWarmSeconds,
5427
+ modelRows,
5428
+ priorModelRows,
5429
+ factDays,
5430
+ warmDays,
5431
+ costDays,
5432
+ warmGroups,
5433
+ liveWarm,
5434
+ rootDrivers,
5435
+ scheduleFacts,
5436
+ tasks,
5437
+ depth,
5438
+ floorRows,
5439
+ machinesOnline,
5440
+ billableTokensUsed,
5441
+ agentRunsUsed,
5442
+ facets
5443
+ ] = await Promise.all([
5444
+ sumUsageQuantityInRange(db, {
5445
+ workspaceId: input.workspaceId,
5446
+ eventType: "model.cost",
5447
+ since: window.since,
5448
+ until: window.until
5449
+ }),
5450
+ sumUsageQuantityInRange(db, {
5451
+ workspaceId: input.workspaceId,
5452
+ eventType: "model.cost",
5453
+ since: window.priorSince,
5454
+ until: window.priorUntil
5455
+ }),
5456
+ sumUsageQuantityInRange(db, {
5457
+ workspaceId: input.workspaceId,
5458
+ eventType: "sandbox.warm_seconds",
5459
+ since: window.since,
5460
+ until: window.until
5461
+ }),
5462
+ sumUsageQuantityInRange(db, {
5463
+ workspaceId: input.workspaceId,
5464
+ eventType: "sandbox.warm_seconds",
5465
+ since: window.priorSince,
5466
+ until: window.priorUntil
5467
+ }),
5468
+ aggregateModelCallFacts(db, {
5469
+ workspaceId: input.workspaceId,
5470
+ since: window.since,
5471
+ until: window.until,
5472
+ ...filter
5473
+ }),
5474
+ aggregateModelCallFacts(db, {
5475
+ workspaceId: input.workspaceId,
5476
+ since: window.priorSince,
5477
+ until: window.priorUntil,
5478
+ ...filter
5479
+ }),
5480
+ aggregateModelCallFactsByDay(db, {
5481
+ workspaceId: input.workspaceId,
5482
+ since: window.since,
5483
+ until: window.until,
5484
+ ...filter
5485
+ }),
5486
+ sumUsageQuantityByDay(db, {
5487
+ workspaceId: input.workspaceId,
5488
+ eventType: "sandbox.warm_seconds",
5489
+ since: window.since,
5490
+ until: window.until
5491
+ }),
5492
+ sumUsageQuantityByDay(db, {
5493
+ workspaceId: input.workspaceId,
5494
+ eventType: "model.cost",
5495
+ since: window.since,
5496
+ until: window.until
5497
+ }),
5498
+ aggregateWarmSecondsByGroup(db, {
5499
+ workspaceId: input.workspaceId,
5500
+ since: window.since,
5501
+ until: window.until,
5502
+ limit: 24
5503
+ }),
5504
+ listLiveWarmLeases(db, input.workspaceId),
5505
+ aggregateRootSessionDrivers(db, {
5506
+ workspaceId: input.workspaceId,
5507
+ since: window.since,
5508
+ until: window.until,
5509
+ ...filter,
5510
+ limit: 8
5511
+ }),
5512
+ aggregateScheduleFacts(db, {
5513
+ workspaceId: input.workspaceId,
5514
+ since: window.since,
5515
+ until: window.until,
5516
+ ...filter
5517
+ }),
5518
+ listScheduledTasks(db, input.workspaceId, 100),
5519
+ aggregateSessionDepth(db, input.workspaceId),
5520
+ listFloorSessions(db, input.workspaceId, 24),
5521
+ settings.sandboxSelfhostedEnabled ? countOnlineMachines(db, input.workspaceId, MACHINE_HEARTBEAT_FRESH_MS) : Promise.resolve(0),
5522
+ sumUsageQuantity2(db, {
5523
+ workspaceId: input.workspaceId,
5524
+ eventType: "model.tokens",
5525
+ since: startOfUtcMonth2(now)
5526
+ }),
5527
+ sumUsageQuantity2(db, {
5528
+ workspaceId: input.workspaceId,
5529
+ eventType: "agent_run.created",
5530
+ since: startOfUtcMonth2(now)
5531
+ }),
5532
+ listModelCallFacets(db, {
5533
+ workspaceId: input.workspaceId,
5534
+ since: window.since,
5535
+ until: window.until
5536
+ })
5537
+ ]);
5538
+ const priorRootDrivers = await aggregateRootSessionDrivers(db, {
5539
+ workspaceId: input.workspaceId,
5540
+ since: window.priorSince,
5541
+ until: window.priorUntil,
5542
+ ...filter,
5543
+ rootSessionIds: rootDrivers.map((row) => row.rootSessionId)
5544
+ });
5545
+ const attached = await countSessionsAttachedToGroups(
5546
+ db,
5547
+ input.workspaceId,
5548
+ warmGroups.map((group) => group.groupId)
5549
+ );
5550
+ const backendByGroup = new Map(liveWarm.map((lease) => [lease.groupId, lease.backend]));
5551
+ const warmSecondsByGroup = new Map(warmGroups.map((group) => [group.groupId, group.warmSeconds]));
5552
+ const models = modelRows.map((row) => ({
5553
+ id: `${row.provider}:${row.model}:${row.billingPath}`,
5554
+ model: row.model,
5555
+ provider: row.provider,
5556
+ billing: billingPathOf(row.billingPath),
5557
+ calls: row.calls,
5558
+ inputTokens: row.inputTokens,
5559
+ outputTokens: row.outputTokens,
5560
+ cachedTokens: row.cachedTokens,
5561
+ cacheWriteTokens: row.cacheWriteTokens,
5562
+ reasoningTokens: row.reasoningTokens,
5563
+ creditUsd: microsToUsd(row.pricedCostMicros)
5564
+ })).sort((a, b) => b.inputTokens - a.inputTokens);
5565
+ const creditMicros = modelRows.reduce((sum, row) => sum + row.pricedCostMicros, 0);
5566
+ const priorCreditMicros = priorModelRows.reduce((sum, row) => sum + row.pricedCostMicros, 0);
5567
+ const priorInputTokens = priorModelRows.reduce((sum, row) => sum + row.inputTokens, 0);
5568
+ const priorCachedTokens = priorModelRows.reduce((sum, row) => sum + row.cachedTokens, 0);
5569
+ const priorCalls = priorModelRows.reduce((sum, row) => sum + row.calls, 0);
5570
+ const days = enumerateUtcDays(window.since, window.until);
5571
+ const series = days.map((day) => {
5572
+ const facts = factDays.get(day) ?? {
5573
+ costMicros: 0,
5574
+ inputTokens: 0,
5575
+ cachedTokens: 0,
5576
+ calls: 0
5577
+ };
5578
+ const modelCostMicros = modelFilterActive ? facts.costMicros : costDays.get(day) ?? facts.costMicros;
5579
+ return {
5580
+ label: day.slice(5),
5581
+ modelCostUsd: microsToUsd(modelCostMicros),
5582
+ warmSeconds: warmDays.get(day) ?? 0,
5583
+ inputTokens: facts.inputTokens,
5584
+ cachedTokens: facts.cachedTokens,
5585
+ cacheHitPct: cacheHitPct(facts.cachedTokens, facts.inputTokens),
5586
+ calls: facts.calls
5587
+ };
5588
+ });
5589
+ const priorDriverByRoot = new Map(
5590
+ priorRootDrivers.map((row) => [row.rootSessionId, row.pricedCostMicros])
5591
+ );
5592
+ const creditUsdForPct = Math.max(microsToUsd(creditMicros), 0.01);
5593
+ const drivers = rootDrivers.map((row) => {
5594
+ const creditUsd = microsToUsd(row.pricedCostMicros);
5595
+ const priorUsd = microsToUsd(priorDriverByRoot.get(row.rootSessionId) ?? 0);
5596
+ return {
5597
+ id: `root:${row.rootSessionId}`,
5598
+ groupBy: "root_session",
5599
+ label: row.title?.trim() || row.rootSessionId.slice(0, 8),
5600
+ creditUsd,
5601
+ tokens: row.inputTokens,
5602
+ cacheHitPct: cacheHitPct(row.cachedTokens, row.inputTokens),
5603
+ pctOfCreditUsd: Math.min(100, Math.round(creditUsd / creditUsdForPct * 100)),
5604
+ deltaUsdVsPrior: Math.round((creditUsd - priorUsd) * 100) / 100
5605
+ };
5606
+ });
5607
+ const fireCounts = await countScheduledTaskFires(db, {
5608
+ workspaceId: input.workspaceId,
5609
+ since: window.since,
5610
+ until: window.until,
5611
+ taskIds: tasks.map((task) => task.id)
5612
+ });
5613
+ const scheduleFactById = new Map(scheduleFacts.map((row) => [row.scheduledTaskId, row]));
5614
+ const schedules = tasks.map((task) => {
5615
+ const fact = scheduleFactById.get(task.id);
5616
+ return {
5617
+ id: task.id,
5618
+ name: task.name,
5619
+ fires: fireCounts.get(task.id) ?? 0,
5620
+ creditUsd: fact ? microsToUsd(fact.pricedCostMicros) : null,
5621
+ tokens: fact ? fact.inputTokens : null,
5622
+ cacheHitPct: fact ? cacheHitPct(fact.cachedTokens, fact.inputTokens) : null,
5623
+ billing: fact ? billingPathOf(fact.billingPath) : null
5624
+ };
5625
+ });
5626
+ const limits = configuredStaticUsageLimits2(settings);
5627
+ const floor = floorRows.filter((row) => {
5628
+ if (!model) return true;
5629
+ return row.model === model;
5630
+ }).map((row) => ({
5631
+ id: row.id,
5632
+ title: row.title?.trim() || "Untitled session",
5633
+ state: floorState(row),
5634
+ depth: row.nestedAgentDepth,
5635
+ model: row.model,
5636
+ provider: null,
5637
+ ageLabel: ageLabel(row.updatedAt, now),
5638
+ cacheHitPct: null,
5639
+ route: row.sandboxBackend
5640
+ }));
5641
+ const snapshot = WorkspaceInsightsSnapshot.parse({
5642
+ range: input.range,
5643
+ rangeLabel: window.rangeLabel,
5644
+ priorLabel: window.priorLabel,
5645
+ seriesLabel: window.seriesLabel,
5646
+ cacheSeriesLabel: window.cacheSeriesLabel,
5647
+ timezone: "UTC",
5648
+ models,
5649
+ facets,
5650
+ series,
5651
+ depth: depth.buckets.map((bucket) => ({
5652
+ depth: bucket.depth,
5653
+ sessions: bucket.sessions
5654
+ })),
5655
+ drivers,
5656
+ schedules,
5657
+ warmSeconds,
5658
+ priorWarmSeconds,
5659
+ warmGroups: warmGroups.map((group) => ({
5660
+ id: group.groupId,
5661
+ groupId: group.groupId,
5662
+ label: group.groupId.slice(0, 8),
5663
+ backend: backendByGroup.get(group.groupId) ?? null,
5664
+ warmSeconds: group.warmSeconds,
5665
+ sessionsAttached: attached.get(group.groupId) ?? 0
5666
+ })),
5667
+ liveWarm: liveWarm.map((lease) => ({
5668
+ id: lease.id,
5669
+ groupId: lease.groupId,
5670
+ backend: lease.backend,
5671
+ turnHolders: lease.turnHolders,
5672
+ viewerHolders: lease.viewerHolders,
5673
+ warmForLabel: lease.turnHolders > 0 ? "in use" : "idle warm",
5674
+ warmSeconds: warmSecondsByGroup.get(lease.groupId) ?? 0
5675
+ })),
5676
+ floor,
5677
+ selfhostedEnabled: settings.sandboxSelfhostedEnabled,
5678
+ machinesOnline,
5679
+ workspaceCreditUsd: microsToUsd(workspaceCreditMicros),
5680
+ priorWorkspaceCreditUsd: microsToUsd(priorWorkspaceCreditMicros),
5681
+ creditUsd: microsToUsd(creditMicros),
5682
+ priorCreditUsd: microsToUsd(priorCreditMicros),
5683
+ priorInputTokens,
5684
+ priorCacheHitPct: cacheHitPct(priorCachedTokens, priorInputTokens),
5685
+ priorCalls,
5686
+ goalsActive: depth.goalsActive,
5687
+ goalsCompleted: depth.goalsCompleted,
5688
+ sessionsTouched: depth.sessionsTouched,
5689
+ rootSessions: depth.rootSessions,
5690
+ deepestDepth: depth.deepestDepth,
5691
+ deepestSessionTitle: depth.deepestSessionTitle || "",
5692
+ avgDepth: Math.round(depth.avgDepth * 10) / 10,
5693
+ warmIdleNow: liveWarm.filter((lease) => lease.turnHolders === 0).length,
5694
+ billableTokensUsed,
5695
+ billableTokenCap: limits.maxMonthlyTokensPerWorkspace ?? null,
5696
+ agentRunsUsed,
5697
+ agentRunCap: limits.maxMonthlyAgentRunsPerWorkspace ?? null,
5698
+ modelFilterActive
5699
+ });
5700
+ return { snapshot };
5701
+ }
5702
+
5079
5703
  // src/domain/workspace-members.ts
5080
5704
  import { HTTPException as HTTPException12 } from "hono/http-exception";
5081
5705
  var MEMBER_ADMIN_PERMISSIONS = ["workspace:admin", "members:manage"];
@@ -5154,6 +5778,7 @@ function mapNewSessionDraft(row) {
5154
5778
  toolsProvided: newSessionDraftToolsProvided(row),
5155
5779
  model: row.model,
5156
5780
  reasoningEffort: row.reasoningEffort,
5781
+ latencyMode: row.latencyMode,
5157
5782
  options: publicNewSessionDraftOptions(row),
5158
5783
  updatedAt: row.updatedAt.toISOString()
5159
5784
  });
@@ -5246,6 +5871,7 @@ async function getActorNewSessionDraft(deps, grant, workspaceId) {
5246
5871
  toolsProvided: false,
5247
5872
  model: deps.settings.openaiModel,
5248
5873
  reasoningEffort: deps.settings.openaiReasoningEffort,
5874
+ latencyMode: "standard",
5249
5875
  options: {},
5250
5876
  updatedAt: null
5251
5877
  };
@@ -5284,6 +5910,7 @@ async function saveActorNewSessionDraft(deps, grant, workspaceId, rawInput) {
5284
5910
  toolsProvided,
5285
5911
  model: input.model,
5286
5912
  reasoningEffort: input.reasoningEffort,
5913
+ latencyMode: input.latencyMode,
5287
5914
  options: input.options,
5288
5915
  // Only managed people are removed through removeWorkspaceMember().
5289
5916
  // API keys and delegated service actors (for example the first-party
@@ -5303,7 +5930,7 @@ async function saveActorNewSessionDraft(deps, grant, workspaceId, rawInput) {
5303
5930
  }
5304
5931
 
5305
5932
  // src/application/session-commands.ts
5306
- import { reasoningEffortForMetadata as reasoningEffortForMetadata2 } from "@opengeni/contracts";
5933
+ import { latencyModeForMetadata as latencyModeForMetadata2, reasoningEffortForMetadata as reasoningEffortForMetadata2 } from "@opengeni/contracts";
5307
5934
  import {
5308
5935
  deleteSessionQueueItemInTransaction,
5309
5936
  editQueuedTurnInTransaction,
@@ -5355,14 +5982,14 @@ async function authorizeHumanSessionCommand(deps, context, operation) {
5355
5982
  return await requireSessionAuthorization(deps, humanAccessGrant(context), {
5356
5983
  sessionId: context.sessionId,
5357
5984
  operation,
5358
- surface: "core"
5985
+ surface: context.authorizationSurface ?? "core"
5359
5986
  });
5360
5987
  }
5361
5988
  async function authorizeAgentSessionCommand(deps, context, targetSessionId, operation) {
5362
5989
  return await requireSessionAuthorization(deps, agentAccessGrant(context), {
5363
5990
  sessionId: targetSessionId,
5364
5991
  operation,
5365
- surface: "core"
5992
+ surface: context.authorizationSurface ?? "core"
5366
5993
  });
5367
5994
  }
5368
5995
  function agentActor(context) {
@@ -5493,7 +6120,12 @@ async function steerAgentSession(deps, context, input) {
5493
6120
  return result;
5494
6121
  }
5495
6122
  async function controlAgentSessionWorkstream(deps, context, input) {
5496
- await authorizeAgentSessionCommand(deps, context, input.targetSessionId, "session.control");
6123
+ const authorization = await authorizeAgentSessionCommand(
6124
+ deps,
6125
+ context,
6126
+ input.targetSessionId,
6127
+ "session.control"
6128
+ );
5497
6129
  const result = await withWorkspaceRls(
5498
6130
  deps.db,
5499
6131
  context.workspaceId,
@@ -5514,7 +6146,7 @@ async function controlAgentSessionWorkstream(deps, context, input) {
5514
6146
  ]);
5515
6147
  await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
5516
6148
  await requestControlWakeDispatch(deps, result.wakeCount);
5517
- return result;
6149
+ return { ...result, authorization };
5518
6150
  }
5519
6151
  function receipt(row) {
5520
6152
  return {
@@ -5536,10 +6168,9 @@ function composerDraft(row) {
5536
6168
  revision: row.revision,
5537
6169
  text: row.text,
5538
6170
  resources: row.resources,
5539
- tools: row.tools,
5540
- toolsProvided: row.toolsProvided,
5541
6171
  model: row.model,
5542
6172
  reasoningEffort: row.reasoningEffort,
6173
+ latencyMode: row.latencyMode,
5543
6174
  sourceTurnId: row.sourceTurnId,
5544
6175
  sourceTurnVersion: row.sourceTurnVersion,
5545
6176
  updatedAt: row.updatedAt.toISOString()
@@ -5755,10 +6386,9 @@ async function getHumanComposerDraft(deps, context) {
5755
6386
  revision: 0,
5756
6387
  text: "",
5757
6388
  resources: [],
5758
- tools: [],
5759
- toolsProvided: false,
5760
6389
  model: session.model,
5761
6390
  reasoningEffort: reasoningEffortForMetadata2(session.metadata, "medium"),
6391
+ latencyMode: latencyModeForMetadata2(session.metadata, "standard"),
5762
6392
  sourceTurnId: null,
5763
6393
  sourceTurnVersion: null,
5764
6394
  updatedAt: null
@@ -5781,6 +6411,8 @@ async function saveHumanComposerDraft(deps, context, input) {
5781
6411
  return composerDraft(row);
5782
6412
  }
5783
6413
  export {
6414
+ CODEX_COMPACTION_V2_PROVIDER_LOCKED,
6415
+ CodexCompactionV2ProviderLockedError,
5784
6416
  MARKETING_SOCIAL_PACK_ID,
5785
6417
  MAX_CHECKS_PER_RIG,
5786
6418
  MAX_CREDENTIAL_HOOKS_PER_RIG,
@@ -5795,7 +6427,9 @@ export {
5795
6427
  SessionAuthorizationDeniedError,
5796
6428
  SessionAuthorizationUnavailableError,
5797
6429
  SessionSpawnDeniedError,
6430
+ TranscriptionServiceError,
5798
6431
  acceptSessionUserMessage,
6432
+ accessGrantAuthorizationFromContext,
5799
6433
  activateRigVersionForApi,
5800
6434
  appendRigSetupCommand,
5801
6435
  applyCapabilityEnablement,
@@ -5803,6 +6437,7 @@ export {
5803
6437
  assertAllowedVariableSetVariableName,
5804
6438
  assertConfiguredModel,
5805
6439
  assertPackSandboxImageCompatible,
6440
+ assertSessionAllowsProductModel,
5806
6441
  assertToolRefsSubset,
5807
6442
  assertWorkspaceDeletable,
5808
6443
  assertWorkspaceMemberRemovable,
@@ -5823,6 +6458,7 @@ export {
5823
6458
  createRigVersionForApi,
5824
6459
  createSessionForRequest,
5825
6460
  createValidatedScheduledTask,
6461
+ defaultSessionMcpServerIds,
5826
6462
  deleteHumanQueuePrompt,
5827
6463
  deleteRigForApi,
5828
6464
  disableCapability,
@@ -5830,17 +6466,22 @@ export {
5830
6466
  editHumanQueuePrompt,
5831
6467
  enableCapability,
5832
6468
  enabledCapabilityMcpToolRefs,
6469
+ executeRunOnSelfhostedMachine,
6470
+ filenameForMimeType,
5833
6471
  getActorNewSessionDraft,
5834
6472
  getCapabilityPack,
5835
6473
  getHumanComposerDraft,
6474
+ getWorkspaceInsights,
5836
6475
  hasPermission,
5837
6476
  hasReservedOpenGeniSlackBotMetadata,
5838
6477
  hasReservedOpenGeniSlackBotSessionMetadata,
6478
+ isAcceptedMimeType,
5839
6479
  isAuthoritativeGitHubRepositorySelectionError,
5840
6480
  isBuiltInCapabilityPack,
5841
6481
  isOpenGeniSlackBotConnection,
5842
6482
  isTrustedScheduledSlackBotSession,
5843
6483
  isUserMember,
6484
+ latencyModeForSession,
5844
6485
  listCapabilityPacks,
5845
6486
  listFleet,
5846
6487
  listRigChangesForApi,
@@ -5852,6 +6493,7 @@ export {
5852
6493
  mergeResourceRefs,
5853
6494
  mergeToolRefs,
5854
6495
  moveHumanQueuePrompt,
6496
+ normalizeMimeType,
5855
6497
  normalizeResources,
5856
6498
  officialMcpRegistryUrl,
5857
6499
  openGeniSlackBotMetadata,
@@ -5869,6 +6511,7 @@ export {
5869
6511
  relayDialBaseFromSettings,
5870
6512
  requireAccessContext,
5871
6513
  requireAccessGrant,
6514
+ requireAccessGrantAuthorization,
5872
6515
  requireEnvironmentEncryption,
5873
6516
  requireLimit,
5874
6517
  requireOpenGeniSlackBotConnection,
@@ -5897,13 +6540,13 @@ export {
5897
6540
  scheduledTaskTriggerToken,
5898
6541
  sendAgentSessionMessage,
5899
6542
  sessionSpawnDenialEnvelope,
5900
- sessionToolPolicyAllowsDefaultNativeTools,
5901
6543
  sessionWithEffectiveToolPolicy,
5902
6544
  settingsWithCodexAppsMcpServer,
5903
6545
  settingsWithEnabledCapabilityMcpServers,
5904
6546
  settingsWithMcpCapabilityServers,
5905
6547
  settingsWithSessionMcpServerMetadata,
5906
6548
  stableJson,
6549
+ statusForVoiceInputError,
5907
6550
  steerAgentSession,
5908
6551
  steerHumanQueuePrompt,
5909
6552
  swapActiveSandbox,