@opengeni/core 0.12.10 → 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 -1199
  17. package/dist/index.js +693 -53
  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 +3 -1
  31. package/src/dependencies.ts +5 -0
  32. package/src/domain/insights.ts +480 -0
  33. package/src/domain/session-tool-policy.ts +17 -25
  34. package/src/domain/sessions.ts +75 -4
  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
+ };
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
+ };
610
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)
@@ -3260,7 +3417,7 @@ function resolveSessionToolPolicy(input) {
3260
3417
  const mandatoryIdSet = new Set(mandatoryIds);
3261
3418
  const selectedRefs = mergeToolRefs2([], input.sessionTools);
3262
3419
  const tracksWorkspaceDefaults = policy.mode === "workspace_default";
3263
- let toolRefs = selectedRefs.filter((tool) => tool.optional !== true || availableIds.has(tool.id));
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);
@@ -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,
@@ -3384,6 +3538,7 @@ import {
3384
3538
  ServiceTurnInitiator,
3385
3539
  ServiceTurnInitiatorContext,
3386
3540
  evaluateWorkspaceModelPolicy,
3541
+ latencyModeForMetadata,
3387
3542
  reasoningEffortForMetadata,
3388
3543
  stableJson as stableJson2,
3389
3544
  SessionMcpApprovalPolicy
@@ -3431,10 +3586,10 @@ import { HTTPException as HTTPException10 } from "hono/http-exception";
3431
3586
  // src/domain/slack-bot.ts
3432
3587
  import {
3433
3588
  OPENGENI_SLACK_BOT_CREDENTIAL_LABEL,
3434
- OPENGENI_SLACK_BOT_REQUIRED_SCOPES,
3435
3589
  OPENGENI_SLACK_BOT_CREDENTIAL_ROLE,
3436
3590
  OPENGENI_SLACK_BOT_SESSION_METADATA_KEY,
3437
- OpenGeniSlackBotConnectionMetadata
3591
+ OpenGeniSlackBotConnectionMetadata,
3592
+ areOpenGeniSlackBotScopesAccepted
3438
3593
  } from "@opengeni/contracts";
3439
3594
  import {
3440
3595
  getConnectionMetadata as getConnectionMetadata2
@@ -3445,8 +3600,7 @@ function openGeniSlackBotMetadata(metadata) {
3445
3600
  return parsed.success ? parsed.data : null;
3446
3601
  }
3447
3602
  function isOpenGeniSlackBotConnection(connection) {
3448
- const granted = new Set(connection.grantedScopes);
3449
- 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;
3450
3604
  }
3451
3605
  function hasReservedOpenGeniSlackBotMetadata(metadata) {
3452
3606
  return metadata?.credentialRole === OPENGENI_SLACK_BOT_CREDENTIAL_ROLE || metadata?.credentialLabel === OPENGENI_SLACK_BOT_CREDENTIAL_LABEL;
@@ -3787,7 +3941,8 @@ async function createAndStartSession(input) {
3787
3941
  const sessionMetadata = {
3788
3942
  ...input.metadata,
3789
3943
  model: input.model,
3790
- reasoningEffort: input.reasoningEffort
3944
+ reasoningEffort: input.reasoningEffort,
3945
+ ...input.latencyMode !== void 0 ? { latencyMode: input.latencyMode } : {}
3791
3946
  };
3792
3947
  if (input.createIdempotencyKey) {
3793
3948
  const keyedResult = await createSessionWithIdempotencyKeyResult(input.db, {
@@ -3953,6 +4108,24 @@ function canonicalConfiguredModel(settings, model) {
3953
4108
  function assertConfiguredModel(settings, model) {
3954
4109
  canonicalConfiguredModel(settings, model);
3955
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
+ }
3956
4129
  async function assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model) {
3957
4130
  if (model === null || model === void 0) {
3958
4131
  return;
@@ -3991,12 +4164,25 @@ async function requireQueuedTurnForApi(db, workspaceId, sessionId, turnId) {
3991
4164
  function reasoningEffortForSession(metadata, fallback) {
3992
4165
  return reasoningEffortForMetadata(metadata, fallback);
3993
4166
  }
4167
+ function latencyModeForSession(metadata, fallback = "standard") {
4168
+ return latencyModeForMetadata(metadata, fallback);
4169
+ }
3994
4170
  async function postUserMessageTurn(input) {
3995
4171
  const { db, bus, workflowClient, settings, accountId, workspaceId, sessionId } = input;
3996
4172
  const requestedModel = canonicalConfiguredModel(settings, input.model ?? null) ?? null;
3997
4173
  const requestedReasoningEffort = input.reasoningEffort ?? null;
3998
4174
  assertConfiguredModel(settings, requestedModel);
3999
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
+ }
4000
4186
  const operationKey = input.clientEventId ?? crypto.randomUUID();
4001
4187
  let result;
4002
4188
  try {
@@ -4024,6 +4210,7 @@ async function postUserMessageTurn(input) {
4024
4210
  resources: input.resources,
4025
4211
  model: requestedModel,
4026
4212
  reasoningEffort: requestedReasoningEffort,
4213
+ latencyMode: input.latencyMode ?? null,
4027
4214
  reasoningEffortFallback: input.reasoningEffortFallback ?? settings.openaiReasoningEffort,
4028
4215
  turnExecutionPolicy: input.turnExecutionPolicy,
4029
4216
  source: input.origin === "operator" ? "api" : "user",
@@ -4214,12 +4401,15 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
4214
4401
  }
4215
4402
  await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model);
4216
4403
  const reasoningEffort = payload.reasoningEffort ?? settings.openaiReasoningEffort;
4404
+ const latencyMode = payload.latencyMode ?? "standard";
4217
4405
  const turnExecutionPolicy = resolveTurnExecutionPolicyV1(settings, {
4218
4406
  modelId: model,
4219
4407
  requestedModelId: payload.model ?? null,
4220
4408
  modelSource: payload.model === void 0 ? "deployment" : "explicit",
4221
4409
  reasoningEffort,
4222
- 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"
4223
4413
  });
4224
4414
  const parentFirstPartyMcpPermissions = parentSession ? [...parentSession.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS] : null;
4225
4415
  if (parentFirstPartyMcpPermissions && payload.firstPartyMcpPermissions?.some(
@@ -4383,6 +4573,7 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
4383
4573
  ...payload.clientEventId ? { clientEventId: payload.clientEventId } : {},
4384
4574
  model,
4385
4575
  reasoningEffort,
4576
+ latencyMode,
4386
4577
  turnExecutionPolicy,
4387
4578
  // A shared spawn inherits the box's backend; a caller-supplied
4388
4579
  // sandboxBackend on a shared spawn is ignored (it is the same box). A
@@ -4468,17 +4659,29 @@ async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, inp
4468
4659
  if (effectiveModel === null) {
4469
4660
  throw new Error("effective follow-up model unexpectedly resolved to null");
4470
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
+ }
4471
4670
  const sessionReasoningEffort = reasoningEffortForSession(
4472
4671
  existingSession.metadata,
4473
4672
  settings.openaiReasoningEffort
4474
4673
  );
4475
4674
  const effectiveReasoningEffort = input.reasoningEffort ?? sessionReasoningEffort;
4675
+ const sessionLatencyMode = latencyModeForSession(existingSession.metadata, "standard");
4676
+ const effectiveLatencyMode = input.latencyMode ?? sessionLatencyMode;
4476
4677
  const turnExecutionPolicy = resolveTurnExecutionPolicyV1(settings, {
4477
4678
  modelId: effectiveModel,
4478
4679
  requestedModelId: input.model ?? null,
4479
4680
  modelSource: input.model == null ? "session" : "explicit",
4480
4681
  reasoningEffort: effectiveReasoningEffort,
4481
- reasoningSource: input.reasoningEffort == null ? "session" : "explicit"
4682
+ reasoningSource: input.reasoningEffort == null ? "session" : "explicit",
4683
+ latencyMode: effectiveLatencyMode,
4684
+ latencyModeSource: input.latencyMode == null ? "session" : "explicit"
4482
4685
  });
4483
4686
  const requestedResources = normalizeResources(input.resources ?? []);
4484
4687
  await requireLimit(deps, {
@@ -4516,6 +4719,7 @@ async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, inp
4516
4719
  resources: requestedResources,
4517
4720
  model: input.model ?? null,
4518
4721
  reasoningEffort: input.reasoningEffort ?? null,
4722
+ latencyMode: input.latencyMode ?? null,
4519
4723
  reasoningEffortFallback: sessionReasoningEffort,
4520
4724
  turnExecutionPolicy,
4521
4725
  mcpCredentialUpdates,
@@ -5078,6 +5282,424 @@ function trimmedScheduledTaskName(name) {
5078
5282
  return trimmed;
5079
5283
  }
5080
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
+
5081
5703
  // src/domain/workspace-members.ts
5082
5704
  import { HTTPException as HTTPException12 } from "hono/http-exception";
5083
5705
  var MEMBER_ADMIN_PERMISSIONS = ["workspace:admin", "members:manage"];
@@ -5156,6 +5778,7 @@ function mapNewSessionDraft(row) {
5156
5778
  toolsProvided: newSessionDraftToolsProvided(row),
5157
5779
  model: row.model,
5158
5780
  reasoningEffort: row.reasoningEffort,
5781
+ latencyMode: row.latencyMode,
5159
5782
  options: publicNewSessionDraftOptions(row),
5160
5783
  updatedAt: row.updatedAt.toISOString()
5161
5784
  });
@@ -5248,6 +5871,7 @@ async function getActorNewSessionDraft(deps, grant, workspaceId) {
5248
5871
  toolsProvided: false,
5249
5872
  model: deps.settings.openaiModel,
5250
5873
  reasoningEffort: deps.settings.openaiReasoningEffort,
5874
+ latencyMode: "standard",
5251
5875
  options: {},
5252
5876
  updatedAt: null
5253
5877
  };
@@ -5286,6 +5910,7 @@ async function saveActorNewSessionDraft(deps, grant, workspaceId, rawInput) {
5286
5910
  toolsProvided,
5287
5911
  model: input.model,
5288
5912
  reasoningEffort: input.reasoningEffort,
5913
+ latencyMode: input.latencyMode,
5289
5914
  options: input.options,
5290
5915
  // Only managed people are removed through removeWorkspaceMember().
5291
5916
  // API keys and delegated service actors (for example the first-party
@@ -5305,7 +5930,7 @@ async function saveActorNewSessionDraft(deps, grant, workspaceId, rawInput) {
5305
5930
  }
5306
5931
 
5307
5932
  // src/application/session-commands.ts
5308
- import { reasoningEffortForMetadata as reasoningEffortForMetadata2 } from "@opengeni/contracts";
5933
+ import { latencyModeForMetadata as latencyModeForMetadata2, reasoningEffortForMetadata as reasoningEffortForMetadata2 } from "@opengeni/contracts";
5309
5934
  import {
5310
5935
  deleteSessionQueueItemInTransaction,
5311
5936
  editQueuedTurnInTransaction,
@@ -5545,6 +6170,7 @@ function composerDraft(row) {
5545
6170
  resources: row.resources,
5546
6171
  model: row.model,
5547
6172
  reasoningEffort: row.reasoningEffort,
6173
+ latencyMode: row.latencyMode,
5548
6174
  sourceTurnId: row.sourceTurnId,
5549
6175
  sourceTurnVersion: row.sourceTurnVersion,
5550
6176
  updatedAt: row.updatedAt.toISOString()
@@ -5762,6 +6388,7 @@ async function getHumanComposerDraft(deps, context) {
5762
6388
  resources: [],
5763
6389
  model: session.model,
5764
6390
  reasoningEffort: reasoningEffortForMetadata2(session.metadata, "medium"),
6391
+ latencyMode: latencyModeForMetadata2(session.metadata, "standard"),
5765
6392
  sourceTurnId: null,
5766
6393
  sourceTurnVersion: null,
5767
6394
  updatedAt: null
@@ -5784,6 +6411,8 @@ async function saveHumanComposerDraft(deps, context, input) {
5784
6411
  return composerDraft(row);
5785
6412
  }
5786
6413
  export {
6414
+ CODEX_COMPACTION_V2_PROVIDER_LOCKED,
6415
+ CodexCompactionV2ProviderLockedError,
5787
6416
  MARKETING_SOCIAL_PACK_ID,
5788
6417
  MAX_CHECKS_PER_RIG,
5789
6418
  MAX_CREDENTIAL_HOOKS_PER_RIG,
@@ -5798,7 +6427,9 @@ export {
5798
6427
  SessionAuthorizationDeniedError,
5799
6428
  SessionAuthorizationUnavailableError,
5800
6429
  SessionSpawnDeniedError,
6430
+ TranscriptionServiceError,
5801
6431
  acceptSessionUserMessage,
6432
+ accessGrantAuthorizationFromContext,
5802
6433
  activateRigVersionForApi,
5803
6434
  appendRigSetupCommand,
5804
6435
  applyCapabilityEnablement,
@@ -5806,6 +6437,7 @@ export {
5806
6437
  assertAllowedVariableSetVariableName,
5807
6438
  assertConfiguredModel,
5808
6439
  assertPackSandboxImageCompatible,
6440
+ assertSessionAllowsProductModel,
5809
6441
  assertToolRefsSubset,
5810
6442
  assertWorkspaceDeletable,
5811
6443
  assertWorkspaceMemberRemovable,
@@ -5826,6 +6458,7 @@ export {
5826
6458
  createRigVersionForApi,
5827
6459
  createSessionForRequest,
5828
6460
  createValidatedScheduledTask,
6461
+ defaultSessionMcpServerIds,
5829
6462
  deleteHumanQueuePrompt,
5830
6463
  deleteRigForApi,
5831
6464
  disableCapability,
@@ -5833,17 +6466,22 @@ export {
5833
6466
  editHumanQueuePrompt,
5834
6467
  enableCapability,
5835
6468
  enabledCapabilityMcpToolRefs,
6469
+ executeRunOnSelfhostedMachine,
6470
+ filenameForMimeType,
5836
6471
  getActorNewSessionDraft,
5837
6472
  getCapabilityPack,
5838
6473
  getHumanComposerDraft,
6474
+ getWorkspaceInsights,
5839
6475
  hasPermission,
5840
6476
  hasReservedOpenGeniSlackBotMetadata,
5841
6477
  hasReservedOpenGeniSlackBotSessionMetadata,
6478
+ isAcceptedMimeType,
5842
6479
  isAuthoritativeGitHubRepositorySelectionError,
5843
6480
  isBuiltInCapabilityPack,
5844
6481
  isOpenGeniSlackBotConnection,
5845
6482
  isTrustedScheduledSlackBotSession,
5846
6483
  isUserMember,
6484
+ latencyModeForSession,
5847
6485
  listCapabilityPacks,
5848
6486
  listFleet,
5849
6487
  listRigChangesForApi,
@@ -5855,6 +6493,7 @@ export {
5855
6493
  mergeResourceRefs,
5856
6494
  mergeToolRefs,
5857
6495
  moveHumanQueuePrompt,
6496
+ normalizeMimeType,
5858
6497
  normalizeResources,
5859
6498
  officialMcpRegistryUrl,
5860
6499
  openGeniSlackBotMetadata,
@@ -5872,6 +6511,7 @@ export {
5872
6511
  relayDialBaseFromSettings,
5873
6512
  requireAccessContext,
5874
6513
  requireAccessGrant,
6514
+ requireAccessGrantAuthorization,
5875
6515
  requireEnvironmentEncryption,
5876
6516
  requireLimit,
5877
6517
  requireOpenGeniSlackBotConnection,
@@ -5900,13 +6540,13 @@ export {
5900
6540
  scheduledTaskTriggerToken,
5901
6541
  sendAgentSessionMessage,
5902
6542
  sessionSpawnDenialEnvelope,
5903
- sessionToolPolicyAllowsDefaultNativeTools,
5904
6543
  sessionWithEffectiveToolPolicy,
5905
6544
  settingsWithCodexAppsMcpServer,
5906
6545
  settingsWithEnabledCapabilityMcpServers,
5907
6546
  settingsWithMcpCapabilityServers,
5908
6547
  settingsWithSessionMcpServerMetadata,
5909
6548
  stableJson,
6549
+ statusForVoiceInputError,
5910
6550
  steerAgentSession,
5911
6551
  steerHumanQueuePrompt,
5912
6552
  swapActiveSandbox,