@opengeni/db 3.7.4 → 4.0.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/automations.d.ts +4 -0
  2. package/dist/canonical-human-identities.js +3 -3
  3. package/dist/capability-integrations.d.ts +2 -0
  4. package/dist/{chunk-6DPJA36C.js → chunk-2XEZK4LF.js} +7 -1
  5. package/dist/chunk-2XEZK4LF.js.map +1 -0
  6. package/dist/{chunk-4NAR7FBA.js → chunk-3RI33YQN.js} +67 -1
  7. package/dist/chunk-3RI33YQN.js.map +1 -0
  8. package/dist/{chunk-SZAWDXQC.js → chunk-CJROYHSC.js} +3 -3
  9. package/dist/{chunk-DZCYW2WT.js → chunk-MX6V5F65.js} +2 -2
  10. package/dist/{chunk-S3TDDCS2.js → chunk-N5VXJ4I2.js} +151 -78
  11. package/dist/chunk-N5VXJ4I2.js.map +1 -0
  12. package/dist/{chunk-U4WPPEBH.js → chunk-NLFHMPUB.js} +2 -2
  13. package/dist/{chunk-5NNCGFQY.js → chunk-P6NSEG2S.js} +2 -2
  14. package/dist/{chunk-O56DM5GZ.js → chunk-QM6YOWHZ.js} +624 -57
  15. package/dist/chunk-QM6YOWHZ.js.map +1 -0
  16. package/dist/{chunk-US4IS6IV.js → chunk-RZNOSEMC.js} +2 -2
  17. package/dist/{chunk-F6PBS6WE.js → chunk-UFAMOUWL.js} +2 -2
  18. package/dist/codemode-operations.d.ts +5 -0
  19. package/dist/codex-token-resolver.d.ts +6 -2
  20. package/dist/connection-token-resolver.d.ts +8 -0
  21. package/dist/editable-artifact-durable-export.js +2 -2
  22. package/dist/editable-artifacts.js +3 -3
  23. package/dist/generated-images.d.ts +15 -0
  24. package/dist/index.d.ts +393 -91
  25. package/dist/index.js +9992 -6069
  26. package/dist/index.js.map +1 -1
  27. package/dist/insights.d.ts +9 -0
  28. package/dist/managed-auth-session-sets.js +3 -3
  29. package/dist/managed-user-setup.d.ts +3 -0
  30. package/dist/mcp-oauth.d.ts +80 -0
  31. package/dist/migrate.d.ts +1 -0
  32. package/dist/migrate.js +3 -1
  33. package/dist/model-catalog.d.ts +153 -0
  34. package/dist/model-context-snapshots.d.ts +20 -0
  35. package/dist/new-session-drafts.d.ts +12 -0
  36. package/dist/organization-membership-lifecycle.d.ts +8 -1
  37. package/dist/organization-model-providers.d.ts +101 -0
  38. package/dist/pack-components.d.ts +1 -0
  39. package/dist/pr-review.d.ts +9 -0
  40. package/dist/provision-roles.js +1 -1
  41. package/dist/runtime-posture.d.ts +8 -8
  42. package/dist/schema.d.ts +7708 -5050
  43. package/dist/schema.js +25 -1
  44. package/dist/session-background-commands.d.ts +18 -6
  45. package/dist/session-background-commands.js +15 -9
  46. package/dist/session-control.d.ts +37 -2
  47. package/dist/session-goal-pacing.d.ts +3 -6
  48. package/dist/session-queue-commands.d.ts +17 -0
  49. package/dist/session-tenancy.js +3 -3
  50. package/dist/tool-gateway-approvals.d.ts +31 -0
  51. package/dist/video-generation.js +3 -3
  52. package/dist/workspace-artifacts.d.ts +17 -3
  53. package/dist/xai-subscription.d.ts +8 -0
  54. package/drizzle/0387_bound_host_export_session_payloads.sql +165 -0
  55. package/drizzle/0388_sandbox_provider_deadline_interactions.sql +491 -0
  56. package/drizzle/0389_model_catalog_and_gateway_custom_models.sql +241 -0
  57. package/drizzle/0390_organization_model_provider_connections.sql +197 -0
  58. package/drizzle/0391_sandbox_provider_deadline_interaction_followup.sql +295 -0
  59. package/drizzle/0392_context_compaction_pending_observability.sql +198 -0
  60. package/drizzle/0393_workspace_memory_and_learning_defaults.sql +102 -0
  61. package/drizzle/0394_session_selected_skill_activation.sql +20 -0
  62. package/drizzle/0395_scheduled_task_unclaimed_occurrence_invalidation.sql +154 -0
  63. package/drizzle/0396_model_call_equivalent_credit_cost.sql +28 -0
  64. package/drizzle/0397_sandbox_deadline_rotation_preemption.sql +113 -0
  65. package/drizzle/0398_organization_workspace_management_entry.sql +206 -0
  66. package/drizzle/0399_additional_managed_organization_creation.sql +691 -0
  67. package/drizzle/0400_session_attempt_model_context_snapshots.sql +65 -0
  68. package/drizzle/0401_organization_user_setup_token_transport.sql +178 -0
  69. package/drizzle/0402_session_input_wait_and_background_command_results.sql +1023 -0
  70. package/drizzle/0403_codex_unconditional_credential_leasing.sql +181 -0
  71. package/drizzle/0404_mcp_oauth_authorization_server.sql +471 -0
  72. package/drizzle/0405_tool_gateway_approval_capabilities.sql +184 -0
  73. package/drizzle/0406_workspace_html_site_sources.sql +71 -0
  74. package/package.json +6 -6
  75. package/src/automations.ts +9 -1
  76. package/src/capability-integrations.ts +8 -0
  77. package/src/codemode-operations.ts +31 -21
  78. package/src/codex-token-resolver.ts +16 -6
  79. package/src/connection-token-resolver.ts +52 -3
  80. package/src/generated-images.ts +70 -6
  81. package/src/index.ts +3894 -994
  82. package/src/insights-model-bundle.ts +54 -5
  83. package/src/insights.ts +53 -7
  84. package/src/managed-user-setup.ts +14 -3
  85. package/src/mcp-oauth.ts +488 -0
  86. package/src/migrate.ts +9 -1
  87. package/src/model-catalog.ts +682 -0
  88. package/src/model-context-snapshots.ts +151 -0
  89. package/src/new-session-drafts.ts +66 -21
  90. package/src/organization-membership-lifecycle.ts +47 -5
  91. package/src/organization-model-providers.ts +614 -0
  92. package/src/pack-components.ts +15 -2
  93. package/src/pr-review.ts +19 -0
  94. package/src/provision-roles.ts +4 -0
  95. package/src/runtime-posture.ts +64 -0
  96. package/src/schema.ts +666 -61
  97. package/src/session-background-commands.ts +180 -78
  98. package/src/session-control.ts +181 -12
  99. package/src/session-goal-pacing.ts +4 -8
  100. package/src/session-queue-commands.ts +157 -82
  101. package/src/tool-gateway-approvals.ts +168 -0
  102. package/src/workspace-artifacts.ts +633 -178
  103. package/src/xai-subscription.ts +66 -14
  104. package/dist/chunk-4NAR7FBA.js.map +0 -1
  105. package/dist/chunk-6DPJA36C.js.map +0 -1
  106. package/dist/chunk-O56DM5GZ.js.map +0 -1
  107. package/dist/chunk-S3TDDCS2.js.map +0 -1
  108. /package/dist/{chunk-SZAWDXQC.js.map → chunk-CJROYHSC.js.map} +0 -0
  109. /package/dist/{chunk-DZCYW2WT.js.map → chunk-MX6V5F65.js.map} +0 -0
  110. /package/dist/{chunk-U4WPPEBH.js.map → chunk-NLFHMPUB.js.map} +0 -0
  111. /package/dist/{chunk-5NNCGFQY.js.map → chunk-P6NSEG2S.js.map} +0 -0
  112. /package/dist/{chunk-US4IS6IV.js.map → chunk-RZNOSEMC.js.map} +0 -0
  113. /package/dist/{chunk-F6PBS6WE.js.map → chunk-UFAMOUWL.js.map} +0 -0
