@opengeni/db 0.36.1 → 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 (47) hide show
  1. package/dist/canonical-human-identities.js +3 -3
  2. package/dist/{chunk-HSOWSYOX.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-VTPRIXKG.js → chunk-CUPM3FGB.js} +3 -3
  6. package/dist/{chunk-GYO7ED2Q.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-FPVAD4CO.js → chunk-WD5ROSLL.js} +2 -2
  10. package/dist/{chunk-Z7VYMNPZ.js → chunk-ZWREYEWA.js} +2 -2
  11. package/dist/editable-artifact-durable-export.d.ts +10 -0
  12. package/dist/editable-artifact-durable-export.js +18 -3
  13. package/dist/editable-artifact-durable-export.js.map +1 -1
  14. package/dist/editable-artifacts.js +3 -3
  15. package/dist/index.d.ts +40 -8
  16. package/dist/index.js +509 -59
  17. package/dist/index.js.map +1 -1
  18. package/dist/knowledge-source-sync-schema.d.ts +730 -0
  19. package/dist/knowledge-source-sync.d.ts +60 -0
  20. package/dist/provision-roles.js +1 -1
  21. package/dist/runtime-posture.d.ts +3 -3
  22. package/dist/schema.d.ts +21 -4
  23. package/dist/schema.js +5 -1
  24. package/dist/session-queue-commands.d.ts +1 -1
  25. package/dist/session-realtime-ledger.d.ts +1 -0
  26. package/dist/session-tenancy.js +3 -3
  27. package/dist/video-generation.js +3 -3
  28. package/drizzle/0240_model_context_user_messages.sql +204 -0
  29. package/drizzle/0243_google_drive_object_acl_authority.sql +554 -0
  30. package/package.json +4 -4
  31. package/src/editable-artifact-durable-export.ts +27 -0
  32. package/src/index.ts +212 -13
  33. package/src/knowledge-source-sync-schema.ts +83 -0
  34. package/src/knowledge-source-sync.ts +530 -0
  35. package/src/provision-roles.ts +36 -0
  36. package/src/runtime-posture.ts +49 -1
  37. package/src/schema.ts +30 -7
  38. package/src/session-queue-commands.ts +13 -14
  39. package/src/session-realtime-context.ts +16 -0
  40. package/src/session-realtime-ledger.ts +53 -1
  41. package/dist/chunk-5KTIEDX7.js.map +0 -1
  42. package/dist/chunk-VKLB2ZGI.js.map +0 -1
  43. /package/dist/{chunk-HSOWSYOX.js.map → chunk-4SR4HKKA.js.map} +0 -0
  44. /package/dist/{chunk-VTPRIXKG.js.map → chunk-CUPM3FGB.js.map} +0 -0
  45. /package/dist/{chunk-GYO7ED2Q.js.map → chunk-LTG3S6ZY.js.map} +0 -0
  46. /package/dist/{chunk-FPVAD4CO.js.map → chunk-WD5ROSLL.js.map} +0 -0
  47. /package/dist/{chunk-Z7VYMNPZ.js.map → chunk-ZWREYEWA.js.map} +0 -0
