@opengeni/db 0.36.0 → 1.0.1

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 (51) hide show
  1. package/dist/canonical-human-identities.js +3 -3
  2. package/dist/{chunk-P3RE4D2B.js → chunk-4SR4HKKA.js} +2 -2
  3. package/dist/{chunk-5KTIEDX7.js → chunk-6ZYKCRFO.js} +124 -16
  4. package/dist/chunk-6ZYKCRFO.js.map +1 -0
  5. package/dist/{chunk-CQZ4QSP5.js → chunk-CUPM3FGB.js} +3 -3
  6. package/dist/{chunk-TAUTWOS5.js → chunk-LTG3S6ZY.js} +2 -2
  7. package/dist/{chunk-VKLB2ZGI.js → chunk-NXAFLCQX.js} +81 -2
  8. package/dist/chunk-NXAFLCQX.js.map +1 -0
  9. package/dist/{chunk-F32YT7MP.js → chunk-WD5ROSLL.js} +2 -2
  10. package/dist/{chunk-JC5QPLUM.js → chunk-ZWREYEWA.js} +48 -3
  11. package/dist/chunk-ZWREYEWA.js.map +1 -0
  12. package/dist/editable-artifact-durable-export.d.ts +10 -0
  13. package/dist/editable-artifact-durable-export.js +18 -3
  14. package/dist/editable-artifact-durable-export.js.map +1 -1
  15. package/dist/editable-artifacts.js +3 -3
  16. package/dist/index.d.ts +69 -8
  17. package/dist/index.js +869 -75
  18. package/dist/index.js.map +1 -1
  19. package/dist/knowledge-source-sync-schema.d.ts +730 -0
  20. package/dist/knowledge-source-sync.d.ts +60 -0
  21. package/dist/persistence-errors.d.ts +8 -0
  22. package/dist/provision-roles.js +1 -1
  23. package/dist/runtime-posture.d.ts +3 -3
  24. package/dist/schema.d.ts +21 -4
  25. package/dist/schema.js +5 -1
  26. package/dist/session-queue-commands.d.ts +1 -1
  27. package/dist/session-realtime-ledger.d.ts +1 -0
  28. package/dist/session-tenancy.js +3 -3
  29. package/dist/video-generation.js +3 -3
  30. package/drizzle/0238_recover_unclaimed_session_turns.sql +307 -0
  31. package/drizzle/0240_model_context_user_messages.sql +204 -0
  32. package/drizzle/0243_google_drive_object_acl_authority.sql +554 -0
  33. package/package.json +5 -5
  34. package/src/editable-artifact-durable-export.ts +27 -0
  35. package/src/index.ts +680 -30
  36. package/src/knowledge-source-sync-schema.ts +83 -0
  37. package/src/knowledge-source-sync.ts +530 -0
  38. package/src/persistence-errors.ts +60 -1
  39. package/src/provision-roles.ts +36 -0
  40. package/src/runtime-posture.ts +49 -1
  41. package/src/schema.ts +30 -7
  42. package/src/session-queue-commands.ts +13 -14
  43. package/src/session-realtime-context.ts +16 -0
  44. package/src/session-realtime-ledger.ts +53 -1
  45. package/dist/chunk-5KTIEDX7.js.map +0 -1
  46. package/dist/chunk-JC5QPLUM.js.map +0 -1
  47. package/dist/chunk-VKLB2ZGI.js.map +0 -1
  48. /package/dist/{chunk-P3RE4D2B.js.map → chunk-4SR4HKKA.js.map} +0 -0
  49. /package/dist/{chunk-CQZ4QSP5.js.map → chunk-CUPM3FGB.js.map} +0 -0
  50. /package/dist/{chunk-TAUTWOS5.js.map → chunk-LTG3S6ZY.js.map} +0 -0
  51. /package/dist/{chunk-F32YT7MP.js.map → chunk-WD5ROSLL.js.map} +0 -0
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  canonicalSessionVisibilityTransitionHash,
4
4
  forkSessionContent,
5
5
  transitionSessionVisibility