@@ -0,0 +1,151 @@
1
+ import {
2
+ MODEL_CONTEXT_SNAPSHOT_MAX_UTF8_BYTES,
3
+ ModelContextSnapshot,
4
+ SessionModelContextResponse,
5
+ } from "@opengeni/contracts";
6
+ import { and, desc, eq, sql } from "drizzle-orm";
7
+ import type { Database } from "./database";
8
+ import { withRlsContext } from "./database";
9
+ import * as schema from "./schema";
10
+
11
+ export class ModelContextSnapshotAuthorityError extends Error {
12
+ readonly code = "model_context_snapshot_authority_mismatch";
13
+
14
+ constructor() {
15
+ super("Model context snapshot does not match the exact durable execution attempt");
16
+ this.name = "ModelContextSnapshotAuthorityError";
17
+ }
18
+ }
19
+
20
+ export async function persistModelContextSnapshot(
21
+ db: Database,
22
+ input: {
23
+ accountId: string;
24
+ workspaceId: string;
25
+ sessionId: string;
26
+ turnId: string;
27
+ attemptId: string;
28
+ executionGeneration: number;
29
+ snapshot: ModelContextSnapshot;
30
+ },
31
+ ): Promise<void> {
32
+ const snapshot = ModelContextSnapshot.parse(input.snapshot);
33
+ if (Buffer.byteLength(JSON.stringify(snapshot), "utf8") > MODEL_CONTEXT_SNAPSHOT_MAX_UTF8_BYTES) {
34
+ throw new RangeError("Model context snapshot exceeds the 16 MiB persist limit");
35
+ }
36
+ await withRlsContext(
37
+ db,
38
+ { accountId: input.accountId, workspaceId: input.workspaceId },
39
+ async (scopedDb) =>
40
+ await scopedDb.transaction(async (tx) => {
41
+ const [attempt] = await tx
42
+ .select({
43
+ accountId: schema.sessionTurnAttempts.accountId,
44
+ workspaceId: schema.sessionTurnAttempts.workspaceId,
45
+ sessionId: schema.sessionTurnAttempts.sessionId,
46
+ turnId: schema.sessionTurnAttempts.turnId,
47
+ executionGeneration: schema.sessionTurnAttempts.executionGeneration,
48
+ })
49
+ .from(schema.sessionTurnAttempts)
50
+ .where(
51
+ and(
52
+ eq(schema.sessionTurnAttempts.workspaceId, input.workspaceId),
53
+ eq(schema.sessionTurnAttempts.id, input.attemptId),
54
+ ),
55
+ )
56
+ .limit(1);
57
+ if (
58
+ !attempt ||
59
+ attempt.accountId !== input.accountId ||
60
+ attempt.sessionId !== input.sessionId ||
61
+ attempt.turnId !== input.turnId ||
62
+ attempt.executionGeneration !== input.executionGeneration
63
+ ) {
64
+ throw new ModelContextSnapshotAuthorityError();
65
+ }
66
+
67
+ const now = new Date(snapshot.capturedAt);
68
+ await tx
69
+ .insert(schema.sessionAttemptModelContextSnapshots)
70
+ .values({
71
+ attemptId: input.attemptId,
72
+ accountId: input.accountId,
73
+ workspaceId: input.workspaceId,
74
+ sessionId: input.sessionId,
75
+ turnId: input.turnId,
76
+ executionGeneration: input.executionGeneration,
77
+ requestIndex: snapshot.requestIndex,
78
+ capturedAt: now,
79
+ snapshot,
80
+ createdAt: now,
81
+ updatedAt: now,
82
+ })
83
+ .onConflictDoUpdate({
84
+ target: schema.sessionAttemptModelContextSnapshots.attemptId,
85
+ set: {
86
+ requestIndex: snapshot.requestIndex,
87
+ capturedAt: now,
88
+ snapshot,
89
+ updatedAt: now,
90
+ },
91
+ setWhere: sql`${schema.sessionAttemptModelContextSnapshots.requestIndex} <= ${snapshot.requestIndex}`,
92
+ });
93
+ }),
94
+ );
95
+ }
96
+
97
+ export async function getLatestSessionModelContext(
98
+ db: Database,
99
+ input: { accountId: string; workspaceId: string; sessionId: string },
100
+ ): Promise<SessionModelContextResponse> {
101
+ return await withRlsContext(
102
+ db,
103
+ { accountId: input.accountId, workspaceId: input.workspaceId },
104
+ async (scopedDb) => {
105
+ const [row] = await scopedDb
106
+ .select({
107
+ attemptId: schema.sessionAttemptModelContextSnapshots.attemptId,
108
+ turnId: schema.sessionAttemptModelContextSnapshots.turnId,
109
+ snapshot: schema.sessionAttemptModelContextSnapshots.snapshot,
110
+ })
111
+ .from(schema.sessionAttemptModelContextSnapshots)
112
+ .innerJoin(
113
+ schema.sessionTurns,
114
+ and(
115
+ eq(schema.sessionTurns.id, schema.sessionAttemptModelContextSnapshots.turnId),
116
+ eq(
117
+ schema.sessionTurns.workspaceId,
118
+ schema.sessionAttemptModelContextSnapshots.workspaceId,
119
+ ),
120
+ eq(schema.sessionTurns.sessionId, schema.sessionAttemptModelContextSnapshots.sessionId),
121
+ ),
122
+ )
123
+ .where(
124
+ and(
125
+ eq(schema.sessionAttemptModelContextSnapshots.workspaceId, input.workspaceId),
126
+ eq(schema.sessionAttemptModelContextSnapshots.sessionId, input.sessionId),
127
+ ),
128
+ )
129
+ .orderBy(
130
+ desc(schema.sessionTurns.position),
131
+ desc(schema.sessionAttemptModelContextSnapshots.executionGeneration),
132
+ desc(schema.sessionAttemptModelContextSnapshots.requestIndex),
133
+ )
134
+ .limit(1);
135
+ if (!row) {
136
+ return {
137
+ sessionId: input.sessionId,
138
+ attemptId: null,
139
+ turnId: null,
140
+ snapshot: null,
141
+ };
142
+ }
143
+ return {
144
+ sessionId: input.sessionId,
145
+ attemptId: row.attemptId,
146
+ turnId: row.turnId,
147
+ snapshot: ModelContextSnapshot.parse(row.snapshot),
148
+ };
149
+ },
150
+ );
151
+ }
@@ -357,23 +357,10 @@ export async function rememberNewSessionSelectionInTransaction(
357
357
  return Boolean(updated);
358
358
  }