package/src/index.ts CHANGED
@@ -156,7 +156,7 @@ import {
156
156
  MODEL_ATTACHMENT_REFS_FIELD,
157
157
  MODEL_TIMELINE_ANNOTATIONS_FIELD,
158
158
  TimelineAnnotations,
159
- renderTimelineAnnotationsForModel,
159
+ renderUserMessageContentForModel,
160
160
  SessionMcpApprovalPolicy as SessionMcpApprovalPolicySchema,
161
161
  RequestHumanInteractionToolInput,
162
162
  WORKSPACE_XAI_PROVIDER_ACCOUNT_AUTHORITY_SNAPSHOT_V1,
@@ -4331,7 +4331,7 @@ export type EnqueueSessionTurnInput = {
4331
4331
  temporalWorkflowId: string;
4332
4332
  source: SessionTurnSource;
4333
4333
  prompt: string;
4334
- turnInstructions?: string | null;
4334
+ modelContext?: string | null;
4335
4335
  resources: ResourceRef[];
4336
4336
  tools: ToolRef[];
4337
4337
  toolsProvided?: boolean;
@@ -4350,12 +4350,8 @@ export type EnqueueSessionTurnInput = {
4350
4350
  placement?: "head" | "tail";
4351
4351
  };
4352
4352
 
4353
- /**
4354
- * Worker-only turn projection. Host instructions are durable execution input,
4355
- * never part of the public SessionTurn/queue/HTTP contract.
4356
- */
4353
+ /** Worker-only turn projection with causal authority omitted from public APIs. */
4357
4354
  export type SessionTurnForExecution = SessionTurn & {
4358
- turnInstructions: string | null;
4359
4355
  personalConnectionDelegations: McpPersonalConnectionDelegation[];
4360
4356
  /** Worker-only causal authority; never inferred from the current worker. */
4361
4357
  initiatingHumanSubjectId: string | null;
@@ -4581,6 +4577,89 @@ export async function requireFile(
4581
4577
  return file;
4582
4578
  }
4583
4579
 
4580
+ /**
4581
+ * Subject-bound file read for user-visible and model-injection surfaces. The
4582
+ * database predicate returns true for ordinary workspace files, but Drive-
4583
+ * derived bytes require current per-object ACL evidence for every protecting
4584
+ * mapping. Missing/stale/mixed denied mappings therefore look not found.
4585
+ */
4586
+ export async function requireFileForSubject(
4587
+ db: Database,
4588
+ input: {
4589
+ accountId: string;
4590
+ workspaceId: string;
4591
+ subjectId: string | null;
4592
+ fileId: string;
4593
+ },
4594
+ ): Promise<FileAsset> {
4595
+ return await withRlsContext(
4596
+ db,
4597
+ { accountId: input.accountId, workspaceId: input.workspaceId },
4598
+ async (scopedDb) => {
4599
+ if (input.subjectId) await setSubjectRlsContext(scopedDb, input.subjectId);
4600
+ const subjectIdSql = input.subjectId === null ? sql`NULL::text` : sql`${input.subjectId}`;
4601
+ const [row] = await scopedDb
4602
+ .select()
4603
+ .from(schema.files)
4604
+ .where(
4605
+ and(
4606
+ eq(schema.files.accountId, input.accountId),
4607
+ eq(schema.files.workspaceId, input.workspaceId),
4608
+ eq(schema.files.id, input.fileId),
4609
+ sql`google_drive_file_authorized(
4610
+ ${input.accountId}::uuid,
4611
+ ${input.workspaceId}::uuid,
4612
+ ${subjectIdSql},
4613
+ ${input.fileId}::uuid
4614
+ )`,
4615
+ ),
4616
+ )
4617
+ .limit(1);
4618
+ if (!row) throw new Error(`File not found: ${input.fileId}`);
4619
+ return mapFile(row);
4620
+ },
4621
+ );
4622
+ }
4623
+
4624
+ /** Batch form of requireFileForSubject for durable model-history projection. */
4625
+ export async function getFilesForSubject(
4626
+ db: Database,
4627
+ input: {
4628
+ accountId: string;
4629
+ workspaceId: string;
4630
+ subjectId: string | null;
4631
+ fileIds: readonly string[];
4632
+ },
4633
+ ): Promise<FileAsset[]> {
4634
+ const ids = [...new Set(input.fileIds)];
4635
+ if (ids.length === 0) return [];
4636
+ return await withRlsContext(
4637
+ db,
4638
+ { accountId: input.accountId, workspaceId: input.workspaceId },
4639
+ async (scopedDb) => {
4640
+ if (input.subjectId) await setSubjectRlsContext(scopedDb, input.subjectId);
4641
+ const subjectIdSql = input.subjectId === null ? sql`NULL::text` : sql`${input.subjectId}`;
4642
+ const rows = await scopedDb
4643
+ .select()
4644
+ .from(schema.files)
4645
+ .where(
4646
+ and(
4647
+ eq(schema.files.accountId, input.accountId),
4648
+ eq(schema.files.workspaceId, input.workspaceId),
4649
+ inArray(schema.files.id, ids),
4650
+ sql`google_drive_file_authorized(
4651
+ ${input.accountId}::uuid,
4652
+ ${input.workspaceId}::uuid,
4653
+ ${subjectIdSql},
4654
+ ${schema.files.id}
4655
+ )`,
4656
+ ),
4657
+ );
4658
+ return rows.map(mapFile);
4659
+ },
4660
+ );
4661
+ }
4662
+
4584
4663
  /** One RLS-scoped query for all attachment metadata needed by a model turn. */
4585
4664
  export async function getFiles(
4586
4665
  db: Database,
@@ -4603,6 +4682,7 @@ export function durableUserHistoryItem(
4603
4682
  prompt: string,
4604
4683
  resources: readonly ResourceRef[],
4605
4684
  annotations: readonly TimelineAnnotation[] = [],
4685
+ modelContext?: string | null,
4606
4686
  ): Record<string, unknown> {
4607
4687
  const attachmentRefs = resources.filter(
4608
4688
  (resource): resource is Extract<ResourceRef, { kind: "file" }> => resource.kind === "file",
@@ -4610,7 +4690,7 @@ export function durableUserHistoryItem(
4610
4690
  return {
4611
4691
  type: "message",
4612
4692
  role: "user",
4613
- content: renderTimelineAnnotationsForModel(prompt, annotations),
4693
+ content: renderUserMessageContentForModel(prompt, annotations, modelContext),
4614
4694
  ...(attachmentRefs.length > 0 ? { [MODEL_ATTACHMENT_REFS_FIELD]: attachmentRefs } : {}),
4615
4695
  ...(annotations.length > 0
4616
4696
  ? {
@@ -22578,6 +22658,122 @@ export async function upsertConnectorActionPolicy(
22578
22658
  );
22579
22659
  }
22580
22660
 
22661
+ /**
22662
+ * Install a risk-appropriate connector default without overwriting an explicit
22663
+ * user choice that already exists for the same immutable connector action.
22664
+ */
22665
+ export async function ensureConnectorActionPolicyDefault(
22666
+ db: Database,
22667
+ input: {
22668
+ accountId: string;
22669
+ workspaceId: string;
22670
+ subjectId: string;
22671
+ connectionId: string;
22672
+ serverId: string;
22673
+ toolName: string;
22674
+ actionName: string;
22675
+ policy: ConnectorActionPolicyDecision;
22676
+ },
22677
+ ): Promise<{
22678
+ policy: typeof schema.connectorActionPolicies.$inferSelect;
22679
+ changed: boolean;
22680
+ }> {
22681
+ const scope = {
22682
+ connectionId: boundedConnectorActionText(
22683
+ input.connectionId,
22684
+ "connector connection id",
22685
+ CONNECTOR_ACTION_CONNECTION_ID_MAX,
22686
+ ),
22687
+ serverId: boundedConnectorActionText(
22688
+ input.serverId,
22689
+ "connector server id",
22690
+ CONNECTOR_ACTION_SERVER_ID_MAX,
22691
+ ),
22692
+ toolName: boundedConnectorActionText(
22693
+ input.toolName,
22694
+ "connector tool name",
22695
+ CONNECTOR_ACTION_NAME_MAX,
22696
+ ),
22697
+ actionName: boundedConnectorActionText(
22698
+ input.actionName,
22699
+ "connector action name",
22700
+ CONNECTOR_ACTION_NAME_MAX,
22701
+ ),
22702
+ };
22703
+ const subjectId = boundedConnectorActionText(input.subjectId, "policy actor", 1024);
22704
+ return await withRlsContext(
22705
+ db,
22706
+ { accountId: input.accountId, workspaceId: input.workspaceId },
22707
+ async (scopedDb) =>
22708
+ await scopedDb.transaction(async (tx) => {
22709
+ await assertWorkspaceAccountPairInScope(tx, input.accountId, input.workspaceId);
22710
+ const [inserted] = await tx
22711
+ .insert(schema.connectorActionPolicies)
22712
+ .values({
22713
+ accountId: input.accountId,
22714
+ workspaceId: input.workspaceId,
22715
+ ...scope,
22716
+ policy: input.policy,
22717
+ createdBySubjectId: subjectId,
22718
+ updatedBySubjectId: subjectId,
22719
+ })
22720
+ .onConflictDoNothing({
22721
+ target: [
22722
+ schema.connectorActionPolicies.workspaceId,
22723
+ schema.connectorActionPolicies.connectionId,
22724
+ schema.connectorActionPolicies.serverId,
22725
+ schema.connectorActionPolicies.toolName,
22726
+ schema.connectorActionPolicies.actionName,
22727
+ ],
22728
+ })
22729
+ .returning();
22730
+ if (!inserted) {
22731
+ const [existing] = await tx
22732
+ .select()
22733
+ .from(schema.connectorActionPolicies)
22734
+ .where(
22735
+ and(
22736
+ eq(schema.connectorActionPolicies.workspaceId, input.workspaceId),
22737
+ eq(schema.connectorActionPolicies.connectionId, scope.connectionId),
22738
+ eq(schema.connectorActionPolicies.serverId, scope.serverId),
22739
+ eq(schema.connectorActionPolicies.toolName, scope.toolName),
22740
+ eq(schema.connectorActionPolicies.actionName, scope.actionName),
22741
+ ),
22742
+ )
22743
+ .limit(1);
22744
+ if (!existing) throw new Error("Failed to reconcile connector action policy default");
22745
+ return { policy: existing, changed: false };
22746
+ }
22747
+ await tx.insert(schema.auditEvents).values(
22748
+ withLosslessContentWriteVersion(
22749
+ {
22750
+ accountId: input.accountId,
22751
+ workspaceId: input.workspaceId,
22752
+ subjectId,
22753
+ action: "connector.action.policy_changed",
22754
+ targetType: "connector_action_policy",
22755
+ targetId: inserted.id,
22756
+ metadata: {
22757
+ connectionId: inserted.connectionId,
22758
+ serverId: inserted.serverId,
22759
+ toolName: inserted.toolName,
22760
+ actionName: inserted.actionName,
22761
+ policy: inserted.policy,
22762
+ version: inserted.version,
22763
+ previousPolicy: null,
22764
+ previousVersion: null,
22765
+ source: "connector_default",
22766
+ },
22767
+ },
22768
+ "metadata",
22769
+ "metadataCodecVersion",
22770
+ ),
22771
+ );
22772
+ return { policy: inserted, changed: true };
22773
+ }),
22774
+ );
22775
+ }
22776
+
22581
22777
  export async function prepareConnectorActionApproval(
22582
22778
  db: Database,
22583
22779
  identity: ConnectorActionAttemptIdentity,
@@ -22916,7 +23112,7 @@ export type SessionCreateInput = {
22916
23112
  accountId: string;
22917
23113
  workspaceId: string;
22918
23114
  initialMessage: string;
22919
- initialTurnInstructions?: string | null;
23115
+ initialModelContext?: string | null;
22920
23116
  resources: ResourceRef[];
22921
23117
  skills?: SessionSkill[];
22922
23118
  tools?: ToolRef[];
@@ -23366,7 +23562,7 @@ async function createSessionInTransaction(
23366
23562
  accountId: input.accountId,
23367
23563
  workspaceId: input.workspaceId,
23368
23564
  initialMessage: input.initialMessage,
23369
- initialTurnInstructions: input.initialTurnInstructions ?? null,
23565
+ initialModelContext: input.initialModelContext ?? null,
23370
23566
  resources: input.resources,
23371
23567
  skills: input.skills ?? [],
23372
23568
  tools: input.tools ?? [],
@@ -46371,6 +46567,9 @@ export async function initializeSessionStartAtomically(
46371
46567
  type: "user.message",
46372
46568
  payload: {
46373
46569
  ...initialPayload,
46570
+ ...(session.initialModelContext
46571
+ ? { modelContext: session.initialModelContext }
46572
+ : {}),
46374
46573
  initiator: creator.initiator,
46375
46574
  },
46376
46575
  clientEventId: input.clientEventId ?? `session-initial:${session.id}`,
@@ -46426,7 +46625,7 @@ export async function initializeSessionStartAtomically(
46426
46625
  source: "user",
46427
46626
  position: queueTailPosition,
46428
46627
  prompt: canonicalInitialMessage,
46429
- turnInstructions: session.initialTurnInstructions ?? null,
46628
+ modelContext: session.initialModelContext ?? null,
46430
46629
  resources: session.resources,
46431
46630
  tools: session.tools,
46432
46631
  toolsProvided: session.toolPolicy?.mode === "explicit",
@@ -46627,7 +46826,7 @@ export async function enqueueSessionTurn(
46627
46826
  source: input.source,
46628
46827
  position,
46629
46828
  prompt: input.prompt,
46630
- turnInstructions: input.turnInstructions ?? null,
46829
+ modelContext: input.modelContext ?? null,
46631
46830
  resources: input.resources,
46632
46831
  tools: input.tools,
46633
46832
  toolsProvided: input.toolsProvided ?? false,
@@ -48378,6 +48577,7 @@ export async function claimSessionWorkForAttempt(
48378
48577
  fromPostgresLosslessText(row.prompt, row.promptCodecVersion),
48379
48578
  Array.isArray(row.resources) ? (row.resources as ResourceRef[]) : [],
48380
48579
  TimelineAnnotations.parse(row.annotations),
48580
+ row.modelContext,
48381
48581
  ),
48382
48582
  },
48383
48583
  "item",
@@ -55758,7 +55958,6 @@ function mapSessionTurnForExecution(
55758
55958
  ): SessionTurnForExecution {
55759
55959
  return {
55760
55960
  ...mapSessionTurn(row),
55761
- turnInstructions: row.turnInstructions ?? null,
55762
55961
  initiatingHumanSubjectId: row.initiatingHumanSubjectId ?? null,
55763
55962
  personalConnectionDelegations: parsedPersonalConnectionDelegations(
55764
55963
  row.personalConnectionDelegations,
@@ -5,6 +5,7 @@ import {
5
5
  integer,
6
6
  jsonb,
7
7
  pgTable,
8
+ primaryKey,
8
9
  text,
9
10
  timestamp,
10
11
  uniqueIndex,
@@ -173,6 +174,7 @@ export const knowledgeSourceSyncIndexObligations = pgTable(
173
174
  objectLifecycleGeneration: bigint("object_lifecycle_generation", { mode: "number" }).notNull(),
174
175
  objectVersionGeneration: bigint("object_version_generation", { mode: "number" }).notNull(),
175
176
  citationLocator: jsonb("citation_locator").$type<Record<string, unknown>>().notNull(),
177
+ googleDriveAclEvidenceId: uuid("google_drive_acl_evidence_id"),
176
178
  aclEligibility: text("acl_eligibility").notNull().default("pending"),
177
179
  status: text("status").notNull().default("pending"),
178
180
  failureCode: text("failure_code"),
@@ -190,3 +192,84 @@ export const knowledgeSourceSyncIndexObligations = pgTable(
190
192
  ),
191
193
  }),
192
194
  );
195
+
196
+ export const googleDriveObjectAclEvidence = pgTable(
197
+ "google_drive_object_acl_evidence",
198
+ {
199
+ id: uuid("id").primaryKey().defaultRandom(),
200
+ accountId: uuid("account_id").notNull(),
201
+ workspaceId: uuid("workspace_id").notNull(),
202
+ sourceId: uuid("source_id").notNull(),
203
+ knowledgeSourceObjectId: uuid("knowledge_source_object_id").notNull(),
204
+ knowledgeDocumentVersionId: uuid("knowledge_document_version_id").notNull(),
205
+ documentId: uuid("document_id").notNull(),
206
+ fileId: uuid("file_id").notNull(),
207
+ indexObligationId: uuid("index_obligation_id").notNull(),
208
+ connectionId: uuid("connection_id").notNull(),
209
+ connectionVersion: bigint("connection_version", { mode: "number" }).notNull(),
210
+ sourcePrincipalHash: text("source_principal_hash").notNull(),
211
+ sourceSyncGeneration: bigint("source_sync_generation", { mode: "number" }).notNull(),
212
+ sourceConfigGeneration: bigint("source_config_generation", { mode: "number" }).notNull(),
213
+ sourceLifecycleGeneration: bigint("source_lifecycle_generation", { mode: "number" }).notNull(),
214
+ objectLifecycleGeneration: bigint("object_lifecycle_generation", {
215
+ mode: "number",
216
+ }).notNull(),
217
+ objectVersionGeneration: bigint("object_version_generation", { mode: "number" }).notNull(),
218
+ providerRevision: text("provider_revision"),
219
+ driveId: text("drive_id"),
220
+ aclRevision: text("acl_revision").notNull(),
221
+ aclHash: text("acl_hash").notNull(),
222
+ eligibility: text("eligibility").notNull(),
223
+ observedAt: timestamp("observed_at", { withTimezone: true }).notNull(),
224
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
225
+ citationLocator: jsonb("citation_locator").$type<Record<string, unknown>>().notNull(),
226
+ operationId: text("operation_id").notNull(),
227
+ inputHash: text("input_hash").notNull(),
228
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
229
+ },
230
+ (table) => ({
231
+ obligationOperation: uniqueIndex("google_drive_object_acl_evidence_obligation_uq").on(
232
+ table.indexObligationId,
233
+ table.operationId,
234
+ ),
235
+ version: index("google_drive_object_acl_evidence_version_idx").on(
236
+ table.knowledgeDocumentVersionId,
237
+ table.expiresAt,
238
+ table.createdAt,
239
+ ),
240
+ file: index("google_drive_object_acl_evidence_file_idx").on(
241
+ table.accountId,
242
+ table.fileId,
243
+ table.expiresAt,
244
+ ),
245
+ }),
246
+ );
247
+
248
+ export const googleDriveObjectAclPrincipals = pgTable(
249
+ "google_drive_object_acl_principals",
250
+ {
251
+ evidenceId: uuid("evidence_id").notNull(),
252
+ ordinal: integer("ordinal").notNull(),
253
+ accountId: uuid("account_id").notNull(),
254
+ workspaceId: uuid("workspace_id").notNull(),
255
+ principalType: text("principal_type").notNull(),
256
+ permissionIdHash: text("permission_id_hash"),
257
+ emailHash: text("email_hash"),
258
+ domainHash: text("domain_hash"),
259
+ role: text("role").notNull(),
260
+ inherited: boolean("inherited").notNull().default(false),
261
+ allowFileDiscovery: boolean("allow_file_discovery"),
262
+ expirationTime: timestamp("expiration_time", { withTimezone: true }),
263
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
264
+ },
265
+ (table) => ({
266
+ identity: primaryKey({ columns: [table.evidenceId, table.ordinal] }),
267
+ match: index("google_drive_object_acl_principals_match_idx").on(
268
+ table.evidenceId,
269
+ table.principalType,
270
+ table.permissionIdHash,
271
+ table.emailHash,
272
+ table.domainHash,
273
+ ),
274
+ }),
275
+ );