6
- } from "./chunk-F32YT7MP.js";
6
+ } from "./chunk-WD5ROSLL.js";
7
7
  import {
8
8
  migrate,
9
9
  runMigrations
@@ -27,7 +27,7 @@ import {
27
27
  inspectRuntimeDatabasePosture,
28
28
  provisionRoles,
29
29
  runtimeDatabaseReadyCheck
30
- } from "./chunk-VKLB2ZGI.js";
30
+ } from "./chunk-NXAFLCQX.js";
31
31
  import {
32
32
  CanonicalHumanIdentityAuthorityError,
33
33
  CanonicalHumanIdentityConflictError,
@@ -39,7 +39,7 @@ import {
39
39
  getCanonicalHumanIdentityProjection,
40
40
  synchronizeCanonicalHumanLoginBindings,
41
41
  validateCanonicalHumanSession
42
- } from "./chunk-TAUTWOS5.js";
42
+ } from "./chunk-LTG3S6ZY.js";
43
43
  import {
44
44
  EDITABLE_ARTIFACT_INTENT_MAX_BYTES,
45
45
  EDITABLE_ARTIFACT_KERNEL_TAIL_MAX_BYTES,
@@ -50,7 +50,7 @@ import {
50
50
  PostgresEditableArtifactStore,
51
51
  listEditableArtifactIdsForSession,
52
52
  touchEditableArtifactSessionLink
53
- } from "./chunk-P3RE4D2B.js";
53
+ } from "./chunk-4SR4HKKA.js";
54
54
  import {
55
55
  ACTIVE_VIDEO_GENERATION_STATUSES,
56
56
  VideoGenerationCapacityError,
@@ -82,7 +82,7 @@ import {
82
82
  settleVideoGenerationFailure,
83
83
  settleVideoGenerationReady,
84
84
  updateWorkspaceVideoGenerationPolicy
85
- } from "./chunk-CQZ4QSP5.js";
85
+ } from "./chunk-CUPM3FGB.js";
86
86
  import {
87
87
  SandboxProviderReadLockUnavailableError,
88
88
  SessionEventPersistenceError,
@@ -90,6 +90,7 @@ import {
90
90
  databaseFailureCode,
91
91
  dbBindingFor,
92
92
  isDatabasePersistenceFailure,
93
+ isRetryableDatabaseTransportFailure,
93
94
  isRetryablePersistenceSqlState,
94
95
  isSessionEventPersistenceError,
95
96
  nestedPostgresSqlState,
@@ -116,7 +117,7 @@ import {
116
117
  withWorkspaceSubjectRls,
117
118
  withWorkspaceSubjectSessionActivityRls,
118
119
  withWorkspaceUsageLock
119
- } from "./chunk-JC5QPLUM.js";
120
+ } from "./chunk-ZWREYEWA.js";
120
121
  import {
121
122
  LOSSLESS_CONTENT_CODEC_VERSION,
122
123
  LOSSLESS_TEXT_PREFIX,
@@ -177,6 +178,8 @@ import {
177
178
  generatedImageArtifacts,
178
179
  githubInstallationRepositories,
179
180
  githubInstallations,
181
+ googleDriveObjectAclEvidence,
182
+ googleDriveObjectAclPrincipals,
180
183
  imageGenerationOperations,
181
184
  importBatches,
182
185
  integrationFacetBindingOwners,
@@ -322,11 +325,11 @@ import {
322
325
  xaiRotationSettings,
323
326
  xaiSessionAccountPins,
324
327
  xaiSubscriptionCredentials
325
- } from "./chunk-5KTIEDX7.js";
328
+ } from "./chunk-6ZYKCRFO.js";
326
329
  import "./chunk-PZ5AY32C.js";
327
330
 
328
331
  // src/index.ts
329
- import { createHash as createHash28, randomUUID as randomUUID10 } from "crypto";
332
+ import { createHash as createHash29, randomUUID as randomUUID10 } from "crypto";
330
333
  import {
331
334
  SESSION_GOAL_PROGRESS_MAX_BYTES,
332
335
  SESSION_GOAL_RATIONALE_MAX_BYTES,
@@ -3914,7 +3917,7 @@ import {
3914
3917
  MODEL_ATTACHMENT_REFS_FIELD,
3915
3918
  MODEL_TIMELINE_ANNOTATIONS_FIELD,
3916
3919
  TimelineAnnotations as TimelineAnnotations2,
3917
- renderTimelineAnnotationsForModel as renderTimelineAnnotationsForModel2,
3920
+ renderUserMessageContentForModel,
3918
3921
  SessionMcpApprovalPolicy as SessionMcpApprovalPolicySchema,
3919
3922
  RequestHumanInteractionToolInput as RequestHumanInteractionToolInput2,
3920
3923
  WORKSPACE_XAI_PROVIDER_ACCOUNT_AUTHORITY_SNAPSHOT_V1 as WORKSPACE_XAI_PROVIDER_ACCOUNT_AUTHORITY_SNAPSHOT_V13,
@@ -9056,7 +9059,7 @@ async function submitHumanPromptInTransaction(db, input) {
9056
9059
  expectedDraftRevision: input.expectedDraftRevision ?? null,
9057
9060
  text: input.text,
9058
9061
  annotations,
9059
- turnInstructions: input.turnInstructions ?? null,
9062
+ modelContext: input.modelContext ?? null,
9060
9063
  resources: withCanonicalResourceMountPaths(input.resources),
9061
9064
  model: input.model ?? null,
9062
9065
  reasoningEffort: input.reasoningEffort ?? null,
@@ -9188,7 +9191,7 @@ async function submitHumanPromptInTransaction(db, input) {
9188
9191
  }
9189
9192
  }
9190
9193
  let editedSourceTurn;
9191
- let editedSourceTurnInstructions;
9194
+ let editedSourceModelContext;
9192
9195
  if (draft?.sourceTurnId) {
9193
9196
  const sourceLocks = await lockSessionEventWriteRows(db, {
9194
9197
  workspaceId: input.workspaceId,
@@ -9212,7 +9215,7 @@ async function submitHumanPromptInTransaction(db, input) {
9212
9215
  );
9213
9216
  }
9214
9217
  editedSourceTurn = sourceTurn;
9215
- editedSourceTurnInstructions = sourceTurn.turnInstructions ?? null;
9218
+ editedSourceModelContext = sourceTurn.modelContext ?? null;
9216
9219
  }
9217
9220
  for (const update of input.mcpCredentialUpdates ?? []) {
9218
9221
  const [server] = await db.update(sessionMcpServers).set({
@@ -9259,6 +9262,7 @@ async function submitHumanPromptInTransaction(db, input) {
9259
9262
  const acceptedEventId = crypto.randomUUID();
9260
9263
  const turnId = crypto.randomUUID();
9261
9264
  const workflowId = session.temporalWorkflowId ?? `session-${session.id}`;
9265
+ const effectiveModelContext = editedSourceModelContext !== void 0 ? editedSourceModelContext : input.modelContext ?? null;
9262
9266
  let sequence = session.lastSequence;
9263
9267
  const eventValues = [
9264
9268
  {
@@ -9279,6 +9283,7 @@ async function submitHumanPromptInTransaction(db, input) {
9279
9283
  }
9280
9284
  } : {},
9281
9285
  ...input.resources.length ? { resources: input.resources } : {},
9286
+ ...effectiveModelContext ? { modelContext: effectiveModelContext } : {},
9282
9287
  ...input.model ? { model: input.model } : {},
9283
9288
  ...input.reasoningEffort ? { reasoningEffort: input.reasoningEffort } : {},
9284
9289
  ...input.latencyMode ? { latencyMode: input.latencyMode } : {},
@@ -9303,7 +9308,7 @@ async function submitHumanPromptInTransaction(db, input) {
9303
9308
  position: input.delivery === "steer" ? 0 : existingQueued.length + 1,
9304
9309
  prompt: input.text,
9305
9310
  annotations,
9306
- turnInstructions: editedSourceTurnInstructions !== void 0 ? editedSourceTurnInstructions : input.turnInstructions ?? null,
9311
+ modelContext: effectiveModelContext,
9307
9312
  resources: input.resources,
9308
9313
  tools: [],
9309
9314
  toolsProvided: false,
@@ -10144,7 +10149,8 @@ async function flushSessionRealtimeTranscriptTailInTransaction(db, input) {
10144
10149
  text: sessionRealtimeEntries.text,
10145
10150
  textCodecVersion: sessionRealtimeEntries.textCodecVersion,
10146
10151
  payload: sessionRealtimeEntries.payload,
10147
- payloadCodecVersion: sessionRealtimeEntries.payloadCodecVersion
10152
+ payloadCodecVersion: sessionRealtimeEntries.payloadCodecVersion,
10153
+ modelContext: sessionRealtimeEntries.modelContext
10148
10154
  }).from(sessionRealtimeEntries).where(
10149
10155
  and12(
10150
10156
  eq13(sessionRealtimeEntries.realtimeId, mode.id),
@@ -10161,6 +10167,20 @@ async function flushSessionRealtimeTranscriptTailInTransaction(db, input) {
10161
10167
  }));
10162
10168
  const rendered = renderSessionRealtimeTail(decodedRows);
10163
10169
  if (!rendered.context) return null;
10170
+ const renderedRows = decodedRows.slice(decodedRows.length - rendered.includedEntryCount);
10171
+ let foundUserTranscript = false;
10172
+ let modelContext = null;
10173
+ for (let index = renderedRows.length - 1; index >= 0; index -= 1) {
10174
+ const entry = renderedRows[index];
10175
+ if (entry.role === "user") {
10176
+ foundUserTranscript = true;
10177
+ modelContext = entry.modelContext;
10178
+ break;
10179
+ }
10180
+ }
10181
+ if (!foundUserTranscript) {
10182
+ modelContext = renderedRows.at(-1)?.modelContext ?? null;
10183
+ }
10164
10184
  const [session] = await db.select({ metadata: sessions.metadata }).from(sessions).where(
10165
10185
  and12(
10166
10186
  eq13(sessions.workspaceId, input.workspaceId),
@@ -10184,6 +10204,7 @@ async function flushSessionRealtimeTranscriptTailInTransaction(db, input) {
10184
10204
  operationKey: deterministicUuid2(`opengeni:session-realtime-tail-flush:${mode.id}`),
10185
10205
  delivery: "steer",
10186
10206
  text: rendered.context,
10207
+ modelContext,
10187
10208
  messagePresentation: {
10188
10209
  kind: "realtime_voice_handoff",
10189
10210
  text: "Voice session ended. Remaining conversation context was sent to the agent.",
@@ -11555,10 +11576,37 @@ function canonicalJsonValue2(value) {
11555
11576
  }
11556
11577
  return value;
11557
11578
  }
11558
- function inboundReplayMatches(row, input, role, text, payload) {
11579
+ function normalizedModelContext(input) {
11580
+ const value = input.modelContext?.trim();
11581
+ if (!value) {
11582
+ if (input.modelContext !== void 0) {
11583
+ throw new Error("Realtime modelContext must not be empty");
11584
+ }
11585
+ return null;
11586
+ }
11587
+ if (value.length > 32768) {
11588
+ throw new Error("Realtime modelContext exceeds the server limit");
11589
+ }
11590
+ if (input.kind !== "delegation_call" && input.kind !== "user_transcript" && input.kind !== "assistant_transcript") {
11591
+ throw new Error("Realtime modelContext requires a delegation or finalized transcript");
11592
+ }
11593
+ return value;
11594
+ }
11595
+ function inboundReplayMatches(row, input, role, text, payload, modelContext) {
11559
11596
  const storedText = row.text === null ? null : fromPostgresLosslessText(row.text, row.textCodecVersion);
11560
11597
  const storedPayload = fromPostgresLosslessJson(row.payload, row.payloadCodecVersion);
11561
- return row.direction === "provider_in" && row.kind === input.kind && row.role === role && row.providerEventId === (input.providerEventId ?? null) && row.delegationItemId === (input.delegationItemId ?? null) && row.sourceUpdateId === null && storedText === text && JSON.stringify(canonicalJsonValue2(storedPayload)) === JSON.stringify(canonicalJsonValue2(payload));
11598
+ return row.direction === "provider_in" && row.kind === input.kind && row.role === role && row.providerEventId === (input.providerEventId ?? null) && row.delegationItemId === (input.delegationItemId ?? null) && row.sourceUpdateId === null && storedText === text && row.modelContext === modelContext && JSON.stringify(canonicalJsonValue2(storedPayload)) === JSON.stringify(canonicalJsonValue2(payload));
11599
+ }
11600
+ async function delegationModelContextMatches(db, row, modelContext) {
11601
+ if (row.kind !== "delegation_call" || row.turnId === null) return true;
11602
+ const [turn] = await db.select({ modelContext: sessionTurns.modelContext }).from(sessionTurns).where(
11603
+ and15(
11604
+ eq16(sessionTurns.workspaceId, row.workspaceId),
11605
+ eq16(sessionTurns.sessionId, row.sessionId),
11606
+ eq16(sessionTurns.id, row.turnId)
11607
+ )
11608
+ ).limit(1);
11609
+ return turn?.modelContext === modelContext;
11562
11610
  }
11563
11611
  async function appendInvalidDelegationFailure(db, input, accountId, incoming, failure, sequence, now) {
11564
11612
  await db.insert(sessionRealtimeEntries).values({
@@ -11583,7 +11631,7 @@ async function appendInvalidDelegationFailure(db, input, accountId, incoming, fa
11583
11631
  updatedAt: now
11584
11632
  });
11585
11633
  }
11586
- async function admitRealtimeDelegationInTransaction(db, input, accountId, incoming, entryId) {
11634
+ async function admitRealtimeDelegationInTransaction(db, input, accountId, incoming, entryId, modelContext) {
11587
11635
  const [session] = await db.select().from(sessions).where(
11588
11636
  and15(
11589
11637
  eq16(sessions.workspaceId, input.workspaceId),
@@ -11633,6 +11681,7 @@ async function admitRealtimeDelegationInTransaction(db, input, accountId, incomi
11633
11681
  operationKey: incoming.operationId,
11634
11682
  delivery: "steer",
11635
11683
  text: incoming.text,
11684
+ modelContext,
11636
11685
  messagePresentation: {
11637
11686
  kind: "realtime_voice",
11638
11687
  text: inputTranscript,
@@ -11805,6 +11854,7 @@ async function syncSessionRealtimeLedgerInTransaction(db, input, hooks = {}) {
11805
11854
  const payload = boundedPayload3(incoming.payload);
11806
11855
  const role = expectedRole(incoming);
11807
11856
  const text = incoming.text ?? null;
11857
+ const modelContext = normalizedModelContext(incoming);
11808
11858
  assertBoundedString(text, SESSION_REALTIME_LEDGER_MAX_TEXT_BYTES, "Realtime text");
11809
11859
  if ((incoming.kind === "user_transcript" || incoming.kind === "assistant_transcript") && !text) {
11810
11860
  throw new Error("Finalized realtime transcript text is required");
@@ -11829,7 +11879,7 @@ async function syncSessionRealtimeLedgerInTransaction(db, input, hooks = {}) {
11829
11879
  )
11830
11880
  ).limit(1);
11831
11881
  if (existing) {
11832
- if (!inboundReplayMatches(existing, incoming, role, text, payload)) {
11882
+ if (!inboundReplayMatches(existing, incoming, role, text, payload, modelContext) || !await delegationModelContextMatches(db, existing, modelContext)) {
11833
11883
  throw new SessionRealtimeConflictError(
11834
11884
  incoming.kind === "delegation_call" ? "REALTIME_DELEGATION_CHANGED" : "REALTIME_ENTRY_CHANGED",
11835
11885
  "Realtime ledger operation was already used with different input"
@@ -11856,6 +11906,7 @@ async function syncSessionRealtimeLedgerInTransaction(db, input, hooks = {}) {
11856
11906
  textCodecVersion: LOSSLESS_CONTENT_CODEC_VERSION,
11857
11907
  payload,
11858
11908
  payloadCodecVersion: LOSSLESS_CONTENT_CODEC_VERSION,
11909
+ modelContext,
11859
11910
  createdAt: now,
11860
11911
  updatedAt: now
11861
11912
  }).returning();
@@ -11878,7 +11929,8 @@ async function syncSessionRealtimeLedgerInTransaction(db, input, hooks = {}) {
11878
11929
  input,
11879
11930
  modeRow.accountId,
11880
11931
  incoming,
11881
- entry.id
11932
+ entry.id,
11933
+ modelContext
11882
11934
  );
11883
11935
  const [linked] = await db.update(sessionRealtimeEntries).set({ turnId: admission.turnId, updatedAt: now }).where(eq16(sessionRealtimeEntries.id, entry.id)).returning();
11884
11936
  if (!linked) throw new Error("Failed to link realtime delegation turn");
@@ -18975,6 +19027,7 @@ import {
18975
19027
  KnowledgeSourceSyncAction,
18976
19028
  KnowledgeSourceSyncRunSummary
18977
19029
  } from "@opengeni/contracts";
19030
+ import { createHash as createHash16 } from "crypto";
18978
19031
  import { and as and23, eq as eq24, inArray as inArray13, sql as sql21 } from "drizzle-orm";
18979
19032
  function compareCanonicalDecimalProviderRevisions(candidate, floor) {
18980
19033
  if (candidate === floor) return 0;
@@ -19817,6 +19870,260 @@ async function recordKnowledgeSourceSyncAclEvidence(db, input) {
19817
19870
  }
19818
19871
  );
19819
19872
  }
19873
+ async function recordGoogleDriveObjectAclEvidence(db, input) {
19874
+ const observedAt = exactDate(input.observedAt, "Google Drive ACL observedAt");
19875
+ const expiresAt = exactDate(input.expiresAt, "Google Drive ACL expiresAt");
19876
+ if (expiresAt.getTime() <= observedAt.getTime()) {
19877
+ throw new Error("Google Drive ACL evidence must expire after it was observed");
19878
+ }
19879
+ if (input.principals.length > 1e3) {
19880
+ throw new Error("Google Drive ACL evidence exceeds 1000 principals");
19881
+ }
19882
+ const principals = input.principals.map(normalizeGoogleDriveAclPrincipal);
19883
+ const canonicalAcl = principals.map((principal) => JSON.stringify(principal)).sort((left, right) => left.localeCompare(right));
19884
+ const aclHash = sha256Hex(JSON.stringify(canonicalAcl));
19885
+ const sourcePrincipalHash = principalHash("permission", input.sourceGooglePermissionId);
19886
+ const inputHash = sha256Hex(
19887
+ JSON.stringify({
19888
+ version: 1,
19889
+ obligationId: input.obligationId,
19890
+ connectionId: input.connectionId,
19891
+ connectionVersion: input.connectionVersion,
19892
+ sourcePrincipalHash,
19893
+ sourceSyncGeneration: input.sourceSyncGeneration,
19894
+ sourceConfigGeneration: input.sourceConfigGeneration,
19895
+ sourceLifecycleGeneration: input.sourceLifecycleGeneration,
19896
+ objectLifecycleGeneration: input.objectLifecycleGeneration,
19897
+ objectVersionGeneration: input.objectVersionGeneration,
19898
+ providerRevision: input.providerRevision,
19899
+ driveId: input.driveId,
19900
+ aclRevision: input.aclRevision,
19901
+ aclHash,
19902
+ eligibility: input.eligibility,
19903
+ observedAt: observedAt.toISOString(),
19904
+ expiresAt: expiresAt.toISOString(),
19905
+ citationLocator: input.citationLocator
19906
+ })
19907
+ );
19908
+ return await withRlsContext(
19909
+ db,
19910
+ { accountId: input.accountId, workspaceId: input.workspaceId },
19911
+ async (scopedDb) => await scopedDb.transaction(async (tx) => {
19912
+ const [observedObligation] = await tx.select().from(knowledgeSourceSyncIndexObligations).where(eq24(knowledgeSourceSyncIndexObligations.id, input.obligationId)).limit(1);
19913
+ if (!observedObligation) {
19914
+ throw new Error("Google Drive ACL evidence obligation was not found");
19915
+ }
19916
+ await setSubjectRlsContext(tx, observedObligation.initiatingSubjectId);
19917
+ const [state] = await tx.select().from(knowledgeSourceSyncStates).where(eq24(knowledgeSourceSyncStates.sourceId, observedObligation.sourceId)).for("update").limit(1);
19918
+ if (!state) throw new Error("Google Drive sync authorization is no longer active");
19919
+ await tx.execute(sql21`
19920
+ SELECT knowledge_source_sync_lock_authority(
19921
+ ${input.accountId}::uuid,
19922
+ ${observedObligation.sourceId}::uuid,
19923
+ ${observedObligation.knowledgeSourceObjectId}::uuid
19924
+ )
19925
+ `);
19926
+ const [[source], [object], [version], [obligation], [connection]] = await Promise.all([
19927
+ tx.select().from(knowledgeSources).where(eq24(knowledgeSources.id, observedObligation.sourceId)).limit(1),
19928
+ tx.select().from(knowledgeSourceObjects).where(eq24(knowledgeSourceObjects.id, observedObligation.knowledgeSourceObjectId)).limit(1),
19929
+ tx.select().from(knowledgeDocumentVersions).where(
19930
+ eq24(
19931
+ knowledgeDocumentVersions.id,
19932
+ observedObligation.knowledgeDocumentVersionId
19933
+ )
19934
+ ).limit(1),
19935
+ tx.select().from(knowledgeSourceSyncIndexObligations).where(eq24(knowledgeSourceSyncIndexObligations.id, input.obligationId)).for("update").limit(1),
19936
+ tx.select().from(connections).where(eq24(connections.id, input.connectionId)).limit(1)
19937
+ ]);
19938
+ const [provider] = source ? await tx.select().from(knowledgeProviders).where(eq24(knowledgeProviders.id, source.providerId)).limit(1) : [];
19939
+ const [document] = obligation ? await tx.select().from(documents).where(eq24(documents.id, obligation.documentId)).for("update").limit(1) : [];
19940
+ const metadata = connection?.metadata ?? {};
19941
+ const connectionPermissionId = cleanBoundedString(metadata.googlePermissionId, 256);
19942
+ const connectionLifecycle = metadata.lifecycle && typeof metadata.lifecycle === "object" ? cleanBoundedString(metadata.lifecycle.state, 64) : null;
19943
+ const hasDriveReadScope = Array.isArray(connection?.grantedScopes) && connection.grantedScopes.some(
19944
+ (scope) => scope === "https://www.googleapis.com/auth/drive" || scope === "https://www.googleapis.com/auth/drive.readonly"
19945
+ );
19946
+ if (!obligation || !source || !object || !version || !provider || !document || !connection || provider.providerKey !== "google-drive" || provider.lifecycleState !== "active" || state.connectionId !== input.connectionId || state.connectionProviderDomain !== "googleapis.com" || state.connectionKind !== "oauth2" || state.connectionOwnerSubjectId !== connection.subjectId || state.reconnectRequired || connection.accountId !== input.accountId || connection.subjectId !== observedObligation.initiatingSubjectId || connection.providerDomain !== "googleapis.com" || connection.kind !== "oauth2" || connection.status !== "active" || connection.version !== input.connectionVersion || connection.version < state.connectionVersion || metadata.accessMode !== "readonly" || connectionLifecycle !== null && connectionLifecycle !== "active" || !hasDriveReadScope || !connectionPermissionId || principalHash("permission", connectionPermissionId) !== sourcePrincipalHash || input.sourceSyncGeneration !== obligation.sourceSyncGeneration || state.sourceSyncGeneration < obligation.sourceSyncGeneration || state.sourceConfigGeneration !== input.sourceConfigGeneration || state.sourceConfigGeneration !== obligation.sourceConfigGeneration || state.sourceLifecycleGeneration !== input.sourceLifecycleGeneration || state.sourceLifecycleGeneration !== obligation.sourceLifecycleGeneration || source.lifecycleState !== "active" || source.syncGeneration < obligation.sourceSyncGeneration || source.lifecycleGeneration !== obligation.sourceLifecycleGeneration || source.currentAclGeneration !== version.aclGeneration || object.sourceId !== obligation.sourceId || object.externalObjectId !== obligation.externalObjectId || object.lifecycleState !== "active" || object.lifecycleGeneration !== obligation.objectLifecycleGeneration || object.versionGeneration !== obligation.objectVersionGeneration || object.currentVersionId !== obligation.knowledgeDocumentVersionId || version.sourceId !== obligation.sourceId || version.objectId !== obligation.knowledgeSourceObjectId || version.versionGeneration !== obligation.objectVersionGeneration || version.documentId !== obligation.documentId || version.fileId !== document.fileId || document.accountId !== input.accountId || document.workspaceId !== input.workspaceId || document.sourceExternalId !== obligation.externalObjectId || !document.knowledgeSourceIdentity || obligation.sourceLifecycleGeneration !== input.sourceLifecycleGeneration || obligation.objectLifecycleGeneration !== input.objectLifecycleGeneration || obligation.objectVersionGeneration !== input.objectVersionGeneration) {
19947
+ throw new Error("Google Drive ACL evidence authority changed");
19948
+ }
19949
+ if (input.eligibility === "eligible" && obligation.status !== "indexed") {
19950
+ throw new Error("Google Drive ACL eligibility requires a completed index obligation");
19951
+ }
19952
+ const evidenceValues = {
19953
+ accountId: input.accountId,
19954
+ workspaceId: input.workspaceId,
19955
+ sourceId: obligation.sourceId,
19956
+ knowledgeSourceObjectId: obligation.knowledgeSourceObjectId,
19957
+ knowledgeDocumentVersionId: obligation.knowledgeDocumentVersionId,
19958
+ documentId: obligation.documentId,
19959
+ fileId: document.fileId,
19960
+ indexObligationId: obligation.id,
19961
+ connectionId: input.connectionId,
19962
+ connectionVersion: input.connectionVersion,
19963
+ sourcePrincipalHash,
19964
+ sourceSyncGeneration: input.sourceSyncGeneration,
19965
+ sourceConfigGeneration: input.sourceConfigGeneration,
19966
+ sourceLifecycleGeneration: input.sourceLifecycleGeneration,
19967
+ objectLifecycleGeneration: input.objectLifecycleGeneration,
19968
+ objectVersionGeneration: input.objectVersionGeneration,
19969
+ providerRevision: input.providerRevision,
19970
+ driveId: cleanBoundedString(input.driveId, 1024),
19971
+ aclRevision: exactBoundedString(input.aclRevision, 1024, "Google Drive ACL revision"),
19972
+ aclHash,
19973
+ eligibility: input.eligibility,
19974
+ observedAt,
19975
+ expiresAt,
19976
+ citationLocator: input.citationLocator,
19977
+ operationId: exactBoundedString(input.operationId, 256, "Google Drive ACL operation id"),
19978
+ inputHash
19979
+ };
19980
+ const [inserted] = await tx.insert(googleDriveObjectAclEvidence).values(evidenceValues).onConflictDoNothing({
19981
+ target: [
19982
+ googleDriveObjectAclEvidence.indexObligationId,
19983
+ googleDriveObjectAclEvidence.operationId
19984
+ ]
19985
+ }).returning();
19986
+ const [evidence] = inserted ? [inserted] : await tx.select().from(googleDriveObjectAclEvidence).where(
19987
+ and23(
19988
+ eq24(googleDriveObjectAclEvidence.indexObligationId, obligation.id),
19989
+ eq24(googleDriveObjectAclEvidence.operationId, evidenceValues.operationId)
19990
+ )
19991
+ ).limit(1);
19992
+ if (!evidence || evidence.inputHash !== inputHash) {
19993
+ throw new Error("Google Drive ACL evidence operation conflicted");
19994
+ }
19995
+ if (inserted && principals.length > 0) {
19996
+ await tx.insert(googleDriveObjectAclPrincipals).values(
19997
+ principals.map((principal, ordinal) => ({
19998
+ evidenceId: evidence.id,
19999
+ ordinal,
20000
+ accountId: input.accountId,
20001
+ workspaceId: input.workspaceId,
20002
+ ...principal
20003
+ }))
20004
+ );
20005
+ }
20006
+ const now = /* @__PURE__ */ new Date();
20007
+ await tx.update(knowledgeSourceSyncIndexObligations).set({
20008
+ googleDriveAclEvidenceId: evidence.id,
20009
+ aclEligibility: input.eligibility,
20010
+ updatedAt: now
20011
+ }).where(eq24(knowledgeSourceSyncIndexObligations.id, obligation.id));
20012
+ await tx.update(knowledgeSourceSyncItemOutcomes).set({
20013
+ aclEligibility: input.eligibility,
20014
+ aclEvidence: {
20015
+ version: 1,
20016
+ provider: "google_drive",
20017
+ evidenceId: evidence.id,
20018
+ aclRevision: evidence.aclRevision,
20019
+ observedAt: evidence.observedAt.toISOString(),
20020
+ expiresAt: evidence.expiresAt.toISOString()
20021
+ }
20022
+ }).where(eq24(knowledgeSourceSyncItemOutcomes.indexObligationId, obligation.id));
20023
+ const [updatedDocument] = await tx.update(documents).set({
20024
+ agentAccess: input.eligibility === "eligible",
20025
+ ...input.eligibility === "denied" ? { chunkCount: 0 } : {},
20026
+ updatedAt: now
20027
+ }).where(eq24(documents.id, obligation.documentId)).returning({ id: documents.id });
20028
+ if (!updatedDocument) {
20029
+ throw new Error("Google Drive ACL evidence document authority changed");
20030
+ }
20031
+ if (input.eligibility === "denied") {
20032
+ await tx.delete(documentChunks).where(eq24(documentChunks.documentId, obligation.documentId));
20033
+ }
20034
+ return { evidenceId: evidence.id, aclHash };
20035
+ })
20036
+ );
20037
+ }
20038
+ async function beginGoogleDriveObjectAclRefresh(db, input) {
20039
+ await withRlsContext(
20040
+ db,
20041
+ { accountId: input.accountId, workspaceId: input.workspaceId },
20042
+ async (scopedDb) => await scopedDb.transaction(async (tx) => {
20043
+ const [observed] = await tx.select().from(knowledgeSourceSyncIndexObligations).where(eq24(knowledgeSourceSyncIndexObligations.id, input.obligationId)).limit(1);
20044
+ if (!observed) throw new Error("Google Drive ACL refresh obligation was not found");
20045
+ await setSubjectRlsContext(tx, observed.initiatingSubjectId);
20046
+ const [state] = await tx.select().from(knowledgeSourceSyncStates).where(eq24(knowledgeSourceSyncStates.sourceId, observed.sourceId)).for("update").limit(1);
20047
+ if (!state) throw new Error("Google Drive sync authorization is no longer active");
20048
+ await tx.execute(sql21`
20049
+ SELECT knowledge_source_sync_lock_authority(
20050
+ ${input.accountId}::uuid,
20051
+ ${observed.sourceId}::uuid,
20052
+ ${observed.knowledgeSourceObjectId}::uuid
20053
+ )
20054
+ `);
20055
+ const [[source], [object], [version], [obligation]] = await Promise.all([
20056
+ tx.select().from(knowledgeSources).where(eq24(knowledgeSources.id, observed.sourceId)).limit(1),
20057
+ tx.select().from(knowledgeSourceObjects).where(eq24(knowledgeSourceObjects.id, observed.knowledgeSourceObjectId)).limit(1),
20058
+ tx.select().from(knowledgeDocumentVersions).where(eq24(knowledgeDocumentVersions.id, observed.knowledgeDocumentVersionId)).limit(1),
20059
+ tx.select().from(knowledgeSourceSyncIndexObligations).where(eq24(knowledgeSourceSyncIndexObligations.id, input.obligationId)).for("update").limit(1)
20060
+ ]);
20061
+ const [document] = obligation ? await tx.select().from(documents).where(eq24(documents.id, obligation.documentId)).for("update").limit(1) : [];
20062
+ if (!source || !object || !version || !obligation || !document || state.reconnectRequired || state.sourceSyncGeneration < input.sourceSyncGeneration || state.sourceConfigGeneration !== input.sourceConfigGeneration || state.sourceLifecycleGeneration !== input.sourceLifecycleGeneration || source.lifecycleState !== "active" || source.syncGeneration < obligation.sourceSyncGeneration || source.lifecycleGeneration !== input.sourceLifecycleGeneration || source.currentAclGeneration !== version.aclGeneration || object.lifecycleState !== "active" || object.lifecycleGeneration !== input.objectLifecycleGeneration || object.versionGeneration !== input.objectVersionGeneration || object.currentVersionId !== version.id || version.documentId !== document.id || version.fileId !== document.fileId || obligation.sourceSyncGeneration !== input.sourceSyncGeneration || obligation.sourceConfigGeneration !== input.sourceConfigGeneration || obligation.sourceLifecycleGeneration !== input.sourceLifecycleGeneration || obligation.objectLifecycleGeneration !== input.objectLifecycleGeneration || obligation.objectVersionGeneration !== input.objectVersionGeneration || obligation.status !== "indexed") {
20063
+ throw new Error("Google Drive ACL refresh authority changed");
20064
+ }
20065
+ const now = /* @__PURE__ */ new Date();
20066
+ await tx.update(knowledgeSourceSyncIndexObligations).set({
20067
+ googleDriveAclEvidenceId: null,
20068
+ aclEligibility: "denied",
20069
+ updatedAt: now
20070
+ }).where(eq24(knowledgeSourceSyncIndexObligations.id, obligation.id));
20071
+ await tx.update(knowledgeSourceSyncItemOutcomes).set({
20072
+ aclEligibility: "denied",
20073
+ aclEvidence: { version: 1, provider: "google_drive", state: "refresh_pending" }
20074
+ }).where(eq24(knowledgeSourceSyncItemOutcomes.indexObligationId, obligation.id));
20075
+ await tx.update(documents).set({ agentAccess: false, updatedAt: now }).where(eq24(documents.id, obligation.documentId));
20076
+ })
20077
+ );
20078
+ }
20079
+ function normalizeGoogleDriveAclPrincipal(principal) {
20080
+ const permissionId = cleanBoundedString(principal.permissionId, 1024);
20081
+ const emailAddress = cleanBoundedString(principal.emailAddress, 320)?.toLowerCase() ?? null;
20082
+ const domain = cleanBoundedString(principal.domain, 320)?.toLowerCase() ?? null;
20083
+ if (principal.type === "user" || principal.type === "group") {
20084
+ if (!permissionId && !emailAddress) {
20085
+ throw new Error(`Google Drive ${principal.type} principal is missing identity`);
20086
+ }
20087
+ } else if (principal.type === "domain") {
20088
+ if (!domain) throw new Error("Google Drive domain principal is missing its domain");
20089
+ } else if (principal.type !== "anyone") {
20090
+ throw new Error("Google Drive ACL principal type is invalid");
20091
+ }
20092
+ const expirationTime = principal.expirationTime ? exactDate(principal.expirationTime, "Google Drive ACL principal expiration") : null;
20093
+ return {
20094
+ principalType: principal.type,
20095
+ permissionIdHash: permissionId ? principalHash("permission", permissionId) : null,
20096
+ emailHash: emailAddress ? principalHash("email", emailAddress) : null,
20097
+ domainHash: domain ? principalHash("domain", domain) : null,
20098
+ role: principal.role,
20099
+ inherited: principal.inherited === true,
20100
+ allowFileDiscovery: principal.allowFileDiscovery === void 0 ? null : principal.allowFileDiscovery,
20101
+ expirationTime
20102
+ };
20103
+ }
20104
+ function principalHash(kind, value) {
20105
+ return sha256Hex(`${kind}:${value.trim().toLowerCase()}`);
20106
+ }
20107
+ function sha256Hex(value) {
20108
+ return createHash16("sha256").update(value).digest("hex");
20109
+ }
20110
+ function exactDate(value, label) {
20111
+ const parsed = new Date(value);
20112
+ if (!value || !Number.isFinite(parsed.getTime()) || parsed.toISOString() !== value) {
20113
+ throw new Error(`${label} must be an exact UTC timestamp`);
20114
+ }
20115
+ return parsed;
20116
+ }
20117
+ function exactBoundedString(value, max, label) {
20118
+ const normalized = cleanBoundedString(value, max);
20119
+ if (!normalized || normalized !== value) throw new Error(`${label} is invalid`);
20120
+ return normalized;
20121
+ }
20122
+ function cleanBoundedString(value, max) {
20123
+ if (typeof value !== "string") return null;
20124
+ const normalized = value.trim();
20125
+ return normalized && normalized.length <= max ? normalized : null;
20126
+ }
19820
20127
  async function pruneKnowledgeSourceSyncEvidence(db, input) {
19821
20128
  const limit = Math.max(1, Math.min(input.limit ?? 500, 5e3));
19822
20129
  return await withRlsContext(
@@ -20496,7 +20803,7 @@ function assertImageGenerationOperationMatches(operation, input) {
20496
20803
  }
20497
20804
 
20498
20805
  // src/slack-user-link-access.ts
20499
- import { createHash as createHash16 } from "crypto";
20806
+ import { createHash as createHash17 } from "crypto";
20500
20807
  import {
20501
20808
  SlackUserLinkAccessRequest as SlackUserLinkAccessRequestSchema
20502
20809
  } from "@opengeni/contracts";
@@ -20951,7 +21258,7 @@ function assertExactClaims(row, input) {
20951
21258
  }
20952
21259
  }
20953
21260
  function digestOperation(value) {
20954
- return createHash16("sha256").update(JSON.stringify(value)).digest("hex");
21261
+ return createHash17("sha256").update(JSON.stringify(value)).digest("hex");
20955
21262
  }
20956
21263
  function mapRequest(row) {
20957
21264
  return {
@@ -20971,12 +21278,12 @@ function mapRequest(row) {
20971
21278
  }
20972
21279
 
20973
21280
  // src/capability-integrations.ts
20974
- import { createHash as createHash18 } from "crypto";
21281
+ import { createHash as createHash19 } from "crypto";
20975
21282
  import { stableJson as stableJson5 } from "@opengeni/contracts";
20976
21283
  import { and as and27, asc as asc14, eq as eq28, inArray as inArray15, ne as ne2, or as or6, sql as sql25 } from "drizzle-orm";
20977
21284
 
20978
21285
  // src/integration-bindings.ts
20979
- import { createHash as createHash17 } from "crypto";
21286
+ import { createHash as createHash18 } from "crypto";
20980
21287
  import { stableJson as stableJson4 } from "@opengeni/contracts";
20981
21288
  import { and as and26, asc as asc13, eq as eq27, or as or5, sql as sql24 } from "drizzle-orm";
20982
21289
  var IntegrationFacetBindingVersionConflictError = class extends Error {
@@ -21260,7 +21567,7 @@ function assertBindingKey(value) {
21260
21567
  }
21261
21568
  }
21262
21569
  function sha2563(value) {
21263
- return createHash17("sha256").update(value).digest("hex");
21570
+ return createHash18("sha256").update(value).digest("hex");
21264
21571
  }
21265
21572
 
21266
21573
  // src/capability-integrations.ts
@@ -22275,11 +22582,11 @@ function stringValue(value) {
22275
22582
  return typeof value === "string" && value.length > 0 ? value : void 0;
22276
22583
  }
22277
22584
  function sha2564(value) {
22278
- return createHash18("sha256").update(value).digest("hex");
22585
+ return createHash19("sha256").update(value).digest("hex");
22279
22586
  }
22280
22587
 
22281
22588
  // src/integration-facets.ts
22282
- import { createHash as createHash19 } from "crypto";
22589
+ import { createHash as createHash20 } from "crypto";
22283
22590
  import { stableJson as stableJson6 } from "@opengeni/contracts";
22284
22591
  import { and as and28, asc as asc15, eq as eq29, ne as ne3, sql as sql26 } from "drizzle-orm";
22285
22592
  var IntegrationFacetNotFoundError = class extends Error {
@@ -22844,7 +23151,7 @@ function objectValue2(value) {
22844
23151
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
22845
23152
  }
22846
23153
  function sha2565(value) {
22847
- return createHash19("sha256").update(value).digest("hex");
23154
+ return createHash20("sha256").update(value).digest("hex");
22848
23155
  }
22849
23156
 
22850
23157
  // src/insights.ts
@@ -24460,7 +24767,7 @@ async function cancelResponseBody(response) {
24460
24767
  }
24461
24768
 
24462
24769
  // src/pack-components.ts
24463
- import { createHash as createHash20 } from "crypto";
24770
+ import { createHash as createHash21 } from "crypto";
24464
24771
  import {
24465
24772
  stableJson as stableJson7
24466
24773
  } from "@opengeni/contracts";
@@ -25098,11 +25405,11 @@ function stringArray2(value) {
25098
25405
  return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
25099
25406
  }
25100
25407
  function sha2566(value) {
25101
- return createHash20("sha256").update(value).digest("hex");
25408
+ return createHash21("sha256").update(value).digest("hex");
25102
25409
  }
25103
25410
 
25104
25411
  // src/pack-installations.ts
25105
- import { createHash as createHash21 } from "crypto";
25412
+ import { createHash as createHash22 } from "crypto";
25106
25413
  import {
25107
25414
  CapabilityPack as CapabilityPackSchema,
25108
25415
  stableJson as stableJson8
@@ -25666,7 +25973,7 @@ async function assertRegisteredPackManifestCurrent(db, input) {
25666
25973
  )
25667
25974
  ).for("update").limit(1);
25668
25975
  const parsed = registration ? CapabilityPackSchema.safeParse(registration.manifest) : null;
25669
- const currentDigest = parsed?.success === true ? createHash21("sha256").update(stableJson8(parsed.data)).digest("hex") : null;
25976
+ const currentDigest = parsed?.success === true ? createHash22("sha256").update(stableJson8(parsed.data)).digest("hex") : null;
25670
25977
  if (input.expectedDigest !== input.admittedDigest || currentDigest !== input.expectedDigest) {
25671
25978
  throw new PackManifestChangedError(
25672
25979
  "Pack manifest changed after preview; review the current installation plan"
@@ -25711,7 +26018,7 @@ function mapPackInstallation(row) {
25711
26018
  }
25712
26019
 
25713
26020
  // src/plugin-packages.ts
25714
- import { createHash as createHash22 } from "crypto";
26021
+ import { createHash as createHash23 } from "crypto";
25715
26022
  import { stableJson as stableJson9 } from "@opengeni/contracts";
25716
26023
  import { and as and32, asc as asc17, eq as eq33, inArray as inArray19, ne as ne6, or as or8, sql as sql30 } from "drizzle-orm";
25717
26024
  var PluginOperationIdempotencyError = class extends Error {
@@ -26501,7 +26808,7 @@ function safeHttpUrl(value) {
26501
26808
  }
26502
26809
  }
26503
26810
  function sha2567(value) {
26504
- return createHash22("sha256").update(value).digest("hex");
26811
+ return createHash23("sha256").update(value).digest("hex");
26505
26812
  }
26506
26813
 
26507
26814
  // src/workspace-artifacts.ts
@@ -28011,7 +28318,7 @@ async function purgeExpiredTranscriptionRecordings(db, input) {
28011
28318
  }
28012
28319
 
28013
28320
  // src/editable-artifact-materialization.ts
28014
- import { createHash as createHash23 } from "crypto";
28321
+ import { createHash as createHash24 } from "crypto";
28015
28322
  import { EDITABLE_ARTIFACT_KERNEL_VERSION_MAX_BYTES } from "@opengeni/contracts/editable-artifacts";
28016
28323
  import { sql as sql33 } from "drizzle-orm";
28017
28324
  var EDITABLE_ARTIFACT_MATERIALIZATION_MAX_CLAIM = 1e3;
@@ -28487,7 +28794,7 @@ function validateDatabaseNormalizedOptions(value, expectedHash) {
28487
28794
  } catch (error) {
28488
28795
  throw contractViolation("Materialization row contains invalid normalized options", error);
28489
28796
  }
28490
- const actualHash = `sha256:${createHash23("sha256").update(normalized, "utf8").digest("hex")}`;
28797
+ const actualHash = `sha256:${createHash24("sha256").update(normalized, "utf8").digest("hex")}`;
28491
28798
  if (actualHash !== expectedHash) {
28492
28799
  throw contractViolation("Materialization options hash does not bind its exact canonical bytes");
28493
28800
  }
@@ -28644,7 +28951,7 @@ async function attemptToolCatalogByAttemptTx(tx, workspaceId, attemptId) {
28644
28951
  }
28645
28952
 
28646
28953
  // src/browser-sessions.ts
28647
- import { createHash as createHash24, randomUUID as randomUUID7 } from "crypto";
28954
+ import { createHash as createHash25, randomUUID as randomUUID7 } from "crypto";
28648
28955
  import {
28649
28956
  BrowserSession,
28650
28957
  BrowserSessionCapabilities,
@@ -29116,7 +29423,7 @@ async function loadOperation2(db, workspaceId, operationId) {
29116
29423
  return row ?? null;
29117
29424
  }
29118
29425
  function requestDigest(value) {
29119
- return createHash24("sha256").update(JSON.stringify(value)).digest("hex");
29426
+ return createHash25("sha256").update(JSON.stringify(value)).digest("hex");
29120
29427
  }
29121
29428
  function browserSessionCreateRequestDigest(input) {
29122
29429
  const revisionSelection = input.identityId ? input.resolveDefaultRevision ? { kind: "identity_default" } : input.baseRevisionId ? { kind: "exact", revisionId: input.baseRevisionId } : { kind: "blank_identity" } : { kind: "none" };
@@ -30468,7 +30775,7 @@ function postgresConstraint2(error) {
30468
30775
  }
30469
30776
 
30470
30777
  // src/computer-sessions.ts
30471
- import { createHash as createHash25, randomUUID as randomUUID8 } from "crypto";
30778
+ import { createHash as createHash26, randomUUID as randomUUID8 } from "crypto";
30472
30779
  import {
30473
30780
  ComputerSession,
30474
30781
  ComputerSessionCapabilities,
@@ -30613,7 +30920,7 @@ async function loadOperation3(db, workspaceId, operationId) {
30613
30920
  return row ?? null;
30614
30921
  }
30615
30922
  function requestDigest2(value) {
30616
- return createHash25("sha256").update(JSON.stringify(value)).digest("hex");
30923
+ return createHash26("sha256").update(JSON.stringify(value)).digest("hex");
30617
30924
  }
30618
30925
  function computerSessionCreateRequestDigest(input) {
30619
30926
  return requestDigest2({
@@ -31274,7 +31581,7 @@ function assertOperationResource2(operation, computerSessionId, kind) {
31274
31581
  }
31275
31582
 
31276
31583
  // src/browser-identities.ts
31277
- import { createHash as createHash26, randomUUID as randomUUID9 } from "crypto";
31584
+ import { createHash as createHash27, randomUUID as randomUUID9 } from "crypto";
31278
31585
  import {
31279
31586
  BrowserIdentity,
31280
31587
  BrowserIdentityListResponse,
@@ -31511,7 +31818,7 @@ async function updateBrowserIdentity(db, input) {
31511
31818
  ...input.defaultRevisionId !== void 0 ? { defaultRevisionId: input.defaultRevisionId } : {}
31512
31819
  });
31513
31820
  const { operationId: _operationId, ...digestRequest } = request;
31514
- const requestDigest4 = createHash26("sha256").update(
31821
+ const requestDigest4 = createHash27("sha256").update(
31515
31822
  JSON.stringify({
31516
31823
  version: 1,
31517
31824
  identityId: input.identityId,
@@ -31622,7 +31929,7 @@ async function updateBrowserIdentity(db, input) {
31622
31929
  }
31623
31930
  }
31624
31931
  function browserRevisionPublicationRequestDigest(input) {
31625
- return createHash26("sha256").update(
31932
+ return createHash27("sha256").update(
31626
31933
  JSON.stringify({
31627
31934
  version: 1,
31628
31935
  browserSessionId: input.browserSessionId,
@@ -32225,7 +32532,7 @@ function postgresConstraint3(error) {
32225
32532
  }
32226
32533
 
32227
32534
  // src/browser-downloads.ts
32228
- import { createHash as createHash27 } from "crypto";
32535
+ import { createHash as createHash28 } from "crypto";
32229
32536
  import {
32230
32537
  BrowserDownload,
32231
32538
  BrowserDownloadSaveRequest,
@@ -32463,7 +32770,7 @@ function parseIdentity(input) {
32463
32770
  };
32464
32771
  }
32465
32772
  function requestDigest3(input) {
32466
- return createHash27("sha256").update(
32773
+ return createHash28("sha256").update(
32467
32774
  JSON.stringify({
32468
32775
  browserSessionId: input.browserSessionId,
32469
32776
  destinationPath: input.request.destinationPath,
@@ -34834,6 +35141,57 @@ async function requireFile(db, workspaceId, fileId) {
34834
35141
  }
34835
35142
  return file;
34836
35143
  }
35144
+ async function requireFileForSubject(db, input) {
35145
+ return await withRlsContext(
35146
+ db,
35147
+ { accountId: input.accountId, workspaceId: input.workspaceId },
35148
+ async (scopedDb) => {
35149
+ if (input.subjectId) await setSubjectRlsContext(scopedDb, input.subjectId);
35150
+ const subjectIdSql = input.subjectId === null ? sql39`NULL::text` : sql39`${input.subjectId}`;
35151
+ const [row] = await scopedDb.select().from(files).where(
35152
+ and42(
35153
+ eq43(files.accountId, input.accountId),
35154
+ eq43(files.workspaceId, input.workspaceId),
35155
+ eq43(files.id, input.fileId),
35156
+ sql39`google_drive_file_authorized(
35157
+ ${input.accountId}::uuid,
35158
+ ${input.workspaceId}::uuid,
35159
+ ${subjectIdSql},
35160
+ ${input.fileId}::uuid
35161
+ )`
35162
+ )
35163
+ ).limit(1);
35164
+ if (!row) throw new Error(`File not found: ${input.fileId}`);
35165
+ return mapFile2(row);
35166
+ }
35167
+ );
35168
+ }
35169
+ async function getFilesForSubject(db, input) {
35170
+ const ids = [...new Set(input.fileIds)];
35171
+ if (ids.length === 0) return [];
35172
+ return await withRlsContext(
35173
+ db,
35174
+ { accountId: input.accountId, workspaceId: input.workspaceId },
35175
+ async (scopedDb) => {
35176
+ if (input.subjectId) await setSubjectRlsContext(scopedDb, input.subjectId);
35177
+ const subjectIdSql = input.subjectId === null ? sql39`NULL::text` : sql39`${input.subjectId}`;
35178
+ const rows = await scopedDb.select().from(files).where(
35179
+ and42(
35180
+ eq43(files.accountId, input.accountId),
35181
+ eq43(files.workspaceId, input.workspaceId),
35182
+ inArray25(files.id, ids),
35183
+ sql39`google_drive_file_authorized(
35184
+ ${input.accountId}::uuid,
35185
+ ${input.workspaceId}::uuid,
35186
+ ${subjectIdSql},
35187
+ ${files.id}
35188
+ )`
35189
+ )
35190
+ );
35191
+ return rows.map(mapFile2);
35192
+ }
35193
+ );
35194
+ }
34837
35195
  async function getFiles(db, workspaceId, fileIds) {
34838
35196
  const ids = [...new Set(fileIds)];
34839
35197
  if (ids.length === 0) return [];
@@ -34842,14 +35200,14 @@ async function getFiles(db, workspaceId, fileIds) {
34842
35200
  return rows.map(mapFile2);
34843
35201
  });
34844
35202
  }
34845
- function durableUserHistoryItem(prompt, resources, annotations = []) {
35203
+ function durableUserHistoryItem(prompt, resources, annotations = [], modelContext) {
34846
35204
  const attachmentRefs = resources.filter(
34847
35205
  (resource) => resource.kind === "file"
34848
35206
  );
34849
35207
  return {
34850
35208
  type: "message",
34851
35209
  role: "user",
34852
- content: renderTimelineAnnotationsForModel2(prompt, annotations),
35210
+ content: renderUserMessageContentForModel(prompt, annotations, modelContext),
34853
35211
  ...attachmentRefs.length > 0 ? { [MODEL_ATTACHMENT_REFS_FIELD]: attachmentRefs } : {},
34854
35212
  ...annotations.length > 0 ? {
34855
35213
  [MODEL_TIMELINE_ANNOTATIONS_FIELD]: TimelineAnnotations2.parse(annotations)
@@ -35945,7 +36303,7 @@ async function installPortableSkill(db, input) {
35945
36303
  fileCount: input.files.length,
35946
36304
  totalBytes: input.totalBytes
35947
36305
  };
35948
- const manifestDigest = createHash28("sha256").update(stableJson10(manifest)).digest("hex");
36306
+ const manifestDigest = createHash29("sha256").update(stableJson10(manifest)).digest("hex");
35949
36307
  const [versionByName] = await tx.select().from(capabilityPluginVersions).where(
35950
36308
  and42(
35951
36309
  eq43(capabilityPluginVersions.pluginId, plugin.id),
@@ -41435,7 +41793,7 @@ async function retainRigProviderImageArtifacts(db, workspaceId, images) {
41435
41793
  inArray25(sandboxCheckpointArtifacts.state, ["candidate", "current"])
41436
41794
  )
41437
41795
  ).for("update").limit(1);
41438
- const bindingHash = artifact ? `sha256:${createHash28("sha256").update(artifact.providerBindingKey, "utf8").digest("hex")}` : null;
41796
+ const bindingHash = artifact ? `sha256:${createHash29("sha256").update(artifact.providerBindingKey, "utf8").digest("hex")}` : null;
41439
41797
  if (!artifact || bindingHash !== image.providerBindingKeyHash) continue;
41440
41798
  retained[backend] = image;
41441
41799
  }
@@ -45590,7 +45948,7 @@ function connectorActionPolicyDecision(resolved) {
45590
45948
  return resolved.decision;
45591
45949
  }
45592
45950
  function connectorActionFingerprint(input) {
45593
- return createHash28("sha256").update(
45951
+ return createHash29("sha256").update(
45594
45952
  stableJson10({
45595
45953
  workspaceId: input.workspaceId,
45596
45954
  connectionId: input.connectionId,
@@ -45899,6 +46257,93 @@ async function upsertConnectorActionPolicy(db, input) {
45899
46257
  })
45900
46258
  );
45901
46259
  }
46260
+ async function ensureConnectorActionPolicyDefault(db, input) {
46261
+ const scope = {
46262
+ connectionId: boundedConnectorActionText(
46263
+ input.connectionId,
46264
+ "connector connection id",
46265
+ CONNECTOR_ACTION_CONNECTION_ID_MAX
46266
+ ),
46267
+ serverId: boundedConnectorActionText(
46268
+ input.serverId,
46269
+ "connector server id",
46270
+ CONNECTOR_ACTION_SERVER_ID_MAX
46271
+ ),
46272
+ toolName: boundedConnectorActionText(
46273
+ input.toolName,
46274
+ "connector tool name",
46275
+ CONNECTOR_ACTION_NAME_MAX
46276
+ ),
46277
+ actionName: boundedConnectorActionText(
46278
+ input.actionName,
46279
+ "connector action name",
46280
+ CONNECTOR_ACTION_NAME_MAX
46281
+ )
46282
+ };
46283
+ const subjectId = boundedConnectorActionText(input.subjectId, "policy actor", 1024);
46284
+ return await withRlsContext(
46285
+ db,
46286
+ { accountId: input.accountId, workspaceId: input.workspaceId },
46287
+ async (scopedDb) => await scopedDb.transaction(async (tx) => {
46288
+ await assertWorkspaceAccountPairInScope(tx, input.accountId, input.workspaceId);
46289
+ const [inserted] = await tx.insert(connectorActionPolicies).values({
46290
+ accountId: input.accountId,
46291
+ workspaceId: input.workspaceId,
46292
+ ...scope,
46293
+ policy: input.policy,
46294
+ createdBySubjectId: subjectId,
46295
+ updatedBySubjectId: subjectId
46296
+ }).onConflictDoNothing({
46297
+ target: [
46298
+ connectorActionPolicies.workspaceId,
46299
+ connectorActionPolicies.connectionId,
46300
+ connectorActionPolicies.serverId,
46301
+ connectorActionPolicies.toolName,
46302
+ connectorActionPolicies.actionName
46303
+ ]
46304
+ }).returning();
46305
+ if (!inserted) {
46306
+ const [existing] = await tx.select().from(connectorActionPolicies).where(
46307
+ and42(
46308
+ eq43(connectorActionPolicies.workspaceId, input.workspaceId),
46309
+ eq43(connectorActionPolicies.connectionId, scope.connectionId),
46310
+ eq43(connectorActionPolicies.serverId, scope.serverId),
46311
+ eq43(connectorActionPolicies.toolName, scope.toolName),
46312
+ eq43(connectorActionPolicies.actionName, scope.actionName)
46313
+ )
46314
+ ).limit(1);
46315
+ if (!existing) throw new Error("Failed to reconcile connector action policy default");
46316
+ return { policy: existing, changed: false };
46317
+ }
46318
+ await tx.insert(auditEvents).values(
46319
+ withLosslessContentWriteVersion(
46320
+ {
46321
+ accountId: input.accountId,
46322
+ workspaceId: input.workspaceId,
46323
+ subjectId,
46324
+ action: "connector.action.policy_changed",
46325
+ targetType: "connector_action_policy",
46326
+ targetId: inserted.id,
46327
+ metadata: {
46328
+ connectionId: inserted.connectionId,
46329
+ serverId: inserted.serverId,
46330
+ toolName: inserted.toolName,
46331
+ actionName: inserted.actionName,
46332
+ policy: inserted.policy,
46333
+ version: inserted.version,
46334
+ previousPolicy: null,
46335
+ previousVersion: null,
46336
+ source: "connector_default"
46337
+ }
46338
+ },
46339
+ "metadata",
46340
+ "metadataCodecVersion"
46341
+ )
46342
+ );
46343
+ return { policy: inserted, changed: true };
46344
+ })
46345
+ );
46346
+ }
45902
46347
  async function prepareConnectorActionApproval(db, identity, invocation) {
45903
46348
  const normalized = normalizedConnectorActionInvocation(identity, invocation);
45904
46349
  if (!normalized.connectionId) {
@@ -46398,7 +46843,7 @@ async function createSessionInTransaction(tx, input, id) {
46398
46843
  accountId: input.accountId,
46399
46844
  workspaceId: input.workspaceId,
46400
46845
  initialMessage: input.initialMessage,
46401
- initialTurnInstructions: input.initialTurnInstructions ?? null,
46846
+ initialModelContext: input.initialModelContext ?? null,
46402
46847
  resources: input.resources,
46403
46848
  skills: input.skills ?? [],
46404
46849
  tools: input.tools ?? [],
@@ -51081,7 +51526,7 @@ function validatedLegacyNativeSnapshotAdoption(value) {
51081
51526
  if (Buffer.from(bytes).toString("base64") !== value.archiveBase64) return null;
51082
51527
  const descriptor = parseArchiveRevision(value.descriptor);
51083
51528
  const native = decodeNativeSnapshotRef(bytes);
51084
- if (descriptor?.version !== 2 || !native || descriptor.archiveBytes !== bytes.length || descriptor.archiveSha256 !== createHash28("sha256").update(bytes).digest("hex") || descriptor.provider !== native.provider || descriptor.snapshotId !== native.snapshotId || descriptor.workspacePersistence !== native.workspacePersistence) {
51529
+ if (descriptor?.version !== 2 || !native || descriptor.archiveBytes !== bytes.length || descriptor.archiveSha256 !== createHash29("sha256").update(bytes).digest("hex") || descriptor.provider !== native.provider || descriptor.snapshotId !== native.snapshotId || descriptor.workspacePersistence !== native.workspacePersistence) {
51085
51530
  return null;
51086
51531
  }
51087
51532
  return { archiveBase64: value.archiveBase64, descriptor };
@@ -51730,7 +52175,7 @@ var MODAL_ARCHIVE_PREFIXES = [
51730
52175
  var COLD_LOST_PROVIDER_OBSERVATION_MAX_AGE_MS = 5 * 60 * 1e3;
51731
52176
  var COLD_LOST_PROVIDER_OBSERVATION_MAX_FUTURE_MS = 60 * 1e3;
51732
52177
  function sha256String(value) {
51733
- return createHash28("sha256").update(value).digest("hex");
52178
+ return createHash29("sha256").update(value).digest("hex");
51734
52179
  }
51735
52180
  function decodeCanonicalBase64(value) {
51736
52181
  if (typeof value !== "string" || value.length === 0 || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(value)) {
@@ -55676,7 +56121,7 @@ function validatedModalCheckpoint(input) {
55676
56121
  throw new Error("Checkpoint artifact archive is not canonical base64");
55677
56122
  }
55678
56123
  const native = decodeNativeSnapshotRef(bytes);
55679
- const sha2568 = createHash28("sha256").update(bytes).digest("hex");
56124
+ const sha2568 = createHash29("sha256").update(bytes).digest("hex");
55680
56125
  if (!native || native.provider !== descriptor.provider || native.snapshotId !== descriptor.snapshotId || native.workspacePersistence !== descriptor.workspacePersistence || descriptor.archiveBytes !== bytes.length || descriptor.archiveSha256 !== sha2568) {
55681
56126
  throw new Error("Checkpoint artifact receipt does not match its verified descriptor");
55682
56127
  }
@@ -57059,7 +57504,7 @@ var MachineRemovalRevisionConflictError = class extends Error {
57059
57504
  name = "MachineRemovalRevisionConflictError";
57060
57505
  };
57061
57506
  function machineRemovalFingerprint(enrollmentId, expectedUpdatedAt) {
57062
- return createHash28("sha256").update(
57507
+ return createHash29("sha256").update(
57063
57508
  JSON.stringify({
57064
57509
  enrollmentId,
57065
57510
  expectedUpdatedAt: expectedUpdatedAt ?? null
@@ -59876,7 +60321,7 @@ async function materializeGoalContinuation(db, input) {
59876
60321
  eq43(sessionGoals.sessionId, input.sessionId)
59877
60322
  )
59878
60323
  ).for("update").limit(1);
59879
- if (!goalRead || goalRead.status !== "active" || session.status === "cancelled" || effectiveControl.state !== "active") {
60324
+ if (!goalRead || goalRead.status !== "active" || session.status === "failed" || session.status === "cancelled" || effectiveControl.state !== "active") {
59880
60325
  return { action: "none", events: [] };
59881
60326
  }
59882
60327
  const malformedGoalVersionEvidence = sql39`
@@ -60453,6 +60898,7 @@ async function initializeSessionStartAtomically(db, input) {
60453
60898
  type: "user.message",
60454
60899
  payload: {
60455
60900
  ...initialPayload,
60901
+ ...session.initialModelContext ? { modelContext: session.initialModelContext } : {},
60456
60902
  initiator: creator.initiator
60457
60903
  },
60458
60904
  clientEventId: input.clientEventId ?? `session-initial:${session.id}`
@@ -60499,7 +60945,7 @@ async function initializeSessionStartAtomically(db, input) {
60499
60945
  source: "user",
60500
60946
  position: queueTailPosition,
60501
60947
  prompt: canonicalInitialMessage,
60502
- turnInstructions: session.initialTurnInstructions ?? null,
60948
+ modelContext: session.initialModelContext ?? null,
60503
60949
  resources: session.resources,
60504
60950
  tools: session.tools,
60505
60951
  toolsProvided: session.toolPolicy?.mode === "explicit",
@@ -60654,7 +61100,7 @@ async function enqueueSessionTurn(db, input) {
60654
61100
  source: input.source,
60655
61101
  position,
60656
61102
  prompt: input.prompt,
60657
- turnInstructions: input.turnInstructions ?? null,
61103
+ modelContext: input.modelContext ?? null,
60658
61104
  resources: input.resources,
60659
61105
  tools: input.tools,
60660
61106
  toolsProvided: input.toolsProvided ?? false,
@@ -60870,9 +61316,14 @@ async function goalSnapshotForAcceptedTurnInTransaction(tx, row) {
60870
61316
  }
60871
61317
  async function claimSessionWorkForAttempt(db, workspaceId, input) {
60872
61318
  const { sessionId, workflowId } = input;
60873
- return await withWorkspaceSessionActivityRls(
61319
+ return await retrySessionActivityRls(
60874
61320
  db,
60875
61321
  workspaceId,
61322
+ {
61323
+ stage: "session_attempts.claim",
61324
+ eventTypes: ["session.turn.attempt_claimed"],
61325
+ maxAttempts: 3
61326
+ },
60876
61327
  async (scopedDb) => await withSessionActivitySavepoint(scopedDb, async (tx) => {
60877
61328
  const deliverPendingUpdates = async (accountId, turnId, turnGeneration, nextSequence, occurredAt, triggerEventId, expectedXaiAuthority) => {
60878
61329
  const [agentSteer] = await tx.select().from(sessionSystemUpdates).where(
@@ -61929,7 +62380,8 @@ async function claimSessionWorkForAttempt(db, workspaceId, input) {
61929
62380
  item: durableUserHistoryItem(
61930
62381
  fromPostgresLosslessText(row.prompt, row.promptCodecVersion),
61931
62382
  Array.isArray(row.resources) ? row.resources : [],
61932
- TimelineAnnotations2.parse(row.annotations)
62383
+ TimelineAnnotations2.parse(row.annotations),
62384
+ row.modelContext
61933
62385
  )
61934
62386
  },
61935
62387
  "item",
@@ -63026,6 +63478,317 @@ async function peekSessionWork(db, workspaceId, sessionId) {
63026
63478
  return pendingAgentSteer ? { kind: "runnable" } : { kind: "idle" };
63027
63479
  });
63028
63480
  }
63481
+ async function failSessionWorkBeforeAttemptClaim(db, workspaceId, input) {
63482
+ return await retrySessionActivityRls(
63483
+ db,
63484
+ workspaceId,
63485
+ {
63486
+ stage: "session_lifecycle_outbox.fail_before_attempt_claim",
63487
+ eventTypes: ["child_terminal_result", "session.status.changed", "turn.failed"],
63488
+ maxAttempts: 3
63489
+ },
63490
+ async (scopedDb) => await scopedDb.transaction(async (tx) => {
63491
+ const baseLocks = await lockChildLifecycleOutboxWriteRowsTx(
63492
+ tx,
63493
+ workspaceId,
63494
+ { sessionId: input.sessionId }
63495
+ );
63496
+ const session = baseLocks.session;
63497
+ if (session.accountId !== input.accountId) {
63498
+ throw new SessionControlInvariantError(
63499
+ `Session ${input.sessionId} does not belong to account ${input.accountId}`
63500
+ );
63501
+ }
63502
+ if (session.status === "failed" || session.status === "cancelled") {
63503
+ return { action: "terminal", turnId: null, events: [] };
63504
+ }
63505
+ if (session.temporalWorkflowId !== null && session.temporalWorkflowId !== input.workflowId) {
63506
+ return { action: "stale", turnId: null, events: [] };
63507
+ }
63508
+ const effectiveControl = await evaluateSessionControl(
63509
+ tx,
63510
+ workspaceId,
63511
+ input.sessionId,
63512
+ { workspaceControl: baseLocks.control ?? void 0 }
63513
+ );
63514
+ if (!baseLocks.workspace || effectiveControl.state !== "active") {
63515
+ return { action: "stale", turnId: null, events: [] };
63516
+ }
63517
+ const [liveAttempt] = await tx.select({ id: sessionTurnAttempts.id }).from(sessionTurnAttempts).where(
63518
+ and42(
63519
+ eq43(sessionTurnAttempts.workspaceId, workspaceId),
63520
+ eq43(sessionTurnAttempts.sessionId, input.sessionId),
63521
+ inArray25(sessionTurnAttempts.state, ["claimed", "running"])
63522
+ )
63523
+ ).limit(1);
63524
+ if (liveAttempt) {
63525
+ return { action: "stale", turnId: null, events: [] };
63526
+ }
63527
+ let turn = null;
63528
+ if (session.activeTurnId) {
63529
+ const exactLocks = await lockSessionEventWriteRows(tx, {
63530
+ workspaceId,
63531
+ controlLock: "already_locked",
63532
+ workspaceLock: "already_locked",
63533
+ turnIds: [session.activeTurnId]
63534
+ });
63535
+ turn = exactLocks.turns[0] ?? null;
63536
+ if (!turn || turn.accountId !== session.accountId || turn.sessionId !== input.sessionId) {
63537
+ turn = null;
63538
+ }
63539
+ if (turn && isTerminalSessionTurnStatus(turn.status)) {
63540
+ turn = null;
63541
+ } else if (turn && input.trigger.kind === "approval") {
63542
+ if (turn.status !== "requires_action" || !await isNewerApprovalTrigger(
63543
+ tx,
63544
+ workspaceId,
63545
+ input.sessionId,
63546
+ turn.triggerEventId,
63547
+ input.trigger.triggerEventId
63548
+ )) {
63549
+ return { action: "stale", turnId: null, events: [] };
63550
+ }
63551
+ } else if (turn) {
63552
+ if (turn.status === "requires_action") {
63553
+ return { action: "stale", turnId: null, events: [] };
63554
+ }
63555
+ if (turn.status === "waiting_capacity") {
63556
+ const [codexWaiter] = await tx.select({ id: codexCapacityWaiters.id }).from(codexCapacityWaiters).where(
63557
+ and42(
63558
+ eq43(codexCapacityWaiters.workspaceId, workspaceId),
63559
+ eq43(codexCapacityWaiters.sessionId, input.sessionId),
63560
+ eq43(codexCapacityWaiters.status, "waiting")
63561
+ )
63562
+ ).limit(1);
63563
+ const xaiWaiter = await getXaiCapacityWaitForSessionInTransaction(
63564
+ tx,
63565
+ workspaceId,
63566
+ input.sessionId
63567
+ );
63568
+ if (codexWaiter || xaiWaiter) {
63569
+ return { action: "stale", turnId: null, events: [] };
63570
+ }
63571
+ }
63572
+ }
63573
+ } else {
63574
+ if (input.trigger.kind === "approval") {
63575
+ return { action: "stale", turnId: null, events: [] };
63576
+ }
63577
+ const [pendingAgentSteer] = await tx.select({ id: sessionSystemUpdates.id }).from(sessionSystemUpdates).where(
63578
+ and42(
63579
+ eq43(sessionSystemUpdates.workspaceId, workspaceId),
63580
+ eq43(sessionSystemUpdates.sessionId, input.sessionId),
63581
+ eq43(sessionSystemUpdates.kind, "agent_steer_instruction"),
63582
+ eq43(sessionSystemUpdates.state, "pending")
63583
+ )
63584
+ ).orderBy(
63585
+ desc17(sessionSystemUpdates.createdAt),
63586
+ desc17(sessionSystemUpdates.id)
63587
+ ).limit(1);
63588
+ const queuedRows = await rawRows(
63589
+ tx,
63590
+ sql39`select id from session_turns
63591
+ where workspace_id = ${workspaceId} and session_id = ${input.sessionId}
63592
+ and status = 'queued' and source in ('user', 'api')
63593
+ and (
63594
+ ${Boolean(pendingAgentSteer)} = false
63595
+ or metadata->>'delivery' = 'steer'
63596
+ )
63597
+ order by position asc, created_at asc, id asc
63598
+ limit 1`
63599
+ );
63600
+ const queuedPreview = queuedRows[0];
63601
+ if (queuedPreview) {
63602
+ const exactLocks = await lockSessionEventWriteRows(tx, {
63603
+ workspaceId,
63604
+ controlLock: "already_locked",
63605
+ workspaceLock: "already_locked",
63606
+ turnIds: [queuedPreview.id]
63607
+ });
63608
+ turn = exactLocks.turns[0] ?? null;
63609
+ if (!turn || turn.accountId !== session.accountId || turn.sessionId !== input.sessionId || turn.status !== "queued" || turn.activeAttemptId !== null) {
63610
+ return { action: "stale", turnId: null, events: [] };
63611
+ }
63612
+ } else if (!session.compactRequested) {
63613
+ if (!pendingAgentSteer && await latestFinishedTurnHasFailureCodeTx(
63614
+ tx,
63615
+ workspaceId,
63616
+ input.sessionId,
63617
+ "context_compaction_failed"
63618
+ )) {
63619
+ return { action: "stale", turnId: null, events: [] };
63620
+ }
63621
+ const [pendingUpdate] = await tx.select({ id: sessionSystemUpdates.id }).from(sessionSystemUpdates).where(
63622
+ and42(
63623
+ eq43(sessionSystemUpdates.workspaceId, workspaceId),
63624
+ eq43(sessionSystemUpdates.sessionId, input.sessionId),
63625
+ eq43(sessionSystemUpdates.state, "pending")
63626
+ )
63627
+ ).limit(1).for("update");
63628
+ if (!pendingUpdate) {
63629
+ return { action: "stale", turnId: null, events: [] };
63630
+ }
63631
+ }
63632
+ }
63633
+ const now = /* @__PURE__ */ new Date();
63634
+ let sequence = session.lastSequence;
63635
+ let closedToolEvents = [];
63636
+ if (turn) {
63637
+ await cancelTurnInteractionInterventionsInTransaction(tx, {
63638
+ accountId: session.accountId,
63639
+ workspaceId,
63640
+ sessionId: input.sessionId,
63641
+ turnId: turn.id
63642
+ });
63643
+ const closedTools = await closePendingSessionToolCallsInTransaction(
63644
+ tx,
63645
+ {
63646
+ accountId: session.accountId,
63647
+ workspaceId,
63648
+ sessionId: input.sessionId,
63649
+ turnId: turn.id,
63650
+ reason: "turn_failed",
63651
+ sequence,
63652
+ now
63653
+ }
63654
+ );
63655
+ sequence = closedTools.sequence;
63656
+ closedToolEvents = closedTools.events;
63657
+ await tx.update(sessionHumanInputRequests).set({
63658
+ status: "cancelled",
63659
+ response: { outcome: "cancelled" },
63660
+ respondedBy: "system:turn_failed",
63661
+ respondedAt: now,
63662
+ updatedAt: now
63663
+ }).where(
63664
+ and42(
63665
+ eq43(sessionHumanInputRequests.workspaceId, workspaceId),
63666
+ eq43(sessionHumanInputRequests.sessionId, input.sessionId),
63667
+ eq43(sessionHumanInputRequests.turnId, turn.id),
63668
+ eq43(sessionHumanInputRequests.status, "pending")
63669
+ )
63670
+ );
63671
+ }
63672
+ await settleSessionMaintenanceInTransaction(tx, {
63673
+ accountId: session.accountId,
63674
+ workspaceId,
63675
+ sessionId: input.sessionId
63676
+ });
63677
+ if (!turn) {
63678
+ await tx.update(sessionSystemUpdates).set({ state: "failed" }).where(
63679
+ and42(
63680
+ eq43(sessionSystemUpdates.workspaceId, workspaceId),
63681
+ eq43(sessionSystemUpdates.sessionId, input.sessionId),
63682
+ eq43(sessionSystemUpdates.state, "pending")
63683
+ )
63684
+ );
63685
+ }
63686
+ const values = [
63687
+ ...turn ? [
63688
+ {
63689
+ accountId: session.accountId,
63690
+ workspaceId,
63691
+ sessionId: input.sessionId,
63692
+ sequence: ++sequence,
63693
+ type: "turn.failed",
63694
+ payload: {
63695
+ triggerEventId: turn.triggerEventId,
63696
+ code: "pre_claim_failure",
63697
+ error: input.error
63698
+ },
63699
+ turnId: turn.id,
63700
+ turnGeneration: turn.executionGeneration,
63701
+ turnAttemptId: null,
63702
+ turnAssociation: "current",
63703
+ occurredAt: now
63704
+ }
63705
+ ] : [],
63706
+ {
63707
+ accountId: session.accountId,
63708
+ workspaceId,
63709
+ sessionId: input.sessionId,
63710
+ sequence: ++sequence,
63711
+ type: "session.status.changed",
63712
+ payload: { status: "failed", code: "pre_claim_failure" },
63713
+ turnId: turn?.id ?? null,
63714
+ turnGeneration: turn?.executionGeneration ?? null,
63715
+ turnAttemptId: null,
63716
+ turnAssociation: turn ? "current" : null,
63717
+ occurredAt: now
63718
+ }
63719
+ ];
63720
+ const inserted = await tx.insert(sessionEvents).values(withLosslessContentWriteVersion(values, "payload", "payloadCodecVersion")).returning();
63721
+ if (turn) {
63722
+ const failedEvent = inserted.find((event) => event.type === "turn.failed");
63723
+ if (!failedEvent) {
63724
+ throw new SessionControlInvariantError(
63725
+ `Pre-claim failure for turn ${turn.id} has no terminal event`
63726
+ );
63727
+ }
63728
+ await projectSessionRealtimeDelegationTerminalInTransaction(tx, {
63729
+ accountId: session.accountId,
63730
+ workspaceId,
63731
+ sessionId: input.sessionId,
63732
+ turnId: turn.id,
63733
+ turnStatus: "failed",
63734
+ terminalEvent: {
63735
+ id: failedEvent.id,
63736
+ type: "turn.failed",
63737
+ payload: sessionEventPayloadRecord(
63738
+ failedEvent.payload,
63739
+ failedEvent.payloadCodecVersion
63740
+ )
63741
+ },
63742
+ now
63743
+ });
63744
+ await tx.update(sessionTurns).set({
63745
+ status: "failed",
63746
+ activeAttemptId: null,
63747
+ version: turn.version + 1,
63748
+ finishedAt: now,
63749
+ updatedAt: now
63750
+ }).where(
63751
+ and42(
63752
+ eq43(sessionTurns.workspaceId, workspaceId),
63753
+ eq43(sessionTurns.sessionId, input.sessionId),
63754
+ eq43(sessionTurns.id, turn.id)
63755
+ )
63756
+ );
63757
+ await enqueueFailedChildOutboxForTurnTx(
63758
+ tx,
63759
+ workspaceId,
63760
+ session,
63761
+ turn
63762
+ );
63763
+ } else {
63764
+ await enqueueFailedChildOutboxWithoutTurnTx(
63765
+ tx,
63766
+ workspaceId,
63767
+ session,
63768
+ sequence
63769
+ );
63770
+ }
63771
+ await tx.update(sessions).set({
63772
+ status: "failed",
63773
+ activeTurnId: null,
63774
+ compactRequested: false,
63775
+ lastSequence: sequence,
63776
+ queueVersion: session.queueVersion + 1,
63777
+ updatedAt: now
63778
+ }).where(
63779
+ and42(
63780
+ eq43(sessions.workspaceId, workspaceId),
63781
+ eq43(sessions.id, input.sessionId)
63782
+ )
63783
+ );
63784
+ return {
63785
+ action: "failed",
63786
+ turnId: turn?.id ?? null,
63787
+ events: [...closedToolEvents, ...inserted.map(mapEvent2)]
63788
+ };
63789
+ })
63790
+ );
63791
+ }
63029
63792
  async function lockChildLifecycleOutboxWriteRowsTx(tx, workspaceId, input) {
63030
63793
  const prefix = await lockSessionEventWriteRows(tx, {
63031
63794
  workspaceId,
@@ -65004,9 +65767,8 @@ function queuedSteerReplacementAttemptId(metadata) {
65004
65767
  }
65005
65768
  return null;
65006
65769
  }
65007
- async function enqueueFailedChildOutboxForTurnTx(tx, workspaceId, session, turn) {
65770
+ async function enqueueFailedChildOutboxTx(tx, workspaceId, session, input) {
65008
65771
  if (!session.parentSessionId) return;
65009
- const dedupeKey = `child-completion:${turn.sessionId}:turn:${turn.id}`;
65010
65772
  const personalConnectionDelegations = session.parentTurnId ? await personalConnectionDelegationsForTurnInTransaction(
65011
65773
  tx,
65012
65774
  workspaceId,
@@ -65038,26 +65800,26 @@ async function enqueueFailedChildOutboxForTurnTx(tx, workspaceId, session, turn)
65038
65800
  withLosslessContentWriteVersion(
65039
65801
  withLosslessContentWriteVersion(
65040
65802
  {
65041
- accountId: turn.accountId,
65803
+ accountId: session.accountId,
65042
65804
  workspaceId,
65043
- sourceSessionId: turn.sessionId,
65805
+ sourceSessionId: session.id,
65044
65806
  targetSessionId: session.parentSessionId,
65045
- dedupeKey,
65807
+ dedupeKey: input.dedupeKey,
65046
65808
  kind: "child_terminal_result",
65047
65809
  classification: "failure",
65048
- sourceId: turn.sessionId,
65810
+ sourceId: session.id,
65049
65811
  summary: "Child session failed; inspect the durable child timeline.",
65050
65812
  payload: {
65051
65813
  type: "child_terminal_result",
65052
- childSessionId: turn.sessionId,
65814
+ childSessionId: session.id,
65053
65815
  status: "failed",
65054
- turnId: turn.id
65816
+ ...input.turnId ? { turnId: input.turnId } : {}
65055
65817
  },
65056
65818
  lineage: {
65057
- childSessionId: turn.sessionId,
65819
+ childSessionId: session.id,
65058
65820
  parentSessionId: session.parentSessionId,
65059
65821
  ...session.parentTurnId ? { parentTurnId: session.parentTurnId } : {},
65060
- turnId: turn.id,
65822
+ ...input.turnId ? { turnId: input.turnId } : {},
65061
65823
  ...xaiAuthoritySubjectId ? { xaiAuthoritySubjectId } : {}
65062
65824
  },
65063
65825
  personalConnectionDelegations,
@@ -65076,6 +65838,23 @@ async function enqueueFailedChildOutboxForTurnTx(tx, workspaceId, session, turn)
65076
65838
  ]
65077
65839
  });
65078
65840
  }
65841
+ async function enqueueFailedChildOutboxForTurnTx(tx, workspaceId, session, turn) {
65842
+ if (turn.accountId !== session.accountId || turn.sessionId !== session.id) {
65843
+ throw new SessionControlInvariantError(
65844
+ `Failed child turn ${turn.id} lost session ${session.id} ownership`
65845
+ );
65846
+ }
65847
+ await enqueueFailedChildOutboxTx(tx, workspaceId, session, {
65848
+ turnId: turn.id,
65849
+ dedupeKey: `child-completion:${turn.sessionId}:turn:${turn.id}`
65850
+ });
65851
+ }
65852
+ async function enqueueFailedChildOutboxWithoutTurnTx(tx, workspaceId, session, terminalSequence) {
65853
+ await enqueueFailedChildOutboxTx(tx, workspaceId, session, {
65854
+ turnId: null,
65855
+ dedupeKey: `child-completion:${session.id}:pre-claim:${terminalSequence}`
65856
+ });
65857
+ }
65079
65858
  function parseChildTerminalResultPayload(input) {
65080
65859
  const payload = SessionSystemUpdatePayload.parse(input);
65081
65860
  if (payload.type !== "child_terminal_result") {
@@ -65177,10 +65956,19 @@ async function enqueueSessionWorkflowWakeInTransaction(tx, input) {
65177
65956
  controlRevision: input.controlRequested ? sql39`${sessionWorkflowWakeOutbox.wakeRevision} + 1` : sql39`${sessionWorkflowWakeOutbox.controlRevision}`,
65178
65957
  reason: input.reason,
65179
65958
  attempts: 0,
65180
- // Coalescing a delayed retry must never postpone an already-due wake
65181
- // owned by another producer. A later revision makes the batch richer;
65182
- // it does not revoke the earlier delivery obligation.
65183
- nextAttemptAt: sql39`least(${sessionWorkflowWakeOutbox.nextAttemptAt}, ${nextAttemptAt.toISOString()}::timestamptz)`,
65959
+ // Coalescing a delayed retry must never postpone an undelivered wake
65960
+ // owned by another producer. Once every prior revision is delivered,
65961
+ // however, this is a new obligation and must honor its own deadline;
65962
+ // retaining the old (usually past) deadline would defeat backoff.
65963
+ nextAttemptAt: sql39`case
65964
+ when ${sessionWorkflowWakeOutbox.wakeRevision}
65965
+ > ${sessionWorkflowWakeOutbox.deliveredRevision}
65966
+ then least(
65967
+ ${sessionWorkflowWakeOutbox.nextAttemptAt},
65968
+ ${nextAttemptAt.toISOString()}::timestamptz
65969
+ )
65970
+ else ${nextAttemptAt.toISOString()}::timestamptz
65971
+ end`,
65184
65972
  lastError: null,
65185
65973
  updatedAt: now
65186
65974
  }
@@ -65980,7 +66768,7 @@ async function acceptSessionApprovalDecision(db, input) {
65980
66768
  );
65981
66769
  }
65982
66770
  function deterministicSystemUuid(seed) {
65983
- const bytes = createHash28("sha256").update(seed, "utf8").digest().subarray(0, 16);
66771
+ const bytes = createHash29("sha256").update(seed, "utf8").digest().subarray(0, 16);
65984
66772
  bytes[6] = (bytes[6] ?? 0) & 15 | 80;
65985
66773
  bytes[8] = (bytes[8] ?? 0) & 63 | 128;
65986
66774
  const hex = bytes.toString("hex");
@@ -66706,7 +67494,6 @@ function mapSessionTurn(row) {
66706
67494
  function mapSessionTurnForExecution(row) {
66707
67495
  return {
66708
67496
  ...mapSessionTurn(row),
66709
- turnInstructions: row.turnInstructions ?? null,
66710
67497
  initiatingHumanSubjectId: row.initiatingHumanSubjectId ?? null,
66711
67498
  personalConnectionDelegations: parsedPersonalConnectionDelegations(
66712
67499
  row.personalConnectionDelegations,
@@ -67735,6 +68522,7 @@ export {
67735
68522
  autoResumeSessionBranchInTransaction,
67736
68523
  backfillModelCallFactsFromSessionEvents,
67737
68524
  beginConnectorActionExecution,
68525
+ beginGoogleDriveObjectAclRefresh,
67738
68526
  beginImageGenerationOperation,
67739
68527
  beginKnowledgeSyncRun,
67740
68528
  beginRigChangeVerificationAttempt,
@@ -67991,6 +68779,7 @@ export {
67991
68779
  ensureCanonicalHumanIdentity,
67992
68780
  ensureCanonicalHumanIdentityForAuthUser,
67993
68781
  ensureCodexRotationSettings,
68782
+ ensureConnectorActionPolicyDefault,
67994
68783
  ensureIntegrationFacetDefinition,
67995
68784
  ensureKnowledgeSourceBlobFile,
67996
68785
  ensureKnowledgeSourceSyncState,
@@ -68019,6 +68808,7 @@ export {
68019
68808
  failMemorySlackPublication,
68020
68809
  failSandboxRematerialization,
68021
68810
  failSessionRealtimeConnectionInTransaction,
68811
+ failSessionWorkBeforeAttemptClaim,
68022
68812
  failTranscriptionRecordingAssembly,
68023
68813
  failTranscriptionRecordingSegment,
68024
68814
  failWarmingToCold,
@@ -68082,6 +68872,7 @@ export {
68082
68872
  getFile,
68083
68873
  getFileUpload,
68084
68874
  getFiles,
68875
+ getFilesForSubject,
68085
68876
  getGeneratedImageArtifact,
68086
68877
  getGeneratedVideoArtifact,
68087
68878
  getHostExportConsumerStatus,
@@ -68243,6 +69034,7 @@ export {
68243
69034
  isMemoryScopeApplicable,
68244
69035
  isMemoryTextTooLong,
68245
69036
  isPrivateAddress,
69037
+ isRetryableDatabaseTransportFailure,
68246
69038
  isRetryablePersistenceSqlState,
68247
69039
  isSessionCompactionRequested,
68248
69040
  isSessionEventPersistenceError,
@@ -68497,6 +69289,7 @@ export {
68497
69289
  recordConnectionTokenRefresh,
68498
69290
  recordConnectionUsed,
68499
69291
  recordGeneratedImageArtifactError,
69292
+ recordGoogleDriveObjectAclEvidence,
68500
69293
  recordKnowledgeLifecycleEvent,
68501
69294
  recordKnowledgeSourceSyncAclEvidence,
68502
69295
  recordKnowledgeSourceSyncItemOutcomes,
@@ -68568,6 +69361,7 @@ export {
68568
69361
  requestSessionTurnRecovery,
68569
69362
  requestSlackUserLinkWorkspaceAccess,
68570
69363
  requireFile,
69364
+ requireFileForSubject,
68571
69365
  requireScheduledTask,
68572
69366
  requireScheduledTaskTargetInTransaction,
68573
69367
  requireSession,