359
359
 
360
- /**
361
- * Replace one exact accepted draft with the next-create safe seed. The row is
362
- * identity-serialized before the revision check so even the absent-row
363
- * revision-zero case cannot race a first save. Exact create callers receive a
364
- * typed conflict; legacy revision-only callers retain the old false/no-op
365
- * result. A missing row is an idempotent no-op.
366
- */
367
- export async function seedNewSessionDraftInTransaction(
360
+ async function lockCurrentNewSessionDraft(
368
361
  db: Database,
369
- input: {
370
- workspaceId: string;
371
- subjectId: string;
372
- expectedRevision: number;
373
- expectedSnapshot?: NewSessionDraftSnapshot;
374
- acceptedSelection?: AcceptedNewSessionSelection;
375
- },
376
- ): Promise<boolean> {
362
+ input: { workspaceId: string; subjectId: string },
363
+ ): Promise<NewSessionDraftRow | undefined> {
377
364
  await lockNewSessionDraftIdentity(db, input.workspaceId, input.subjectId);
378
365
  const [current] = await db
379
366
  .select()
@@ -386,14 +373,23 @@ export async function seedNewSessionDraftInTransaction(
386
373
  )
387
374
  .for("update")
388
375
  .limit(1);
376
+ return current;
377
+ }
378
+
379
+ async function lockExactNewSessionDraft(
380
+ db: Database,
381
+ input: {
382
+ workspaceId: string;
383
+ subjectId: string;
384
+ expectedRevision: number;
385
+ expectedSnapshot: NewSessionDraftSnapshot;
386
+ },
387
+ ): Promise<NewSessionDraftRow> {
388
+ const current = await lockCurrentNewSessionDraft(db, input);
389
389
  if (!current || current.revision !== input.expectedRevision) {
390
- if (input.expectedSnapshot) {
391
- throw new NewSessionDraftConflictError(current?.revision ?? 0);
392
- }
393
- return false;
390
+ throw new NewSessionDraftConflictError(current?.revision ?? 0);
394
391
  }
395
392
  if (
396
- input.expectedSnapshot &&
397
393
  stableJson({
398
394
  text: current.text,
399
395
  resources: current.resources,
@@ -407,6 +403,55 @@ export async function seedNewSessionDraftInTransaction(
407
403
  ) {
408
404
  throw new NewSessionDraftConflictError(current.revision);
409
405
  }
406
+ return current;
407
+ }
408
+
409
+ /**
410
+ * Fence a fresh session shell on the exact actor-private draft it represents.
411
+ * The caller keeps this row lock through its create transaction, so a draft
412
+ * that was already stale cannot leave a committed, uninitialized session.
413
+ * The later atomic initializer still performs the authoritative consume.
414
+ */
415
+ export async function assertExactNewSessionDraftInTransaction(
416
+ db: Database,
417
+ input: {
418
+ workspaceId: string;
419
+ subjectId: string;
420
+ expectedRevision: number;
421
+ expectedSnapshot: NewSessionDraftSnapshot;
422
+ },
423
+ ): Promise<void> {
424
+ await lockExactNewSessionDraft(db, input);
425
+ }
426
+
427
+ /**
428
+ * Replace one exact accepted draft with the next-create safe seed. The row is
429
+ * identity-serialized before the revision check so even the absent-row
430
+ * revision-zero case cannot race a first save. Exact create callers receive a
431
+ * typed conflict; legacy revision-only callers retain the old false/no-op
432
+ * result. A missing row is an idempotent no-op.
433
+ */
434
+ export async function seedNewSessionDraftInTransaction(
435
+ db: Database,
436
+ input: {
437
+ workspaceId: string;
438
+ subjectId: string;
439
+ expectedRevision: number;
440
+ expectedSnapshot?: NewSessionDraftSnapshot;
441
+ acceptedSelection?: AcceptedNewSessionSelection;
442
+ },
443
+ ): Promise<boolean> {
444
+ const current = input.expectedSnapshot
445
+ ? await lockExactNewSessionDraft(db, {
446
+ workspaceId: input.workspaceId,
447
+ subjectId: input.subjectId,
448
+ expectedRevision: input.expectedRevision,
449
+ expectedSnapshot: input.expectedSnapshot,
450
+ })
451
+ : await lockCurrentNewSessionDraft(db, input);
452
+ if (!current || current.revision !== input.expectedRevision) {
453
+ return false;
454
+ }
410
455
 
411
456
  const parsedOptions = NewSessionDraftOptions.safeParse(publicNewSessionDraftOptions(current));
412
457
  const options = parsedOptions.success ? parsedOptions.data : {};
@@ -1,4 +1,5 @@
1
1
  import {
2
+ CreateAdditionalOrganizationResponse,
2
3
  CreateOrganizationResponse,
3
4
  ListOrganizationAdministrationMembersResponse,
4
5
  ListOrganizationInvitationsResponse,
@@ -18,6 +19,7 @@ import {
18
19
  OrganizationRetentionPolicy,
19
20
  OrganizationSummary,
20
21
  RevokeOrganizationWorkspaceMemberResponse,
22
+ type CreateAdditionalOrganizationResponse as CreateAdditionalOrganizationResponseType,
21
23
  type CreateOrganizationResponse as CreateOrganizationResponseType,
22
24
  type OrganizationAdministrationMember as OrganizationAdministrationMemberType,
23
25
  type OrganizationAdministrationOverview as OrganizationAdministrationOverviewType,
@@ -74,6 +76,32 @@ export async function createManagedOrganization(
74
76
  });
75
77
  }
76
78
 
79
+ export async function createAdditionalManagedOrganization(
80
+ db: Database,
81
+ input: {
82
+ subjectId: string;
83
+ subjectLabel: string;
84
+ name: string;
85
+ workspaceName: string;
86
+ operationId: string;
87
+ },
88
+ ): Promise<CreateAdditionalOrganizationResponseType> {
89
+ return await db.transaction(async (tx) => {
90
+ await setSubjectRlsContext(tx as unknown as Database, input.subjectId);
91
+ const [row] = await rawRows<{ result: unknown }>(
92
+ tx,
93
+ sql`select create_additional_managed_organization(
94
+ ${input.subjectId},
95
+ ${input.subjectLabel},
96
+ ${input.name},
97
+ ${input.workspaceName},
98
+ ${input.operationId}::uuid
99
+ ) as result`,
100
+ );
101
+ return CreateAdditionalOrganizationResponse.parse(row?.result);
102
+ });
103
+ }
104
+
77
105
  /**
78
106
  * Bounded replay of one exact organization-lifecycle transaction after a
79
107
  * PostgreSQL deadlock abort.
@@ -208,7 +236,10 @@ async function settleOrganizationMembershipProtocols(
208
236
  db: Database,
209
237
  settlements: OrganizationMembershipProtocolSettlement[],
210
238
  ): Promise<void> {
211
- const [prior] = await rawRows<{ subject_id: string; initiating_human_subject_id: string }>(
239
+ const [prior] = await rawRows<{
240
+ subject_id: string;
241
+ initiating_human_subject_id: string;
242
+ }>(
212
243
  db,
213
244
  sql`select
214
245
  coalesce(current_setting('opengeni.subject_id', true), '') as subject_id,
@@ -436,7 +467,9 @@ async function runOrganizationWorkspaceCommand(
436
467
  { accountId: command.organizationId, workspaceId: null },
437
468
  async (scopedDb) => {
438
469
  await setSubjectRlsContext(scopedDb, command.actorSubjectId);
439
- const [row] = await rawRows<{ result: OrganizationWorkspaceCommandResult }>(
470
+ const [row] = await rawRows<{
471
+ result: OrganizationWorkspaceCommandResult;
472
+ }>(
440
473
  scopedDb,
441
474
  sql`select organization_workspace_command(${JSON.stringify(command)}::jsonb) as result`,
442
475
  );
@@ -455,7 +488,10 @@ export async function createOrganizationWorkspace(
455
488
  operationId: string;
456
489
  },
457
490
  ): Promise<OrganizationWorkspaceAccessType> {
458
- const command = await runOrganizationWorkspaceCommand(db, { action: "create", ...input });
491
+ const command = await runOrganizationWorkspaceCommand(db, {
492
+ action: "create",
493
+ ...input,
494
+ });
459
495
  const overview = await getOrganizationAdministrationOverview(db, input);
460
496
  const workspace = overview.workspaces.find((candidate) => candidate.id === command.workspaceId);
461
497
  if (!workspace) throw new Error("Created organization workspace is missing from its overview");
@@ -615,7 +651,9 @@ export async function assertActiveManagedHumanOrganizationMembership(
615
651
  db: Database,
616
652
  input: { accountId: string; subjectId: string },
617
653
  ): Promise<number | null> {
618
- const [row] = await rawRows<{ authorization_revision: number | string | null }>(
654
+ const [row] = await rawRows<{
655
+ authorization_revision: number | string | null;
656
+ }>(
619
657
  db,
620
658
  sql`select assert_active_managed_human_organization_membership(
621
659
  ${input.accountId}::uuid,
@@ -1098,7 +1136,11 @@ export async function previewOrganizationRetentionDeletions(
1098
1136
 
1099
1137
  export async function claimOrganizationRetentionDeletion(
1100
1138
  db: Database,
1101
- input: { organizationId: string; operationId: string; excludedMembershipIds?: string[] },
1139
+ input: {
1140
+ organizationId: string;
1141
+ operationId: string;
1142
+ excludedMembershipIds?: string[];
1143
+ },
1102
1144
  ): Promise<OrganizationRetentionDeletionClaimType | null> {
1103
1145
  return await runRetentionCapability(db, input.organizationId, async (scopedDb) => {
1104
1146
  const excludedMembershipIds = input.excludedMembershipIds ?? [];